【Android】Componse中的常用组件

Componse中的常用组件

  • 一. 常用组件
    • 1.1 HorizontalPager 轮播图
    • 1.2 Scaffold 脚手架
      • 1.2.1 基础Scaffold
      • 1.2.2 添加顶部导航栏
      • 1.2.3 添加底部导航栏
      • 1.2.4 添加悬浮按钮
      • 1.2.5 封装BottomNav
    • 1.3. SecondaryScrollableTabRow 分类Tab
      • 1.3.1. 最简单的分类Tab
      • 1.3.2. 自定义选中样式
    • 1.4. 底层弹窗(ModelBottomSheet)
      • 1.4.1. 简单集成

一. 常用组件

1.1 HorizontalPager 轮播图

@ComposablefunBasicPagerDemo(){// 由于没有图片, 使用颜色代替valcolors=listOf(Color(0xFFE91E63),// 粉色Color(0xFF2196F3),// 蓝色Color(0xFF4CAF50)// 绿色)// 定义pageState对象valpageState=rememberPagerState(pageCount={colors.size})HorizontalPager(state=pageState,verticalAlignment=Alignment.Top){page->// 当前页数下标Box(modifier=Modifier.fillMaxWidth().aspectRatio(2.6f).background(colors[page]),contentAlignment=Alignment.Center){Text("第${page+1}页",fontWeight=FontWeight.Bold,color=Color.White)}}}
  • rememberPagerState(pageCount = { colors.size }): 创建分页状态, 3页
  • HorizontalPager: 水平分页组件,类似ViewPager
  • aspectRatio: 宽高比
  • **{page ->} **: 每一页的UI, page是当前页面 (0,1,2)

rememberPagerState参数说明:

  • pageCount = { 数量 } -> 总页数(Lambda形式)
  • initalPage = 起始页 -> 初始显示第几页(默认0)

pageState提供了几个关键属性,让我们可以随时获取分页的状态:

pageState提供了两个挂起函数:

1.2 Scaffold 脚手架

什么是Scaffold

Scaffold是Componse提供的”页面框架模版“,就像盖房子先搭脚手架一样,它帮你自动处理顶部栏、底部栏、内容区域的位置关系,不用手动计算问题。

1.2.1 基础Scaffold

@ComposablefunScaffoldStepOne(){Scaffold{paddingValues->Box(modifier=Modifier.fillMaxSize().padding(paddingValues).background(Color.Red),contentAlignment=Alignment.Center// 内容居中显示){Text("主题内容-简单的脚手架",fontSize=20.sp)}}}

结果:

运行之后,你可以看到屏幕居中显示”主内容“,不会被状态栏遮挡

解释:

  • Scaffold { paddingValues -> ...}: 大括号中是内容区域
  • paddingValues: Scaffold自动计算出安全距离,你不用管具体数值,用它就行。f

1.2.2 添加顶部导航栏

// 使用Scaffold(topBar={TopAppBarView()}// 导航栏)// 导航栏@OptIn(ExperimentalMaterial3Api::class)@ComposablefunTopAppBarView(){TopAppBar(title={Text("导航栏标题",fontWeight=FontWeight.Bold,fontSize=20.sp)},colors=TopAppBarDefaults.topAppBarColors(containerColor=Color.Blue,// 导航栏的背景色titleContentColor=Color.Green// 导航栏标题颜色))}

结果:

  • topBar参数接受一个@Componse组件
  • TopAppBar是Material3提供的标准顶部栏,自带标题模式
  • colors参数设置顶部栏背景色和标题颜色
  • 加上后,paddingvalues会自动包含顶部导航栏的高度
  • @OptIn(ExperimentalMaterial3Api::class)TopAppBar的部分参数是实验性API,需要加这个注解。它只是一个标记,告诉编译器,”我知道这是实验性的“。

1.2.3 添加底部导航栏

首先我们可以配置下icons库

implementation("androidx.compose.material:material-icons-extended:1.7.8")

Scaffold(// ... 其他配置bottomBar={BottomBarView()}// 底部导航栏){// ... 内容}@ComposablefunBottomBarView(){NavigationBar{NavigationBarItem(selected=true,icon={Icon(Icons.Filled.Home,contentDescription="首页")},label={Text("首页")},onClick={})NavigationBarItem(selected=true,icon={Icon(Icons.Filled.AlarmOn,contentDescription="消息")},label={Text("首页")},onClick={})NavigationBarItem(selected=true,icon={Icon(Icons.Filled.Person,contentDescription="我的")},label={Text("首页")},onClick={})}}

结果:

1.2.4 添加悬浮按钮

Scaffold(// ... 其他配置floatingActionButton={// 悬浮按钮FloatingActionButton(onClick={/* 处理点击事件 */}){Icon(Icons.Filled.Add,contentDescription="添加")}}){// 内容 ....}

结果:

1.2.5 封装BottomNav

实现底部工具栏的点击:

@ComposablefunScaffoldStepOne(){// 定义底部table数据valtabs=listOf<TabItem>(TabItem("首页",selectedIcon=Icons.Filled.Home,unSelectedIcon=Icons.Outlined.Home,TabType.Home),TabItem("消息",selectedIcon=Icons.Filled.AlarmOn,unSelectedIcon=Icons.Outlined.AlarmOn,TabType.Message),TabItem("我的",selectedIcon=Icons.Filled.Person,unSelectedIcon=Icons.Outlined.Person,TabType.Mine),)// 声明变量记录当前的选中tab类型varcurrentRoutebyremember{mutableStateOf(TabType.Home)}Scaffold(// 其他属性内容 ...bottomBar={BottomBarView(tabs,currentRoute,{currentRoute=it})},// 底部导航栏){// 内容....}// 封装的底部工具栏代码:@ComposablefunBottomBarView(tabs:List<TabItem>,currentRoute:TabType,onTableItemClick:(TabType)->Unit){NavigationBar{tabs.forEach{tab->NavigationBarItem(selected=currentRoute==tab.route,icon={Icon(if(currentRoute==tab.route)tab.selectedIconelsetab.unSelectedIcon,contentDescription=tab.name)},label={Text(tab.name)},onClick={onTableItemClick(tab.route)})}}}

注意:

  • ImageVector是矢量图标的类型
  • Icons.Filled.Home是实心图标(选中时用),Icons.Outlined.Home是描边图标(未选中时用)

1.3. SecondaryScrollableTabRow 分类Tab

例如顶部的分类标签

1.3.1. 最简单的分类Tab

@OptIn(ExperimentalMaterial3Api::class)@ComposablefunCategoryTabsDemo(){valcategories=listOf<String>("全部","Android","Java","Kotlin","网络","算法","数据库")varselectedIndexbyremember{mutableIntStateOf(0)}SecondaryScrollableTabRow(selectedTabIndex=selectedIndex,edgePadding=16.dp){categories.forEachIndexed{index,category->Tab(selected=selectedIndex==index,text={Text(category)},onClick={selectedIndex=index})}}}

1.3.2. 自定义选中样式

@OptIn(ExperimentalMaterial3Api::class)@ComposablefunCategoryTabsCustomDemo(){valcategories=listOf<String>("全部","Android","Java","Kotlin","网络","算法","数据库")varselectedIndexbyremember{mutableIntStateOf(0)}SecondaryScrollableTabRow(selectedTabIndex=selectedIndex,edgePadding=16.dp,indicator={},// 取出默认的指示器,就是选中的item下面的下划线divider={}){categories.forEachIndexed{index,category->Tab(selected=selectedIndex==index,text={Column(horizontalAlignment=Alignment.CenterHorizontally,modifier=Modifier.background(Color.Red)){// 文字Text(category,fontSize=15.sp,color=if(selectedIndex==index)Color.BlackelseColor.Gray,fontWeight=if(selectedIndex==index)FontWeight.BoldelseFontWeight.Normal)// 选中时的下划线if(selectedIndex==index){Spacer(modifier=Modifier.height(5.dp))Box(modifier=Modifier.width(20.dp).height(2.dp).background(Color.Black))}}},onClick={selectedIndex=index})}}}

结果:

1.4. 底层弹窗(ModelBottomSheet)

ModelBottomSheet是Mateial3的实验性API,使用时需要加注解@OptIn(ExperimentalMaterial3Api::class)。
@OptIn不是功能代码,只是一个标记,实验性API可能在未来的版本变化,编译器要求你明确知道风险。

1.4.1. 简单集成

@OptIn(ExperimentalMaterial3Api::class)@ComposablefunFilterSheetDemo(onDismiss:()->Unit){ModalBottomSheet(onDismissRequest=onDismiss){Text("这个是弹窗内容",modifier=Modifier.padding(20.dp))}}// 调用// 声明底部视图的类型。varshowModelBottomViewbyremember{mutableStateOf(false)}// 点击事件触发floatingActionButton={// 悬浮按钮FloatingActionButton(onClick={/* 处理点击事件 */showModelBottomView=true}){Icon(Icons.Filled.Add,contentDescription="添加")}}// 显示弹窗// 底部弹窗if(showModelBottomView){FilterSheetDemo{showModelBottomView=false}}

效果: