1. 前言
上篇文章 我们实现了 Compose Bloom项目的开发页,这篇文章接着上文,来介绍主页的开发。
2. 分析页面布局
根据UI稿我们可知,这个页面有一个底部切换的BottomBar
,还有一个搜索框,一个横向的列表以及一个竖向的列表。
3. 定义数据
首先先定义数据
data class ImageItem(val name: String, val resId: Int)
val navList = listOf(
ImageItem("Home", R.drawable.ic_home),
ImageItem("Favorites", R.drawable.ic_favorite_border),
ImageItem("Profile", R.drawable.ic_account_circle),
ImageItem("Cart", R.drawable.ic_shopping_cart)
)
val gardenList = listOf(
ImageItem("Monstera", R.drawable.monstera),
ImageItem("Aglaonema", R.drawable.aglaonema),
ImageItem("Peace lily", R.drawable.peace_lily),
ImageItem("Fiddle leaf", R.drawable.fiddle_leaf),
ImageItem("Snake plant", R.drawable.snake_plant),
ImageItem("Pothos", R.drawable.pothos),
)
val themeList = listOf(
ImageItem("Desert chic", R.drawable.desert_chic),
ImageItem("Tiny terrariums", R.drawable.tiny_terrariums),
ImageItem("Jungle vibes", R.drawable.jungle_vibes),
ImageItem("Easy care", R.drawable.easy_care),
ImageItem("Statements", R.drawable.statements),
)
4. 实现底部Tab栏BottomBar
Scaffold
是Android
中的脚手架Scaffold
,Compose
提供了大量基于 Material Design
的可组合项以及依赖项,旨在简化界面的构建。Scaffold
可以实现具有基本 Material Design
布局结构的界面,比如Drawer
、FloatingActionButton
、 TopAppBar
以及BottomBar
@Preview
@Composable
fun HomePage() {
Scaffold(bottomBar = {
BottomBar()
}) {
}
}
@Preview(showBackground = true, backgroundColor = 0xFFFFFF)
@Composable
fun BottomBar() {
BottomNavigation(
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
backgroundColor = pink100,
) {
navList.forEach {
val isSelected = "Home" == it.name
BottomNavigationItem(selected = isSelected, onClick = { }, icon = {
Image(
painter = painterResource(id = it.resId),
contentDescription = "",
modifier = Modifier.size(24.dp),
colorFilter = ColorFilter.tint(
if (isSelected) gray else Color(
0xff757575
)
)
)
}, label = {
Text(
text = it.name,
style = caption,
color = if (isSelected) gray else Color(0xff757575)
)
})
}
}
}
预览效果如下所示
5. 实现搜索框
搜索框其实就是OutlinedTextField
,带边框的输入框,leadingIcon
中传入Icon
,用来显示搜索图标。
@Preview(showBackground = true)
@Composable
fun SearchBar() {
val keyword = remember { mutableStateOf("") }
Box(
modifier = Modifier
.height(96.dp)
.padding(top = 40.dp)
) {
OutlinedTextField(
value = keyword.value, onValueChange = {
keyword.value = it
}, modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp),
maxLines = 1,
placeholder = { Text(text = "Search", style = MaterialTheme.typography.body1) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.Search,
contentDescription = null,
modifier = Modifier.size(18.dp)
)
}
)
}
}
预览效果如下所示
6. 实现横向列表
首先实现Item
@Composable
private fun BloomRowTitle() {
Text(
text = "Browse themes",
modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 6.dp),
style = h1
)
}
然后实现横向列表
@Composable
fun BloomRowList() {
LazyRow(content = {
items(themeList.size) {
ThemeCard(themeList[it])
}
}, modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 3.dp))
}
预览效果如下
@Preview(showBackground = true, backgroundColor = 0xFFFFFF)
@Composable
fun BloomRowPreView() {
Column {
BloomRowTitle()
BloomRowList()
}
}
7. 实现竖向的列表
首先实现Item
@Composable
fun BloomListTitle() {
Box(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
) {
Text(
text = "Design you home garden",
modifier = Modifier.align(Alignment.CenterStart),
style = h1,
)
Image(
imageVector = Icons.Default.FilterList,
contentDescription = null,
modifier = Modifier.align(Alignment.CenterEnd),
colorFilter = ColorFilter.tint(MaterialTheme.colors.onBackground)
)
}
}
然后实现竖向列表
@Composable
fun BloomList() {
LazyColumn(content = {
items(gardenList.size) {
ItemGarden(it == 0, gardenList[it])
}
})
}
来实现具体的Item
@Composable
fun ItemGarden(checked: Boolean, item: ImageItem) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp, horizontal = 16.dp)
.height(64.dp),
) {
Image(
painter = painterResource(id = item.resId),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier
.height(64.dp)
.width(64.dp)
.clip(shape = RoundedCornerShape(4.dp))
)
Column(modifier = Modifier.padding(start = 80.dp)) {
Text(text = item.name, style = h2, modifier = Modifier.padding(top = 12.dp))
Text(text = "This is a description", style = body1)
}
Checkbox(
checked = checked,
onCheckedChange = {},
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(end = 16.dp)
)
Divider(
modifier = Modifier
.padding(start = 72.dp, end = 16.dp)
.align(Alignment.BottomStart)
)
}
}
预览效果如下
8. 组装所有组件
@Composable
fun HomePage() {
Scaffold(bottomBar = {
BottomBar()
}) {
Column {
SearchBar()
BloomRowTitle()
BloomRowList()
BloomListTitle()
BloomList()
}
}
}
最终显示效果如下
9. 小结
至此,我们就完成了主页的UI效果,下一篇文章,我们将来处理Compose页面见的跳转 (待更新)
Compose 项目实战 系列文章
Android Compose Bloom 项目实战 (一) : 项目说明与配置
Android Compose Bloom 项目实战 (二) : 欢迎页
Android Compose Bloom 项目实战 (三) : 登录页
本文源码 : ComposeBloom