安卓jetpack compose学习笔记-UI基础学习
哲学知识应该用哲学的方式学习,技术知识也应该用技术的方式学习。没必要用哲学的态度来学习技术。
学完安卓技术能做事就ok了,安卓技术肯定是有哲学的,但是在初学阶段没必要讨论什么安卓哲学。
学习一们复杂技术的路径有很多,这里不妨碍尝试介绍一条。
1、简单概述,这个很简单。
2、自己需要学习的东西有哪有,即这个技术常用的技能。
3、学习对应技能,建立感性认识。
4、实操这些组件的使用。
5、将这些组件组合成一个完整应用。
一、概述
Jetpack Compose 是 Google 推出的一款基于 Kotlin API 的框架,旨在重新定义 Android 应用的布局方式。它通过使用可组合函数(Composable)来构建用户界面,使得开发过程更加高效、快速,并且能够减少应用的包体积,提高性能。
Jetpack Compose可以直接翻译为喷气背包组合,jetpack是形容词,compose的组合性才是主要意思。
Material Design中午意思是材料设计语言。Material Design是Google提出的设计理念,安卓的Compose技术则是这一理念的具体表现方式。
二、常用UI组件
UI组件:Button、Text等。
布局组件:Column、Row、Box三种。
参数控制:Modifier修饰符。
其他的还有控制组件,权限组件等。
1、UI组件
1)Text
一个文字组件。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.spclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent { AText() }}
}@Composable
fun AText(){Text(text = "Hello,world!",// 为了方便更容易看清fontSize =24.sp,modifier = Modifier.padding(top = 300.dp,start=100.dp))
}
效果:
其他文字输入组件:TextField、OutlinedTextField。前者是填充风格的输入框,后者的外面会带一个边框。其他操作类似。两个常用参数:
1、placeholder参数控当输入框为空时显示的内容。
2、visualTransformation控制输入框内容的视觉效果,设置为PasswordVisualTransformation()时为密码框效果,将输入框内容替换为*号进行显示。
2)Button
一个按钮组件,可以设置点击函数或者在这个按钮上面显示个文字。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Previewclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染AButton函数setContent { AButton() }}
}@Composable
fun AButton() {// 按钮的定义Button(// 点击即打印字符串onClick = {println("hello, world!")},// 填满屏幕,不填满,我的机器好像点不了。modifier = Modifier.fillMaxSize()) {Text(text = "我是按钮")}
}@Preview
@Composable
fun PreviewAButton() {AButton()
}
效果:
3)Image
一张图片。除了显示图片,这个组件还可以放在Box中用来作为一种图片背景。和Image比较类似的还有Icon组件。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Previewclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {AImage()}}
}@Composable
fun AImage() {// 加载一个矢量图Image(imageVector = Icons.Filled.Favorite,contentDescription = null,modifier = Modifier.fillMaxSize())
}@Preview
@Composable
fun PreviewAImage() {AImage()
}
效果:
4)FloatingActionButton
悬浮按钮。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.FloatingActionButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {AFloatingButton()}}
}@Composable
fun AFloatingButton() {FloatingActionButton(onClick = {println("hello, Floating!")},Modifier.padding(start = 16.dp,top = 300.dp)) { }
}@Preview
@Composable
fun PreviewAFloatingButton() {AFloatingButton()
}
效果:
5)Checkbox复选框
复选框组件。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Checkbox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {ACheckbox()}}
}@Composable
fun ACheckbox() {var checkState = remember {mutableStateOf(true)}Checkbox(checked = checkState.value,onCheckedChange = {checkState.value = itprintln("change: " + checkState.value)},modifier = Modifier.padding(top = 300.dp))println("end: " + checkState.value)
}@Preview
@Composable
fun PreviewACheckbox() {ACheckbox()
}
效果:
6)Switch单选框
单选开关。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Switch
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {ASwitch()}}
}@Composable
fun ASwitch() {var checkState = remember {mutableStateOf(true)}Switch(checked = checkState.value,onCheckedChange = {checkState.value = itprintln("change: " + checkState.value)},modifier = Modifier.padding(top = 300.dp))println("end: " + checkState.value)
}@Preview
@Composable
fun PreviewASwitch() {ASwitch()
}
效果:
7)Slider滑竿组件
可以用来做音量、亮度之类的数值调整,或者进度条。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Previewclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {ASlider()}}
}@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ASlider() {val sliderState = remember {mutableStateOf(0.3f)}Column(modifier = Modifier.fillMaxSize(),// 需要把这个列填满父空间,垂直居中才能看出来,否则Column可能太小,无法看出居中效果。verticalArrangement = Arrangement.Center) {// 显示具体值Text(text = "音量:%.0f".format(sliderState.value * 100))// 滑竿组件Slider(value = sliderState.value,onValueChange = {sliderState.value = it},)}
}@Preview
@Composable
fun PreviewASlider() {ASlider()
}
效果:
8)Dialog对话框
在需要的时候弹出一个对话框。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialogclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {ADialog()}}
}@Composable
fun ADialog() {// 因为Compose是不可变的,所以需要使用这种共享变量的方式。val state = remember {mutableStateOf(false)}Column(modifier = Modifier.fillMaxSize(),// 需要把这个列填满父空间,垂直居中才能看出来,否则Column可能太小,无法看出居中效果。verticalArrangement = Arrangement.Center) {// 使用开关触发对话框。// 因为Compose是根据变量是否改变进行渲染的模式,所以需要通过变量来控制对话框是否显示。// 比如下边通过单选框来控制对应变量。Switch(checked = state.value,onCheckedChange = {state.value = it})}// 对话框的开启和关闭实际上是由state.value来控制的if (state.value) {// properties可以设置对话框的一些东西。Dialog(// 点击对话框之外的区域关闭对话框onDismissRequest = {state.value = false}) {// 对话框实际上是用Window重新渲染的这个Box。Box(modifier = Modifier.size(300.dp, 300.dp).background(Color.White)) {Text(text = "我是对话框!")}}}
}@Preview
@Composable
fun PreviewA() {ADialog()
}
效果:
类似组件:AlertDialog。
9)进度条
Compose自带圆形和直线两种进度条。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 渲染Compose函数setContent {ACircular()}}
}@Composable
fun ACircular() {// 因为Compose是不可变的,所以需要使用这种共享变量的方式。val progress = remember {mutableFloatStateOf(0.1f)}Column(modifier = Modifier.fillMaxSize(),// 需要把这个列填满父空间,垂直居中才能看出来,否则Column可能太小,无法看出居中效果。verticalArrangement = Arrangement.Center) {// 圆形进度条CircularProgressIndicator(progress = {progress.value})// 用几个空白区域把进度条顶上去。Spacer(Modifier.requiredHeight(30.dp))// 直线进度条LinearProgressIndicator(progress = {progress.value})// 用几个空白区域把进度条顶上去。Spacer(Modifier.requiredHeight(30.dp))OutlinedButton(onClick = {if (progress.value < 1f)progress.value += 0.1felseprogress.value = 0.1f}) {Text("增加进度!")}}
}@Preview
@Composable
fun PreviewA() {ACircular()
}
效果:
2、布局组件
1)Column
一个列布局组件,将内部的其他UI组件以列的方式进行组织。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent { AColumn(name = "Bob") }}
}@Composable
fun AColumn(name: String){Column(modifier = Modifier.padding(top = 300.dp,start=100.dp)) {// Column会使用列的方式组织下述Text组件。Text(text = "hello, $name")Text(text = "我是第二列")Text(text = "我是第三列")Text(text = "...")Text(text = "我是第N列")}
}@Preview
@Composable
fun PreviewAColumn() {AColumn(name = "Bob")
}
效果:
2)Row
一个行组件。可以把这个组件里的子组件以行的方式进行组织。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {ARow()}}
}@Composable
fun ARow(){Row(modifier = Modifier.padding(top = 300.dp,start=5.dp)) {// Row会使用行的方式组织下述Text组件。Text(text = "|我是第1行|")Text(text = "我是第2行|")Text(text = "我是第3行|")Text(text = "...|")Text(text = "我是第N行|")}
}@Preview
@Composable
fun PreviewARow() {ARow()
}
效果:
3)Box
一个盒子组件。会以堆叠的方式组织子组件。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)println("onCreate")// 渲染Compose函数setContent {ABox()}}
}@Composable
fun ABox() {Box {// Box会使用堆叠的方式组织下述Compose组件。Button(onClick = {},modifier = Modifier.fillMaxSize()) { }Text(text = "|我是第1行|",modifier = Modifier.padding(top = 300.dp,start = 100.dp))}
}@Preview
@Composable
fun PreviewABox() {ABox()
}
效果:
4)Surface
一个平面组件。和Box很像,只是可以快速完成阴影等风格的设置。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 渲染Compose函数setContent {ASurface()}}
}@Composable
fun ASurface() {// 一个平面,和Box很像,自带一定的风格,可以快速设置阴影等。// 如果需要风格设置,考虑Surface。否则直接用没有风格的Box。Surface(shape = RoundedCornerShape(8.dp),modifier = Modifier.height(300.dp).width(300.dp)) {Image(imageVector = Icons.Filled.Favorite,contentDescription = null,modifier = Modifier.fillMaxSize())// Box和Surface都是堆叠的模式,行列布局需要使用Column和Row。Column(// 子组件的对齐方式,需要Column有足够的空间才能看出来。verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally,modifier = Modifier.fillMaxSize()) {// 如果没有Column,Text就会堆在一起。Text(text = "1234", color = Color.White)Text(text = "1234", color = Color.White)}}
}@Preview
@Composable
fun PreviewA() {ASurface()
}
效果:
5)Spacer
空白区域。主要用来分割不同的组件。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 渲染Compose函数setContent {ASpacer()}}
}@Composable
fun ASpacer() {Column(// 子组件的对齐方式,需要Column有足够的空间才能看出来。verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally,modifier = Modifier.fillMaxSize()) {Text(text = "1234")Text(text = "1234")Spacer(modifier = Modifier.padding(vertical = 10.dp))Text(text = "1234")Spacer(modifier = Modifier.padding(vertical = 10.dp))Text(text = "1234")}
}@Preview
@Composable
fun PreviewA() {ASpacer()
}
效果:
6)Scaffold脚手架
快速构建一个应用的基础布局。
代码:
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 渲染Compose函数setContent {AScaffold()}}
}data class Item(val name: String,val icon:Int
)@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AScaffold() {var selectedItem = remember { mutableStateOf(0) }var items = listOf<Item>(Item("主页", R.drawable.home),Item("列表", R.drawable.liebiao),Item("设置", R.drawable.shezhi))Scaffold(topBar = {TopAppBar(title = { Text("主页") },navigationIcon = {IconButton(onClick = {}) {Icon(Icons.Filled.Menu, null)}})},bottomBar = {NavigationBar {items.forEachIndexed { index,item ->NavigationBarItem(selected = selectedItem.value == index,onClick = {selectedItem.value = index},icon = {Icon(painterResource(item.icon), null)},alwaysShowLabel = false,label = {Text(item.name)},modifier = Modifier.size(20.dp))}}}) {Box(modifier = Modifier.fillMaxSize(),contentAlignment = Alignment.Center) {Text("主页界面")}}
}@Preview
@Composable
fun PreviewA() {AScaffold()
}
效果:
其他布局组件:ConstraintLayout约束布局,及其Barrier分界线、Guideline引导线、Chain链接约束、
3、Modifier修饰符
可以为组件应用样式设置。如边距、字体、位移等。每个基础Compose组件都有一个modifier参数,通过传入的modifier参数修改组件的样式。
代码:
Text(text = "|我是第1行|",modifier = Modifier.padding(top = 300.dp,start = 100.dp))
效果:
其他一些作用:
1、通过size修改被修饰组件的大小。
2、通过background修改被修饰组件的背景。
3、通过fillMaxSize让被修饰组件填满父组件的空间。
4、通过border为被修饰组件添加边框。通过padding为被修饰组件增加间隙。
5、通过offset移动被修饰组件的位置。
6、通过clickable为被修饰组件增加点击函数。
注意事项:
Compose作用于限定实现了Modifier的安全调用,我们只能在特定作用于中调用修饰符。这个设计可能会导致上层的Modifier设置在子组件中无法使用,这是设计哲学上的取舍,暂不细究。在初学阶段把Modifier的定义移到需要这个Modifier的组件即可。
4、逻辑组件
1)列表
基本逻辑就是用循环把一个组件多创建出来几个。
代码:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {// 在这个Activity被创建的时候调用这个函数。override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 渲染Compose函数setContent {AList()}}
}data class Item(val name: String,val icon: Int
)@Composable
fun AList() {var items = listOf<Item>(Item("主页", R.drawable.home),Item("列表", R.drawable.liebiao),Item("设置", R.drawable.shezhi),Item("设置", R.drawable.shezhi),Item("设置", R.drawable.shezhi),Item("设置", R.drawable.shezhi),)Row{Column {items.forEachIndexed { index, opt->Text("我是Column $index")}}Spacer(Modifier.padding(horizontal = 10.dp))LazyColumn(state = rememberLazyListState(3,4),contentPadding = PaddingValues(30.dp)) {itemsIndexed(items) { index, it ->Text("我是LazyColumn。index: ${index}, name: ${it.name}")}}}
}@Preview
@Composable
fun PreviewA() {AList()
}
效果:
其他列表:一行的列表可以用Row来实现。
三、UI组合实践
1、简单页面的实践
可以随便找个页面,然后自己以素描的方式构建出该页面的仿制版。比如下述界面:
代码:
把BloomLogin的Compose函数放到setContent中即可。
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp@Composable
fun BloomLogin() {var email = remember { mutableStateOf("") }var password = remember { mutableStateOf("") }Surface {Column(verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally,modifier = Modifier.fillMaxSize().padding(start = 20.dp, end = 20.dp)) {Text(text="Log in with email",fontWeight = FontWeight.Bold)Spacer(Modifier.padding(vertical = 6.dp))TextField(value = email.value,onValueChange = {email.value = it},modifier = Modifier.fillMaxWidth(),placeholder = {Text("Email address")})Spacer(Modifier.padding(vertical = 3.dp))TextField(value = password.value,onValueChange = {password.value = it},modifier = Modifier.fillMaxWidth(),placeholder = {Text("Password(8+ characters)")},visualTransformation = PasswordVisualTransformation())Spacer(Modifier.padding(vertical = 6.dp))var text = "Dy clicking below. " +"you agree to our Terms of Use and " +"consent to our Privacy Policy."Text(text=text,textAlign = TextAlign.Center,modifier = Modifier)Spacer(Modifier.padding(vertical = 6.dp))Button(onClick = {},modifier = Modifier.fillMaxWidth()) {Text("Log in")}}}
}@Preview
@Composable
fun PreviewBloomLogin() {BloomLogin()
}
效果:
也可以用github上面安卓官方提供的例子练手:https://github.com/android/compose-samples
2、实践总结
学会上述的布局组件、UI组件和Modifier修饰符之后,基本上可以模仿现有的手机页面。如果还有不足之处,那么应该在于设计审美和资源素材的不足。其他遗漏的组件,有了上诉的经验后,从网络上或官网上寻找对应的使用例子应该是比较容易的了。
一门技术,如果你已经懂了90%,那么限制你提高的水平的因素,将不再是表面上的技术,而是相关的哲学。
3、未来提升方向:
1、不断模仿其他页面进行仿写,或者参与实际的项目开发,提升实践能力。
2、学习其他遗漏或者新出的组件。
3、学习、思考jetpack compose android的设计哲学。
参考内容:
书籍《Jetpack Compose从入门到实战》。
百度AI。