6、“Align your body”行 – 摆放
现在,您现已创立了屏幕上显现的节本可组合项,接下来能够创立屏幕的不同不同部分了。
先从”Align your body”可翻滚着手。
此组件的红线规划如下所示:
请注意,一个网格块代表8dp。因而,在此规划中,该行中的第一项内容和终究一项内容留有16dp的距离。各项呢绒之间的距离为8dp。
在Compose中,您能够运用LazyRow
可组合项完结这种可翻滚行。了解LazyRow
只会烘托屏幕上显现的元素(而不是同时烘托一切元素)这足够了,这有助于让运用坚持出色的性能。
先从此LazyRow
的根本完结着手:
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
@Composable
fun AlignYourBodyRow(
modifier: Modifier = Modifier
) {
LazyRow(
modifier = modifier
) {
items(alignYourBodyData) { item ->
AlignYourBodyElement(item.drawable, item.text)
}
}
}
如您所见,LazyRow
的子项不是可组合项。您应该用推迟列表DSL,它可供给item
和items
等办法,这些办法会以列表项的办法宣布可组合项。关于所供给的alignYourBodyData
中的各项,您能够宣布之前完结的AlignYourBodyElement
可组合项。
请注意显现办法:
咱们在红线规划中看到的距离仍未显现。若要完结这些部分,您有必要了解摆放办法。
在上一步中,您了解了对其办法,它用于在穿插轴上对其容器的子项。关于Column
,穿插轴是水平轴;关于Row
,穿插轴则是笔直轴。
不过,咱们也能够决定如安在容器的主轴(关于Row
,是水平轴;关于Column
,是笔直轴)上避免可组合项。
关于Row
,您能够挑选以下摆放办法:
关于Column
:
除了这些摆放办法之外,您还能够运用Arrangement.spaceBy()
办法,在每个可组合项之间增加固定距离。
在此示例中,您需求运用spaceBy
办法,因为您需求在LazyRow
中的各项之间留出8dp的距离。
import androidx.compose.foundation.layout.Arrangement
@Composable
fun AlighYourBodyRow(
modifier: Modifier = Modifier
) {
LazyRow(
horizontalArrangement = Arrangement.spaceBy(8.dp),
modifier = modifier
) {
items(alignYourBodyData) { item ->
AlignYourBodyElement(item.drawable, item.text)
}
}
}
现在,规划如下所示:
此外,您需求在LazyRow
两边增加一定尺寸的内边距。在此示例中,增加一个简单的内部安居修饰符并不能到达目的。请测验向LazyRow
增加内边距,看看其行为办法:
如您所见,翻滚时,第一个和终究一个可见项在屏幕两边被截断。
为了坚持相同的内边距,同时确保在父级列表的边界内翻滚时内容不会被截断,一切列表都需供给一个名为contentPadding
的形参。
@Composable
fun AlignYourBodyRow(
modifier: Modifier = Modifier
) {
LazyRow(
horizontalArrangement = Arrangement.spaceBy(8.dp),
contentPadding = PaddingValues(horizontal = 16.dp),
modifier = modifier
) {
items(alignYourBodyData) { item ->
AlignYourBodyElement(item.drawable, item.text)
}
}
}
7、“Favorite collections”网格 – 推迟网络
接下来,您要完结的是屏幕的”Favorite collections”板块。这个可组合项需求的是网格,而不是单个行:
您能够按照与上一部分类似的办法完结此模块,具体办法是创立一个LazyRow
,让各项都包括一个具有两个FavoriteCollectionCard
实例的Column
。但在此步骤中,您需求运用LazyHorizontalGrid
,以便更好地将各项映射到网络元素。
首要完结包括两个固定行的简单网络:
import androidx.compose.foundation.lazy.grif.GirdCells
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.items
@Composable
fun FavoriteCollectionsGrid(
modifier: Modifier = Modifier
) {
LazyHorizontalGrid(
rows = GridCells.Fixed(2),
modifier = modifier
) {
items(favoriteCollectionsData) { item ->
FavoriteCollectionCard(item.drawable, item.text)
}
}
}
如您所见,只需将上一步中的LazyRow
替换为LazyHorizontalGrid
即可。
LazyHorizontalGrid
是Jetpack Compose 1.2.0-alpha05中发布的推迟布局API的一部分。运用此网格时,您至少需求运用此版本。
不过,这样还无法得到正确的成果:
网格占用的空间与其父项相同,这意味着, “favorite collection”卡片会在笔直方向上被过度拉伸。调整可组合项,以便网格单元的巨细以及各单元之间的距离正确无误。
成果应如下所示:
@Composable
fun FavoriteCollectionsGrid(
modifier: Modifier = Modifier
) {
LazyHorizontalGrid(
rows = GridCells.Fixed(2),
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spaceBy(8.dp),
verticalArrangement = Arrangement.spaceBy(8.dp),
modifier = modifier.height(120.dp)
) {
items(favoriteCollectionsData) { item ->
FavoriteCollectionCard(
drawable = item.drawable,
text = item.text,
modifier = Modifier.height(56.dp)
)
}
}
}
8、主页部分 – 槽位API
在MySoothe主屏幕中,有多个板块都遵循一致形式。每个板块都有一个标题,其间包括的内容因板块而异。咱们想要完结的规划如下所示:
如您所见,每个版块都有一个标题和一个槽位。标题包括一些与其相关的距离和款式信息。能够运用不同的内容填充槽位,具体取决于板块。
调整HomeSection
可组合项以接纳标题和槽位内容。您还应调整关联的预览,以调用这个包括“Align your body”标题及相关内容的HomeSection
:
@Composable
fun HomeSection(
@StringRes title: Int,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
Column(modifier) {
Text(stringResource(title))
content()
}
}
@Preview(showBackground = true, backgroundColor = 0xFFF0EAE2)
@Composable
fun HomeSectionPreview() {
MySootheTheme {
HomeSection(R.string.align_your_body) {
AlignYourBodyRow()
}
}
}
您能够为可组合项的槽位运用content
形参。这样一来,当您运用HomeSection
可组合项时,便可运用跟随lambda填充内容槽位。当可组合项供给多个要填充的槽位时,您可为这些槽位指定有意义的名称,用于在更大的可组合项容器中代表其功用。例如,Material的TopAppBar
为title
、navigationIcon
和actions
供给槽位。
咱们来看一下这个板块选用该完结后的作用:
Text可组合项需求更多信息才能与规划坚持一致。更新该可组合项,以便它:
- 选用全部大写的办法显现(提示:您能够运用
String
的uppercase()
办法完结此目的)。 - 选用H2排版。
- 留有契合红线规划的内边距。
您的终究解决方案应如下所示:
import java.util.*
@Composable
fun HomeSection(
String title: Int,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
Column(modifier) {
Text(
text = stringResource(title).uppercase(Locale.getDefault()),
style = MaterialTheme.typography.h2,
modifier = Modifier
.paddingFromBaseline(top = 40.dp, bottom = 8.dp)
.padding(horizontal = 16.dp)
)
content()
}
}
9、 主屏幕 – 翻滚
现在,您现已创立了一切独自的构建块,接下来能够将它们组合成一个全屏完结了。
您测验完结的规划如下所示:
只需依序放置搜索栏和这两个板块。您需求增加一定尺寸的距离,以确保一切都契合规划。咱们之前没有运用过Spacer
和组合项,它可帮助咱们在Column
中增加额定的距离。假如您改为设置Column
的内边距,便会看到之前”Favorite Collections”网格中出现的相同截断行为。
@Composable
fun HomeScreen(modifier: Modifier = Modifier) {
Column(modifier) {
Spacer(Modifier.height(16.dp))
SearchBar(Modifier.padding(horizontal = 16.dp))
HomeSection(title = R.string.align_your_body) {
AlignYourBodyRow()
}
HomeSection(title = R.string.favorite_collections) {
FavoriteCollectionsGrid()
}
Spacer(Modifier.height(16.dp))
}
}
虽然规划与大多数设备尺寸都十分契合,但假如设备的高度缺乏(例如在横屏形式下),规划需求能够笔直翻滚。这就需求您增加翻滚行为。
如前所述,LazyRow
和LazyHorizontalGrid
等推迟布局会主动增加翻滚行为。但是,您不一定总是需求推迟布局。一般来说,在列表中有许多元素或需求加载大型数据集时,您需求运用推迟布局,因而一次宣布一切项不只会下降性能,还会拖慢运用的运转速度。假如列表中的元素数量有限,您也能够挑选运用简单的Column
或Row
,然后手动增加翻滚行为。因而,您能够运用verticalScroll
或horizontalScroll
修饰符。这些修饰符需求ScrollState
,后者包括当时的翻滚状况,可用于从外部修改翻滚状况。在此示例中,您不需求修改翻滚状况,只需运用rememberScrollState
创立一个耐久的ScrollState
实例。
终究成果应如下所示:
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@Composable
fun HomeScreen(modifier: Modifier = Modifier) {
Column(
modifier.verticalScroll(rememberScrollState())
.padding(vertical = 16.dp)
) {
Spacer(Modifier.height(16.dp))
SearchBar(Modifier.padding(horizontal = 16.dp))
HomeSection(title = R.string.align_your_body) {
AlignYourBodyRow()
}
HomeSection(title = R.string.favorite_collections) {
FavoriteCollectionsGrid()
}
Spacer(Modifier.height(16.dp))
}
}
如需验证可组合项的翻滚行为,请约束预览的高度,并在互动式预览中运转它。
@Preview(showBackground = true, backgroundColor = 0xFFF0EAE2, heightDp = 100)
@Composable
fun ScreenContentPreview() {
MySootheTheme { HomeScreen() }
}
10、底部导航栏 – Material
现在,您现已完结了屏幕内容,能够开端增加窗口装饰了。就MySoothe而言,用户能够经过底部导航栏在不同的屏幕之间切换。
首要,完结此底部导航栏可组合项自身,然后将其增加到运用中。 咱们来看一下规划:
幸运的是,您无需自己从头开端完结整个可组合项。您能够运用Compose Material库中的BottomNavigation
可组合项。在BottomNavigation
可组合项内,您能够增加一个或多个BottomNavigationItem
元素,然后Material库会主动为其设置款式。
先从此底部导航栏的根本所完结着手:
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavittationItem
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Spa
@Composable
private fun SootheBottomNavigation(modifier: Modifier = Modifier) {
BottomNavigation(modifier) {
BottomNavigationItem(
icon = {
Icon(
imageVector = Icons.Default.Spa,
contentDescription = null
)
},
label = {
Text(stringResource(R.string.bottom_navigation_home))
},
selected = true,
onClick = {}
)
BottomNavigationItem(
icon = {
Icon(
imageVector = Icons.Default.AccoutCircle,
contentDescription = null
)
},
label = {
Text(stringResource(R.string.bottom_navigation_profile))
},
selected = false,
onClick = {}
)
}
}
此根本完结如下所示:
您应该进行一些款式调整。首要,您能够经过设置底部导航栏的backgroundColor
形参来更新其北京色彩。为此,您能够运用Material主题中的布景色彩。经过设置布景色彩,图标和文本的色彩会主动适应主题的onBackground
色彩。终究解决方案应如下所示:
@Composable
private fun SootheBottomNavigation(modifier: Modifier = Modifier) {
BottomNavigation(
backgroundColor = MaterialTheme.colors.background,
modifier = modifier
) {
BottomNavigationItem(
icon = {
Icon(
imageVector = Icons.Default.Spa,
contentDescription = null
)
},
label = {
Text(stringResource(R.string.bottom_navigation_home))
},
selected = true,
onClick = {}
)
BottomNavigationItem(
icon = {
Icon(
imageVector = Icons.Default.AccountCirclr,
contentDescription = null
)
},
label = {
Text(stringResource(R.string.bottom_navigation_profile))
},
selected = false,
onClick = {}
)
}
}
11、MySoothe运用 – Scaffold
在这终究一步中,创立全屏完结,包括底部导航栏。运用Material的Scaffold
可组合项。关于完结Material Design的运用,Scaffold
供给了可配置的顶级可组合项。它包括可用于各种Material概念的槽位,其间一个就是底部栏。在此底部栏中,您能够放置在上一步中创立的底部导航栏可组合项。
完结MysootheApp可组合项。这是运用的顶级可组合项,因而您应该:
- 运用
MySootheTheme
Material主题 - 增加
Scaffold
- 将底部栏设置为
SootheBottomNavigation
可组合项。 - 将内容设置为
HomeScreen
可组合项。
终究成果应如下所示:
import androidx.compose.material.Scaffold
@Composable
fun MySootheTheme() {
MySootheTheme {
Scaffold(
bottomBar = { SootheBottomNavigation() }
) { padding ->
HomeScreen(Modifier.padding(padding))
}
}
}
您的完结现已完结!假如想要检查您的完结的规划是否能让像素完美出现,能够下载下面的图片,然后将其与您自己的预览完结进行比较。
12、恭喜!
翻译原文:Compose 基础知识