这篇文章会介绍Tab,LeadingIconTab,TabRow,以及ScrollableTabRow的用户。TabRow跟ScrollableTabRow就类似于以前View系统的TabLayout。只不过TabRow是不可滑动的,而ScrollableTabRow是可滑动的。而Tab就是TabRow跟ScrollableTabRow使用的Item的控件。LeadingIconTab跟Tab的区别就是LeadingIconTab是带Icon的。
一:Tab
首先来看看Tab的代码:
@Composable
fun Tab(
selected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
selectedContentColor: Color = LocalContentColor.current,
unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium),
content: @Composable ColumnScope.() -> Unit
){
...
}
复制代码
- selected 是否选中
- onClick 点击事件
- modifier 修饰符 Modifier的讲解
- enabled 是否可用
- interactionSource 可以处理状态的,比如按下的时候什么效果,正常时候什么效果。类似之前再布局文件里写Selector。 比如我们下面的例子中设置,如果是选中时候边框线的颜色是绿色,没有选中时候是黑色。 interactionSource.collectIsPressedAsState() 判断是否按下状态interactionSource.collectIsFocusedAsState() 判断是否获取焦点的状态interactionSource.collectIsDraggedAsState() 判断是否拖动
我们讲button的时候讲过,Button的讲解 - selectedContentColor 选中时候的颜色
- unselectedContentColor 没有选中时候的颜色
- content 内容
举例:Tab的按下时候是字体颜色是红色,选中时候字体颜色也是红色。我们的例子中,最终Tab会跟TabRow一起使用,所以我们先给出Tab部分的代码。
@Composable
fun tabView(index:Int,text:String,tabIndex:MutableState<Int>){
val interactionSource = remember {
MutableInteractionSource()
}
val isPress = interactionSource.collectIsPressedAsState().value
Tab(
selected = index == tabIndex.value,
onClick = {
tabIndex.value = index
},
modifier = Modifier
.wrapContentWidth()
.fillMaxHeight(),
enabled =true,
interactionSource = interactionSource,
selectedContentColor = Color.Red,
unselectedContentColor = Color.Black
) {
Text(text = text,color = if(isPress || index == tabIndex.value) Color.Red else Color.Black)
}
}
复制代码
二:LeadingIconTab
先来看看LeadingIconTab的代码
@ExperimentalMaterialApi
@Composable
fun LeadingIconTab(
selected: Boolean,
onClick: () -> Unit,
text: @Composable (() -> Unit),
icon: @Composable (() -> Unit),
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
selectedContentColor: Color = LocalContentColor.current,
unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
){...}
复制代码
- selected 是否选中
- onClick 点击事件
- text 文本控件
- icon Icon控件
- modifier 修饰符
- interactionSource 处理状态的类跟上面一致
- selectedContentColor 选中的颜色
- unselectedContentColor 没有选中时候的颜色
举例:Tab的按下时候是字体颜色跟Icon是红色,选中时候字体颜色和Icon也是红色。我们的例子中,最终LeadingIconTab会跟ScrollableTabRow一起使用,所以我们先给出LeadingIconTab部分的代码。
@ExperimentalMaterialApi
@Composable
fun leadingIconTabView(index:Int,text:String,tabIndex:MutableState<Int>){
val interactionSource = remember {
MutableInteractionSource()
}
val isPress = interactionSource.collectIsPressedAsState().value
val imageVector = when(index){
0-> Icons.Filled.Home
1-> Icons.Filled.Shop
2-> Icons.Filled.Favorite
3-> Icons.Filled.School
4-> Icons.Filled.ShoppingBag
5-> Icons.Filled.DesktopMac
6-> Icons.Filled.Message
7-> Icons.Filled.FmdGood
8-> Icons.Filled.Domain
else ->Icons.Filled.Person
}
LeadingIconTab(
selected = index == tabIndex.value,
onClick = {
tabIndex.value = index
},
text = {
Text(text = text,color = if(isPress || index == tabIndex.value) Color.Red else Color.Black)
},
icon = {
Icon(imageVector, contentDescription = "icon图标",tint = if(isPress || index == tabIndex.value) Color.Red else Color.Black)
},
modifier = Modifier.wrapContentWidth().fillMaxHeight().background(Color.White),
enabled = true,
interactionSource = interactionSource,
selectedContentColor = Color.Red,
unselectedContentColor = Color.Black
)
}
复制代码
三:TabRow
先来看看TabRow的代码
@Composable
fun TabRow(
selectedTabIndex: Int,
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions ->
TabRowDefaults.Indicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
)
},
divider: @Composable () -> Unit = @Composable {
TabRowDefaults.Divider()
},
tabs: @Composable () -> Unit
){
...
}
复制代码
- selectedTabIndex 选中的index位置
- modifier 修饰符
- backgroundColor 背景颜色
- contentColor 内容颜色
- indicator 选中的下面那条线 默认是实现是TabRowDefaults.Indicator。我们来看看TabRowDefaults.Indicator的代码
@Composable fun Indicator( modifier: Modifier = Modifier, height: Dp = IndicatorHeight, color: Color = LocalContentColor.current ) { Box( modifier .fillMaxWidth() .height(height) .background(color = color) ) } 复制代码
- modifier修饰符
- height 高度
- color 颜色
所以其实我们可以自定义
- divider tabRow下面那条线的 这个是一个Divider 默认实现是TabRowDefaults.Divider()。Divider的用法我们前面文章讲过 Divider用法
- tabs tabRow的内容
@Preview()
@Composable
fun tabRowTest(){
val tabIndex = remember {
mutableStateOf(0)
}
val tabDatas = ArrayList<String>().apply {
add("语文")
add("数学")
add("英语")
}
TabRow(
selectedTabIndex = tabIndex.value,
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
backgroundColor = Color.Green,
contentColor = Color.Black,
divider = {
TabRowDefaults.Divider()
},
indicator = {
TabRowDefaults.Indicator(
Modifier.tabIndicatorOffset(it[tabIndex.value]),
color = Color.Blue,
height = 2.dp
)
}
) {
tabDatas.forEachIndexed{
index, s ->
tabView(index,s,tabIndex)
}
}
}
@Composable
fun tabView(index:Int,text:String,tabIndex:MutableState<Int>){
val interactionSource = remember {
MutableInteractionSource()
}
val isPress = interactionSource.collectIsPressedAsState().value
Tab(
selected = index == tabIndex.value,
onClick = {
tabIndex.value = index
},
modifier = Modifier
.wrapContentWidth()
.fillMaxHeight(),
enabled =true,
interactionSource = interactionSource,
selectedContentColor = Color.Red,
unselectedContentColor = Color.Black
) {
Text(text = text,color = if(isPress || index == tabIndex.value) Color.Red else Color.Black)
}
}
复制代码
其实TabRow默认是Item是会平分TabRow的宽度。而ScrollableTabRow的Item会是自适应宽度的类型
四:ScrollableTabRow
先来看看ScrollableTabRow的代码
@Composable
fun ScrollableTabRow(
selectedTabIndex: Int,
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
edgePadding: Dp = TabRowDefaults.ScrollableTabRowPadding,
indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions ->
TabRowDefaults.Indicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
)
},
divider: @Composable () -> Unit = @Composable {
TabRowDefaults.Divider()
},
tabs: @Composable () -> Unit
){
...}
复制代码
- selectedTabIndex 选中的index
- modifier修饰符
- backgroundColor背景颜色
- contentColor内容颜色
- edgePadding 是ScrollableTabRow开头和结尾的留白的的大小 默认是54dp
- indicator 选中时候下面那条线 跟上面一致
- divider ScrollableTabRow下面的线 跟上面一致
- tabs ScrollableTabRow的内容
举例有9个tab。tab是带Icon的LeadingIconTab,选中和按下的时候图标和文字变红。
@ExperimentalMaterialApi
@Preview()
@Composable
fun scrollableTabRowTest(){
val tabIndex = remember {
mutableStateOf(0)
}
val tabDatas = ArrayList<String>().apply {
add("第1tab")
add("第2tab")
add("第3tab")
add("第4tab")
add("第5tab")
add("第6tab")
add("第7tab")
add("第8tab")
add("第9tab")
}
ScrollableTabRow(
selectedTabIndex = tabIndex.value,
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
backgroundColor = Color.White,
contentColor = Color.Black,
edgePadding = 10.dp,
divider = {
TabRowDefaults.Divider(color = Color.Red)
},
indicator = {
TabRowDefaults.Indicator(
Modifier.tabIndicatorOffset(it[tabIndex.value]),
color = Color.Blue,
height = 2.dp
)
},
tabs = {
tabDatas.forEachIndexed{
index, s ->
leadingIconTabView(index,s,tabIndex)
}
})
}
@ExperimentalMaterialApi
@Composable
fun leadingIconTabView(index:Int,text:String,tabIndex:MutableState<Int>){
val interactionSource = remember {
MutableInteractionSource()
}
val isPress = interactionSource.collectIsPressedAsState().value
val imageVector = when(index){
0-> Icons.Filled.Home
1-> Icons.Filled.Shop
2-> Icons.Filled.Favorite
3-> Icons.Filled.School
4-> Icons.Filled.ShoppingBag
5-> Icons.Filled.DesktopMac
6-> Icons.Filled.Message
7-> Icons.Filled.FmdGood
8-> Icons.Filled.Domain
else ->Icons.Filled.Person
}
LeadingIconTab(
selected = index == tabIndex.value,
onClick = {
tabIndex.value = index
},
text = {
Text(text = text,color = if(isPress || index == tabIndex.value) Color.Red else Color.Black)
},
icon = {
Icon(imageVector, contentDescription = "icon图标",tint = if(isPress || index == tabIndex.value) Color.Red else Color.Black)
},
modifier = Modifier.wrapContentWidth().fillMaxHeight().background(Color.White),
enabled = true,
interactionSource = interactionSource,
selectedContentColor = Color.Red,
unselectedContentColor = Color.Black
)
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END