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 外观视图的主要内容,如果未能解决你的问题,请参考以下文章

Android Jetpack Compose学习—— Jetpack compose基础布局

Android Jetpack Compose学习—— Jetpack compose基础布局

Android Jetpack Compose学习—— Jetpack compose入门

Android Jetpack Compose学习—— Jetpack compose入门

Android Kotlin Jetpack Compose 使用

Jetpack Compose 和 Compose Navigation 如何处理 Android 活动?