Android Jetpack Compose Grid 外观视图

Posted

技术标签:

【中文标题】Android Jetpack Compose Grid 外观视图【英文标题】:Android Jetpack Compose Grid looking view 【发布时间】:2022-01-21 13:40:06 【问题描述】:

我的屏幕目前分为3个主要部分(我想可能有更好的方法):

    第一部分显示数据。它分为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
                )
            
        
    

还有我的物品状态类:

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

我仍然没有创建视图模型的东西,我也会接受包括它在内的答案。

【问题讨论】:

起初我对使用 Jetpack Compose 构建 UI 有同样的感受。但是随着越来越多的编码,它变得越来越容易。对我帮助很大的是速度编码或构建此类布局的更多解释视频。 YouTube 上有很多关于它的内容,在我看来,Philip Lackner 有相当不错的视频,展示了他在 Compose 中构建某些东西。他的 Clean Architecture 播放列表很好地解释了如何连接 UI 和数据相关的东西。我希望这会有所帮助;) @amtrax 谢谢你的建议 :) 我会看看他。另外,我能问你一个简短的问题吗?实验的东西怎么样,我正在寻找有关它的更多信息。我有点困惑。我可以使用它,还是尽量避免它。你是做什么的? 我不是这个主题的权威,因为我在该领域的经验可以忽略不计。 Compose 的很大一部分被注释为实验性的,它仍然很新。对于业余项目,我想使用它没有什么不好的。 【参考方案1】:

看起来很简单。

@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))
        )
    

【讨论】:

感谢您的完整回答。这对我帮助很大。

以上是关于Android Jetpack Compose Grid 外观视图的主要内容,如果未能解决你的问题,请参考以下文章