Android Jetpack Compose 网格查看视图
Android Jetpack Compose Grid looking view
我的屏幕分为三个主要部分,目前(我想可能有更好的方法):
- 第一部分是展示数据。它分为9个几乎相同的项目来显示不同的实时(定期变化的数据)。它们现在是 3 行 3 列(我想可能有更好的方法)。
在它们下面,我有内部的屏幕选项卡导航,它将控制哪个片段将显示在屏幕的最后一部分。
在屏幕的底部,我想我需要 fragmentFrame(我会研究它在 Jetpack Compose 中的等价物),以及更频繁更改的数据(图表、地图等中显示的数据)。当在屏幕的第 2) 部分选择特定选项卡时,将显示每个片段。
这是我创建屏幕的代码:
@ExperimentalFoundationApi
@Composable
fun ActivityCustomGridScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Gray)
.fillMaxHeight(/*4f*/)
.fillMaxWidth(/*4f*/)
) {
CustomItem(1f, MaterialTheme.colors.secondaryVariant)
CustomItem(1f, MaterialTheme.colors.secondary)
CustomItem(1f, MaterialTheme.colors.onSurface)
CustomItem(0.7f, MaterialTheme.colors.onError, false)
CustomItem(2.5f, areItemsShown = false)
}
}
@Composable
fun ColumnScope.CustomItem(
weight: Float,
color: Color = MaterialTheme.colors.primary,
areItemsShown: Boolean = true
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
// .width(200.dp)
.weight(weight)
.padding(3.dp),
color = color
) {
Row(
Modifier
.weight(3f)
) {
if (areItemsShown) {
ActivityCardComponent(
ParameterItemState(), modifier = Modifier
.padding(5.dp)
.weight(1f)
)
ActivityCardComponent(
ParameterItemState(), modifier = Modifier
.padding(5.dp)
.weight(1f),
Alignment.CenterHorizontally
)
ActivityCardComponent(
ParameterItemState(), modifier = Modifier
.padding(5.dp)
.weight(1f),
Alignment.End
)
}
}
}
}
- 此外,我在从屏幕的第一部分创建单个项目以达到理想大小时遇到问题(我希望每列有 3 个项目,按此比例 1:2:1)
@Composable
fun ActivityCardComponent(
itemData: ParameterItemState, modifier: Modifier,
alignment: Alignment.Horizontal = Start
) {
Card(
modifier = modifier
.wrapContentWidth(alignment)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.background(Color.Red)
) {
Image(
painter = painterResource(id = itemData.getIndicatorIcon()),
contentDescription = "Sport Parameter Icon"
)
Column(Modifier.padding(4.dp)) {
Text(
stringResource(itemData.getIndicatorTittle()),
modifier = Modifier
.align(Alignment.CenterHorizontally),
style = MaterialTheme.typography.overline,
)
Spacer(modifier = Modifier.defaultMinSize())
Text(
text = itemData.parameterValue,
modifier = Modifier,
style = MaterialTheme.typography.subtitle1
)
Text(
stringResource(itemData.getIndicatorDimensionName()),
modifier = Modifier.align(Alignment.End),
style = MaterialTheme.typography.overline
)
}
}
}
}
我的物品状态class:
data class ParameterItemState(
val parameterValue: String = "12 345",
val parameterDimension: IndicatorsEnum = IndicatorsEnum.DISTANCE_IN_METERS,
val itemVisibility: Int = View.VISIBLE,
val itemPosition: Int = 0,
) {
fun getIndicatorTittle() = parameterDimension.getIndicatorTittle() // Speed (Time per 500m) id
fun getIndicatorDimensionName() = parameterDimension.getIndicatorDimensionName() // ave per 500 m id
fun getIndicatorIcon() = parameterDimension.getIndicatorIcon() // icon id
}
我仍然没有创建视图模型的东西,我也会接受包含它的答案。
看起来很简单
@Composable
fun Test(){
Scaffold(Modifier.fillMaxSize()) {
Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(8.dp)) {
BoxWithConstraints(Modifier.weight(1f)) {
Column(
Modifier.padding(8.dp).fillMaxSize(), verticalArrangement = Arrangement.spacedBy(8.dp)
) {
val height = (this@BoxWithConstraints.maxHeight - 32.dp) / 3
Item(height)
Item(height)
Item(height)
}
}
LazyRow(contentPadding = PaddingValues(horizontal = 8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)){
items(5) { index ->
Box(
Modifier
.size(56.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color.Yellow, RoundedCornerShape(8.dp)))
}
}
Box(
Modifier
.fillMaxSize()
.weight(1f)
.background(Color.Blue)) {
}
}
}
}
@Composable
fun Item(maxHeight: Dp){
Row(
Modifier
.fillMaxWidth()
.height(maxHeight),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Box(
Modifier
.fillMaxSize()
.weight(1f)
.background(Color.Red, RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
)
Box(
Modifier
.fillMaxSize()
.weight(2f)
.background(Color.Red, RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
)
Box(
Modifier
.fillMaxSize()
.weight(1f)
.background(Color.Red, RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
)
}
}
我的屏幕分为三个主要部分,目前(我想可能有更好的方法):
- 第一部分是展示数据。它分为9个几乎相同的项目来显示不同的实时(定期变化的数据)。它们现在是 3 行 3 列(我想可能有更好的方法)。
在它们下面,我有内部的屏幕选项卡导航,它将控制哪个片段将显示在屏幕的最后一部分。
在屏幕的底部,我想我需要 fragmentFrame(我会研究它在 Jetpack Compose 中的等价物),以及更频繁更改的数据(图表、地图等中显示的数据)。当在屏幕的第 2) 部分选择特定选项卡时,将显示每个片段。
这是我创建屏幕的代码:
@ExperimentalFoundationApi
@Composable
fun ActivityCustomGridScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Gray)
.fillMaxHeight(/*4f*/)
.fillMaxWidth(/*4f*/)
) {
CustomItem(1f, MaterialTheme.colors.secondaryVariant)
CustomItem(1f, MaterialTheme.colors.secondary)
CustomItem(1f, MaterialTheme.colors.onSurface)
CustomItem(0.7f, MaterialTheme.colors.onError, false)
CustomItem(2.5f, areItemsShown = false)
}
}
@Composable
fun ColumnScope.CustomItem(
weight: Float,
color: Color = MaterialTheme.colors.primary,
areItemsShown: Boolean = true
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
// .width(200.dp)
.weight(weight)
.padding(3.dp),
color = color
) {
Row(
Modifier
.weight(3f)
) {
if (areItemsShown) {
ActivityCardComponent(
ParameterItemState(), modifier = Modifier
.padding(5.dp)
.weight(1f)
)
ActivityCardComponent(
ParameterItemState(), modifier = Modifier
.padding(5.dp)
.weight(1f),
Alignment.CenterHorizontally
)
ActivityCardComponent(
ParameterItemState(), modifier = Modifier
.padding(5.dp)
.weight(1f),
Alignment.End
)
}
}
}
}
- 此外,我在从屏幕的第一部分创建单个项目以达到理想大小时遇到问题(我希望每列有 3 个项目,按此比例 1:2:1)
@Composable
fun ActivityCardComponent(
itemData: ParameterItemState, modifier: Modifier,
alignment: Alignment.Horizontal = Start
) {
Card(
modifier = modifier
.wrapContentWidth(alignment)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.background(Color.Red)
) {
Image(
painter = painterResource(id = itemData.getIndicatorIcon()),
contentDescription = "Sport Parameter Icon"
)
Column(Modifier.padding(4.dp)) {
Text(
stringResource(itemData.getIndicatorTittle()),
modifier = Modifier
.align(Alignment.CenterHorizontally),
style = MaterialTheme.typography.overline,
)
Spacer(modifier = Modifier.defaultMinSize())
Text(
text = itemData.parameterValue,
modifier = Modifier,
style = MaterialTheme.typography.subtitle1
)
Text(
stringResource(itemData.getIndicatorDimensionName()),
modifier = Modifier.align(Alignment.End),
style = MaterialTheme.typography.overline
)
}
}
}
}
我的物品状态class:
data class ParameterItemState(
val parameterValue: String = "12 345",
val parameterDimension: IndicatorsEnum = IndicatorsEnum.DISTANCE_IN_METERS,
val itemVisibility: Int = View.VISIBLE,
val itemPosition: Int = 0,
) {
fun getIndicatorTittle() = parameterDimension.getIndicatorTittle() // Speed (Time per 500m) id
fun getIndicatorDimensionName() = parameterDimension.getIndicatorDimensionName() // ave per 500 m id
fun getIndicatorIcon() = parameterDimension.getIndicatorIcon() // icon id
}
我仍然没有创建视图模型的东西,我也会接受包含它的答案。
看起来很简单
@Composable
fun Test(){
Scaffold(Modifier.fillMaxSize()) {
Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(8.dp)) {
BoxWithConstraints(Modifier.weight(1f)) {
Column(
Modifier.padding(8.dp).fillMaxSize(), verticalArrangement = Arrangement.spacedBy(8.dp)
) {
val height = (this@BoxWithConstraints.maxHeight - 32.dp) / 3
Item(height)
Item(height)
Item(height)
}
}
LazyRow(contentPadding = PaddingValues(horizontal = 8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)){
items(5) { index ->
Box(
Modifier
.size(56.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color.Yellow, RoundedCornerShape(8.dp)))
}
}
Box(
Modifier
.fillMaxSize()
.weight(1f)
.background(Color.Blue)) {
}
}
}
}
@Composable
fun Item(maxHeight: Dp){
Row(
Modifier
.fillMaxWidth()
.height(maxHeight),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Box(
Modifier
.fillMaxSize()
.weight(1f)
.background(Color.Red, RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
)
Box(
Modifier
.fillMaxSize()
.weight(2f)
.background(Color.Red, RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
)
Box(
Modifier
.fillMaxSize()
.weight(1f)
.background(Color.Red, RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
)
}
}