1

My screen is divided into 3 main parts, currently (I guess that probably there is a better approach):

enter image description hereenter image description here

  1. First part is showing data. It's divided into 9 almost identical items which to show different live(regular changing data). They are now in 3 rows and 3 columns(I guess that probably there is a better approach).

enter image description hereenter image description here

  1. Below them, I have internal for the Screen tab navigation, which will control whose fragment will be shown on the last part of the screen.

  2. In the bottom part of the screen I guess i need fragmentFrame(I will research for it's equivalent in Jetpack Compose), with more frequently changed data(data shown in graphs, maps , etc). Each Fragment is shown when specific tab is selected on part 2) of the screen.

Here is my code for creating the screen:

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

    }
}
  • Also i have problems in creating singe Item from 1st part of the screen to be in desirable size (I want to have 3 Items per Column in this proportion 1:2:1)

enter image description here

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

And my item state 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
}

I still didn't create viewmodel stuff, and i will accept answers including it too.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
Red Coder
  • 107
  • 1
  • 8
  • 1
    At first I've same feelings about building UI's with Jetpack Compose. But it gets easier and easier with more and more coding. What helped me a lot was speed coding or more explained videos of building such layouts. There's much about it on YouTube, In my opinion Philip Lackner has quite good videos showing him building certain things in Compose. His Clean Architecture playlist explains good how to connect UI and data related stuff. I hope this would help ;) – amtrax Dec 19 '21 at 17:48
  • @amtrax thank you for the advice :) I will take a look at him. Also, can I ask you one short question? What about experiment stuff, I was searching for more info about it. I am a bit confused. does I can use it, or try to avoid it. What do you do? – Red Coder Dec 19 '21 at 17:58
  • I'm not authority in this topic since my experience in field negligible. A large part of Compose is annotated as experimental, it's still very new. For amateur projects I guess there's nothing bad in using it. – amtrax Dec 19 '21 at 18:10

1 Answers1

1

Look so simple.

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

enter image description here

alekseyHunter
  • 371
  • 3
  • 11