skip to Main Content

I’m trying to complete a codelab for Jetpack Compose Basics, and there’s a challenge for which they don’t provide the code solution, and I’m stumped. I have read countless other StackOverflow posts and blogs (and official docs) about how to potentially use Spacer, or horizontalAlignment, or the .weight modifier, and no matter what I do, I can either get everything centered (but no left align), or everything left aligned at the left edge of the screen, but not centered. I did come up with a solution using a combo of Spacers + .weight modifier that gave me what I want, but it doesn’t scale to different screen sizes. This seems like it should be WAY easier than it is, so I assume I’m doing something wrong.

Here’s what I am trying to build:
Contact Card - Centered in UI, with Left Justification within

And here is the code that gets me "everything centered":

@Composable
fun ContactInfo(phone_text: String, social_text: String, email_text: String, modifier: Modifier = Modifier){
    val image = painterResource(R.drawable.android_logo)
    Column (
        modifier = modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    )
    {
        Row (
        ){
            Icon(
                Icons.Filled.Phone,
                contentDescription = stringResource(id = R.string.phone_android_content_desc),
                tint = Color(0xff056c3a),
                modifier = modifier
                    .padding(end=16.dp)
            )
            Text(
                text = phone_text,
                fontSize = 12.sp
            )
        }
        Row (
        ) {
            Icon(
                Icons.Filled.Share,
                contentDescription = stringResource(id = R.string.phone_android_content_desc),
                tint = Color(0xff056c3a),
                modifier = modifier
                    .padding(end=16.dp)
            )
            Text(
                text = social_text,
                fontSize = 12.sp,
            )
        }
        Row (
        ) {
            Icon(
                Icons.Filled.Email,
                contentDescription = stringResource(id = R.string.phone_android_content_desc),
                tint = Color(0xff056c3a),
                modifier = modifier
                    .padding(end=16.dp)
            )
            Text(
                text = email_text,
                fontSize = 12.sp,
            )
        }

    }
}

That yields this:
Everything Centered

And here is the code using Spacers & .weight that gives me sort of what I want, but doesn’t scale to different screen sizes:

@Composable
fun ContactInfo(phone_text: String, social_text: String, email_text: String, modifier: Modifier = Modifier){
    val image = painterResource(R.drawable.android_logo)
    Column (
        modifier = modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    )
    {
        Row (
        ){
            Spacer(modifier = Modifier.weight(.5F))
            Icon(
                Icons.Filled.Phone,
                contentDescription = stringResource(id = R.string.phone_android_content_desc),
                tint = Color(0xff056c3a),
                modifier = modifier
                    .weight(.25F)
            )
            Text(
                modifier = modifier.weight(1F),
                text = phone_text,
                fontSize = 12.sp
            )
            Spacer(modifier = Modifier.weight(.5F))
        }
        Row (
        ) {
            Spacer(modifier = Modifier.weight(.5F))
            Icon(
                Icons.Filled.Share,
                contentDescription = stringResource(id = R.string.phone_android_content_desc),
                tint = Color(0xff056c3a),
                        modifier = modifier
                            .weight(.25F)
            )
            Text(
                modifier = modifier.weight(1F),
                text = social_text,
                fontSize = 12.sp,
            )
            Spacer(modifier = Modifier.weight(.5F))
        }
        Row (
        ) {
            Spacer(modifier = Modifier.weight(.5F))

            Icon(
                Icons.Filled.Email,
                contentDescription = stringResource(id = R.string.phone_android_content_desc),
                tint = Color(0xff056c3a),
                        modifier = modifier
                            .weight(.25F)
            )
            Text(
                text = email_text,
                modifier = modifier.weight(1F),
                fontSize = 12.sp,
            )
            Spacer(modifier = Modifier.weight(.5F))
        }
    }
}

That yields this:
Left Justified & Centered, but doesn't scale

2

Answers


  1. Here’s something you can try.

    Scaffold(
        bottomBar = {
            CustomBottomBar()
        }
    ) { paddingValues ->
        // your content
        Box(modifier = Modifier.padding(paddingValues))
    }
    

    Views

    @Composable
    fun CustomBottomBar() {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(300.dp)
                .background(
                    color = Color(210, 232, 213)
                ),
            contentAlignment = Alignment.Center
        ) {
            Box(
                modifier = Modifier
                    .wrapContentSize()
                    .padding(top = 80.dp)
    
            ) {
                Column(
                    verticalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    InfoRow(
                        text = "+11 (123) 444 555 666",
                        icon = Icons.Default.Phone
                    )
                    InfoRow(
                        text = "@AndroidDev",
                        icon = Icons.Default.Share
                    )
                    InfoRow(
                        text = "[email protected]",
                        icon = Icons.Default.Email
                    )
                }
            }
        }
    }
    
    
    @Composable
    fun InfoRow(text: String, icon: ImageVector) {
        Row(
            modifier = Modifier
                .wrapContentWidth()
                .padding(8.dp)
        ) {
            Icon(
                imageVector = icon,
                contentDescription = null,
                tint = Color(1, 109, 59)
            )
    
            Spacer(modifier = Modifier.width(25.dp))
    
            Text(text = text)
        }
    }
    

    Output

    Login or Signup to reply.
  2. You have to just wrap all Rows within a Column.

    Example:

    @Composable
    fun ContactInfo(
        // ...
        modifier: Modifier = Modifier
    ) {
        Column (
            modifier = modifier.fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Column {
                Row {
                    Icon(imageVector = Icons.Filled.Phone, contentDescription = "")
                    Spacer(modifier = Modifier.width(16.dp))
                    Text(text = "+11 (123) 444 555 666")
                }
                Row {
                    Icon(imageVector = Icons.Filled.Share, contentDescription = "")
                    Spacer(modifier = Modifier.width(16.dp))
                    Text(text = "@AndroidDev")
                }
                Row {
                    Icon(imageVector = Icons.Filled.Email, contentDescription = "")
                    Spacer(modifier = Modifier.width(16.dp))
                    Text(text = "[email protected]")
                }
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search