Android Jetpack Compose —— 控件

907 阅读7分钟

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中,remembermutableStateOf协同工作,为开发者提供了一种强大的状态管理机制。

mutableStateOf

mutableStateOf是一个函数,用于创建一个可观察的状态对象。当这个对象的值发生变化时,所有观察到这个状态的Composable函数将自动重新绘制,以反映新的状态。这种机制是响应式编程的核心,允许我们构建动态和交互式的UI。

remembe

remember函数用于在Composable函数重新绘制时记住(保持)一个值。它确保了,即使在多次重新绘制过程中,状态或计算结果可以被保留,避免了不必要的重计算。

组合使用remembermutableStateOf

remembermutableStateOf结合使用,可以有效地管理在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")
     }
 }

这个例子展示了如何使用remembermutableStateOf来管理和观察一个简单的计数器状态。当按钮被点击时,计数器的值会增加,并且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中的remembermutableStateOf与Vue中的reactive在概念上相似,都旨在提供响应式的状态管理,但它们在实现和使用场景上存在一些差异。

Vue的reactive系统是基于Proxy实现的,可以自动跟踪和响应状态对象的深度变化,适合于构建复杂的Web应用。相比之下,Compose的remembermutableStateOf更侧重于组件级别的状态管理,它们通过可观察的状态对象和组件的重新组合来驱动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")
     }
     
 }