Android Jetpack Compose —— 控件
一、Compose控件分类
二、常用控件说明
一、Compose控件分类,主要分以下几个类
容器控件:如Box、Row、Column、Stack、Wrap /ræp/、Scrollable等,用于包含其他控件或布局。 图像控件:如Image、Canvas /ˈkænvəs/、Drawable等,用于显示图像或绘制自定义图形。 输入控件:如TextField、Checkbox、RadioGroup、Switch、Slider、DatePicker、TimePicker等,用于接收用户输入或选择。 列表控件:如LazyColumn /ˈkɑːləm/、LazyRow、LazyVerticalGrid等,用于显示长列表或网格数据。 动画控件:如Animatable ˈænɪmət 爱你美得包、AnimatedVisibility、AnimatedContent等,用于创建动态的视觉效果。 滑动控件:如Swipeable、Scrollable、Scrollbar、Pager等,用于支持滑动和手势交互。 样式控件:如Scaffold、TopAppBar、BottomAppBar、SnackBar等,用于管理应用程序的样式和外观。
二、常用控件说明
Text:用于呈现文本的控件。 TextField:可以让用户输入文本的控件。 Button:用于执行操作的控件。 Image:用于显示图像的控件。 Row横排布局 Column是竖排布局/ˈkɑːləm/ Card:用于呈现卡片式布局的控件。
Scaffold:/ˈskæfoʊld/ 可以将应用程序的基本UI元素包装在一起的控件。
FloatingActionButton:/ˈfloʊtɪŋ/ 实现浮动操作按钮 Slider:/ˈslaɪdər/实现滑动条 ProgressBar:实现进度条
Tab:/tæb/用于在选项卡之间切换的控件。 BottomNavigation:/ˌnævɪˈɡeɪʃn/实现底部导航栏 Dialog:/ˈdaɪəlɔːɡ/用于显示对话框的控件。 Column:用于将子控件垂直排列 Row:用于将子控件水平排列 Box:类似于 FrameLayout,可以用于布局或者装饰
根布局
Scaffold:实现 Material Design /məˈtɪriəl/ 风格的屏幕布局 Surface:实现 Material Design 风格的表面,具有形状和阴影
控制布局
Row横排布局 Column是竖排布局/ˈkɑːləm/ Card:用于呈现卡片式布局的控件
Box:类似于 FrameLayout,可以用于布局或者装饰
基本元素
Divider:/dɪˈvaɪdər/用于绘制分割线,可以在Column和Row中使用。 TextButton:实现文本按钮 OutlinedButton:实现带边框的按钮 Checkbox:实现多选框 RadioGroup:实现单选框 TabRow:实现选项卡,可用于导航 ModalBottomSheet:实现底部弹出框 AlertDialog:实现弹出框 BottomSheet: 底部弹出式窗口。 Menu: 弹出式菜单。 Tooltip: 文本提示框。 RadioButton: 单选框。 Switch: 开关按钮。 LinearProgressIndicator: /ˈɪndɪkeɪtər/线性进度指示器 CircularProgressIndicator:圆形进度指示器,圆形进度条。 Spacer: /ˈspeɪsər/用于占据空白区域,并支持自定义大小
AppBar: 应用栏。 Drawer: 抽屉式布局。/drɔːr/用于显示侧边栏的控件。
Box:用于在自由布局中控制位置、大小和绘制顺序等。
Snackbar:用于在屏幕底部显示消息的控件。 Navigation:用于管理应用程序的导航,提供了一种可以让用户从一个屏幕到另一个屏幕的方式。 ViewPager2:用于创建可左右滑动的页面。 SwipeRefreshLayout:可用于实现下拉刷新操作的控件。 ProgressIndicator:用于显示进度的控件,提供了多种样式,如环形进度条、线性进度条等。 WebView:用于在应用中加载网页的控件。 SurfaceView:用于在应用中显示视频的控件,支持播放本地视频和网络视频。 LinearProgressIndicator:线性进度条 DropdownMenu:实现下拉菜单 PopupMenu:弹出菜单 LazyColumn:垂直滚动列表 LazyRow:水平滚动列表 LazyVerticalGrid:垂直滚动网格 LazyHorizontalGrid:水平滚动网格 Pager:分页控件
Surface:用于创建表面,可以用来绘制自定义的UI元素。
SwipeRefresh:用于创建下拉刷新的控件。 Accompanist:[əˈkʌmpənɪst]提供了许多有用的Compose控件,例如各种加载占位符、图片缩放控件、滑动刷新控件等等。 Compose Charts:提供了各种绘图控件,包括折线图、柱状图、饼状图等等。 Compose Navigator:提供了一种新的导航方式,通过声明式路由和导航来管理不同屏幕之间的转换。 Compose DataTable:提供了数据表格控件,用于展示数据的表格。 Compose Countdown Timer:提供了倒计时控件。 Compose Material Dialogs:提供了Material Design风格的对话框控件。 Compose Timeline:提供了时间线控件。 Compose Dropdown Menu:提供了下拉菜单控件。 BottomAppBar:用于底部应用程序栏。 DatePicker:用于选择日期。 BottomAppBar: 底部应用栏 BottomDrawer: 底部抽屉 TopAppBar: 顶部应用栏 ViewPager: 用于滑动切换多个页面的控件 这一章主要是介绍常用的控件,这些控件在使用的时候是必不可少的,这个需要我们慢慢练习,才能达到孰能生巧。
入门
android Compose
Jetpack Compose 是用于构建原生 Android 界面的新工具包,无需修改任何 XML 布局,也不需要使用布局编辑器。相反,只需调用可组合函数来定义所需的元素,Compose 编译器即会完成后面的所有工作。
简而言之,使用Compose,不再需要xml编写页面。
可组合函数(Composable function)
Compose是围绕可组合函数构建的,只需要描述应用界面的外观并提供数据依赖,而不必关注界面的构建过程(如初始化元素、将其附加到父项等)。而创建Composable function,只需要添加注解 @Composable到函数名称前。
首先,我们构建创建一个应用:ComposeTutorial。在AS中选择Empty Activity创建。
Hello World
添加文本元素
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {//在此处定义布局
//此处的Text方法是由Compose界面库定义的文本Composable function
Text("Hello world!")
}
}
}
Scaffold
脚手架的意思,和 Flutter 中的 Scaffold 是一样的,通过 Scaffold 我看可以快速的对页面进行布局,例如设置导航栏,侧滑栏,底部导航等等。
fun Scaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
containerColor: Color = MaterialTheme.colorScheme.background,
contentColor: Color = contentColorFor(containerColor),
content: @Composable (PaddingValues) -> Unit
)
topBar:Toolbar,常用的有 CenterAlignedTopAppBar,SmallTopAppBar,MediumTopAppBar 等。 bootomBar:底部导航栏 snackbarHost: floatingActionButton:按钮 floatingActionButtonPosition:按钮位置 containerColor:背景颜色 contentColor:内容首选颜色
看一个栗子:
Scaffold(
topBar = {
//.....
},
bottomBar = bottomBar,
) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(top = it.calculateTopPadding(), bottom = it.calculateBottomPadding())
) {
content.invoke(it)
}
}
需要注意的是,如果使用了 toolbar 或者 bootomBar,就会把 content 中的内容挡住,这个时候就需要使用 PaddingValue 设置内边距了。
还有一点须要注意,如果要使用沉浸式状态栏,就需要自定义 topBar 了,要不然状态栏会被 topBar 覆盖。下面代码是设置沉浸式状态栏的。
点击事件实现
非按钮控件(文本…) Modifier.clickable
Text(text = "点击我", Modifier.clickable {
Log.d(TAG, "TestTouchEvent: 单击事件")
})
按钮 onClick
Button(
onClick = { enabled = false },
enabled = enabled
) {
Text(text = "Click Me")
}
状态机
remember和mutableStateOf的基本概念
在Jetpack Compose中,remember和mutableStateOf协同工作,为开发者提供了一种强大的状态管理机制。
mutableStateOf
mutableStateOf是一个函数,用于创建一个可观察的状态对象。当这个对象的值发生变化时,所有观察到这个状态的Composable函数将自动重新绘制,以反映新的状态。这种机制是响应式编程的核心,允许我们构建动态和交互式的UI。
remembe
remember函数用于在Composable函数重新绘制时记住(保持)一个值。它确保了,即使在多次重新绘制过程中,状态或计算结果可以被保留,避免了不必要的重计算。
组合使用remember和mutableStateOf
将remember与mutableStateOf结合使用,可以有效地管理在UI中随时间变化的状态。remember确保在组件的重新绘制过程中保持状态对象不变,而mutableStateOf负责监测状态变化并触发UI更新。这种模式支持构建高效且响应快速的应用。
@Composable
fun MyComposable() {
// Remembering a mutable state
val count = remember { mutableStateOf(0) }
// A simple button that increments the count when clicked
Button(onClick = { count.value++ }) {
Text("I've been clicked ${count.value} times")
}
}
这个例子展示了如何使用remember和mutableStateOf来管理和观察一个简单的计数器状态。当按钮被点击时,计数器的值会增加,并且UI会自动更新来反映新的值。
ui动态刷新:设置值
ComposeDropDownItem(
text = viewModel.orderConvertDisplay(it),
arg1 = it.REFNO,
arg2 = it.OrderTime.getValidDateOnlyYMD(),
checked = mutableStateOf(
viewModel.selectOrderNo.get()?.contains(it.REFNO) == true
)
)
与Vue中的reactive比较
虽然Jetpack Compose中的remember和mutableStateOf与Vue中的reactive在概念上相似,都旨在提供响应式的状态管理,但它们在实现和使用场景上存在一些差异。
Vue的reactive系统是基于Proxy实现的,可以自动跟踪和响应状态对象的深度变化,适合于构建复杂的Web应用。相比之下,Compose的remember和mutableStateOf更侧重于组件级别的状态管理,它们通过可观察的状态对象和组件的重新组合来驱动UI的更新。
列表
在Compose中有没有像RecycleView的控件可以滑动呢?答案:是有的,它们分别是LazyRow和LazyColumn。
基本使用
LazyRow和LazyColumn用法相似,只是展示的方向不同,所以便是不各自分个章节出来了,下文以LazyColumn为例讲解
@SuppressLint("UnrememberedMutableState")
@Preview(showBackground = true)
@Composable
fun ListPageDemo() {
//可触发重组的List
val list = arrayListOf<String>()
//构造数据
repeat(30) {
list.add("卡片$it")
}
ComposeDemoTheme {
Column() {
LazyColumn {
items(list) {
Text(
it, modifier = Modifier
.fillMaxWidth()
.height(50.dp)
)
}
}
}
}
}
上面主要使用了LazyListScope里提供的items方法来构造列表
除此之外,LazyListScope也是提供了几个不同的方法来构造列表
LazyColumn {
// 添加单个项目
item {
Text(text = "First item")
}
// 添加五个项目
items(5) { index ->
Text(text = "Item: $index")
}
// 添加其他单个项目
item {
Text(text = "Last item")
}
}