前言
Jetpack Compose 是用于构建原生界面的新款 Android 工具包。它可简化并加快 Android 上的界面开发。使用更少的代码、强大的工具和直观的 Kotlin API,快速让应用生动而精彩。这是官方对它的介绍。2019年Google就推出了Jetpack Compose,并且稳定版本即将在2021年7月发布,所以大家还是有必要提前学习一下的。
通过这一段时间的学习,了解到Jectpack Compose是一种全新的UI开发框架,采用了声明式编程思想,完全基于Kotlin语言,并将之前的Xml UI界面渲染那一套逻辑完全废弃了,所以界面布局/渲染/刷新机制完全是新的。
需要实现的功能
Pager组件介绍
Pager组件是专门为使用Jetpack Compose开发类似页面切换布局的一个库,类似AndroidView中的Viewpager,需要注意的是,当前该组件还在实验阶段,所以库中的API可能还会发生变化,并且所有的API都加了@ExperimentalPagerApi注解
该组件库中目前提供了:
1)HorizontalPager:水平方向切换页面的组件,简单用法:
// Display 10 items
val pagerState = rememberPagerState(pageCount = 10)
HorizontalPager(state = pagerState) { page ->
// Our page content
Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() )
}
通过pagerState可以得到当前页面:pagerState.currentPage,可以滚动到指定页面:pagerState.scrollToPage(index),或者pagerState.animateScrollToPage(index),但这两个方法需要在CoroutineScope使用,如下:
coroutineScope.launch { pagerState.animateScrollToPage(index)}
2) VerticalPager:竖直方向切换页面的组件,基本使用方式同HorizontalPager
3)同ViewPager一样,Pager组件同样可以指定当前页面两侧的页数,通过设置initOffscreenLimit字段
val pagerState = rememberPagerState( pageCount = 10, initialOffscreenLimit = 2,)
HorizontalPager(state = pagerState) { page -> // ...}
并且,当用户在界面间滑动时,超过该数量的界面就会被动态移除。
Demo实现
需要上图中多tab样式的feed流样式,需要用到的组件:TabRow + Pager + Indicators + LazyColumn,对应AndroidView的TabLayout + ViewPager + RecyclerView
环境准备:app下的build.gradle中引入如下依赖:
implementation "com.google.accompanist:accompanist-pager:0.13.0"
implementation "com.google.accompanist:accompanist-pager-indicators:0.13.0"
Node:本文基于Jetpack Compose 1.0.0-beta09'
关键代码:
@ExperimentalPagerApi
@Composable
private fun TabContentScreen(recItems: List<PostData>, followItems: List<PostData>, hotItems: List<PostData>) {
val pages = listOf("热门", "关注", "推荐")
Column {
val coroutineScope = rememberCoroutineScope()
val pagerState = rememberPagerState( pageCount = pages.size, initialOffscreenLimit = 2, )
TabRow( selectedTabIndex = pagerState.currentPage, indicator = {tabPositions ->
TabRowDefaults.Indicator( Modifier.pagerTabIndicatorOffset(pagerState, tabPositions), color = Color.White ) },
backgroundColor = Color.White, modifier = Modifier.width(210.dp),
divider = { TabRowDefaults.Divider(color = Color.White) } ) {
pages.forEachIndexed { index, title ->
Tab( selected = pagerState.currentPage == index, onClick = {
coroutineScope.launch { pagerState.animateScrollToPage(index) }
},
modifier = Modifier.height(50.dp).background(Color.White),
selectedContentColor = Color.Black,
unselectedContentColor = Color.Gray ) {
Text(title, maxLines = 1,
fontSize = if (pagerState.currentPage == index) 20.sp else 16.sp,
fontWeight = if (pagerState.currentPage == index) FontWeight.Bold else FontWeight.Normal )
}
}
}
HorizontalPager( state = pagerState, modifier = Modifier .weight(1f) .fillMaxWidth() ) {
LazyColumn(contentPadding = PaddingValues(start = 16.dp, end = 16.dp)) {
val curItems = if (pagerState.currentPage == 0) {
recItems
} else if (pagerState.currentPage == 1) {
followItems
} else {
hotItems
}
items(items = curItems) {
PostCardView(itemData = it)
}
}
}
}
}
PS:简书的难道没有直接插入代码的功能吗,太难用了