- 效果图
- 开源地址:
- 功能介绍:
- SnakeRowTab:
- SnakeRowTab:
- 关于构造函数的解释
- 使用示例:
最近研究且学习Compose,目的是能够用Compose进行商业项目开发,过程中发现了Compose官方提供的Tab 为TabRow和ScrollTabRow,使用后感觉效果不错,但是定制性太差,完全无法用到项目中去,因此自己造轮子
效果图有水印,将就着看一下吧…
SnakeTab
我的项目开源在Gitee,且代码量非常小,
可选择直接使用(使用过后觉得好用,请给我点个star)
snakeTab目前支持横向Tab,包含两个主要Compose组件,SnakeRowTab与SnakeScrollTab
SnakeRowTab:宽度不满一屏,且想要在轴上摆放Tab
SnakeRowTab,主要功能是用于在轴方向上摆放Tab,对齐方式有:
SpaceBetween,SpaceAround,SpaceEvenly等
其主要功能是,当tab宽度超过一屏时,可滚动tab,切能够跟随设定的tabScrollPosition进行位置固定的滚动,如上方效果图中,当pager滚动后,tab滚动位置总是停留在scrollPOsition
当然关于效果,描述上去始终是乏力的,感兴趣的,去拉代码run起来看一看
关于构造函数的解释首先两个组件在细节上会有不同,在这里只做简单的描述,如果有不太清楚的,可以私信给我
modifier:装饰器
tabWidth:tab的总宽度
selectIndex:选中的位置,通常与pager等联动
tabs :@Composable()->Unit 具体的tab内容,文章下方会给出使用示例
tabAlignment: tab自身的对齐方式,目前tab支持的是Text类型的tab,以baseLine为基准进行对齐,以后会支持任何类型组件对齐
tabAxisAlignment :tab在轴上的分配方式,SpaceEvenly,SpaceBetween,SpaceAround等
indicator: 指示器,通常为tab下方,当tab被选中时展示的组件
indicatorRule: 指示器规则,设定指示器的宽度是跟随自身 还是跟随每一个Tab的宽度
indicatorOffset: 指示器的Offset,支持4个方向上位移
indicatorScrollPercentage: 指示器的滚动百分比,当需要指示器跟随pager之类的进行滚动时,需要传一个百分比,使得指示器跟随(例如:手指在pager中滑动 10.dp,这10.dp相对于pager的宽度,占比为 5%,因此传入这0.05),文章下方会有使用示例
tabContentPadding : tab的内容间距
class SnakeRowTabActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val pagerData = mutableListOf() val tabData = mutableListOf () for (index in 1..3) { pagerData.add("${index}--page") tabData.add("tab$index") } val pagerWidth = with(LocalDensity.current){ this@SnakeRowTabActivity.resources.displayMetrics.widthPixels.toDp() } ShowContent(pagerData, tabData,pagerWidth,pagerWidth) } } @OptIn(ExperimentalPagerApi::class) @Composable fun ShowContent(pagerdata: List , tabdata: List ,tabWidth :Dp,pagerWidth:Dp){ val pagerState = rememberPagerState() val pagerWidthPx = with(LocalDensity.current){ pagerWidth.toPx() } var tabSelectIndex by remember { mutableStateOf(0) } var lastTabSelectIndex by remember { mutableStateOf(0) } var indicatorScrollPercentage by remember { mutableStateOf(0f) } LaunchedEffect(key1 = pagerState.currentPage + tabSelectIndex, block = { if (tabSelectIndex == lastTabSelectIndex) { //触发来源于pagerState tabSelectIndex = pagerState.currentPage } else { //触发来源于tabSelect pagerState.animateScrollToPage(tabSelectIndex) } indicatorScrollPercentage = 0f lastTabSelectIndex = tabSelectIndex }) val nestedScroll = remember { object : NestedScrollConnection { override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { indicatorScrollPercentage += available.x / pagerWidthPx return Offset.Zero } } } Column( modifier = Modifier .background(Color.White) .fillMaxWidth() .fillMaxHeight() ) { SnakeRowTab( Modifier.background(Color.Blue), tabWidth=tabWidth, selectIndex = tabSelectIndex, tabs = { tabData.forEachIndexed { index, s -> Text( text = s, Modifier.clickable { tabSelectIndex = index }, fontSize = if (index == tabSelectIndex) 20.sp else 13.sp, color = if (index == tabSelectIndex) Color.Red else Color.White ) } }, tabAlignment = SnakeTabSetting.tabAlignment, tabAxisAlignment=SnakeTabSetting.tabAxisAlignment, indicator = { Box( Modifier .width(20.dp) .height(4.dp) .background(Color.Red) ) }, indicatorRule = SnakeTabSetting.indicatorRule, indicatorOffset = DpOffset(0.dp, 0.dp), indicatorScrollPercentage = if (SnakeTabSetting.moveByOther) indicatorScrollPercentage else 0f, ) HorizontalPager( count = pagerData.size, modifier = Modifier .background(Color.Gray) .nestedScroll(nestedScroll), state = pagerState ) { index -> Text(text = pagerData[index], textAlign = TextAlign.Center, fontSize = 20.sp) } } } }
另一个组件的使用也雷同,因此不做额外展示
代码中只是对SnakeRowTab做使用,为了与pager进行联动,使用nestedScroll进行pager的事件获取,在计算后,返回给了SnakeRowTab,也算是顺便演示了一下nestedScroll的用法
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)