Home > Blockchain >  How to equally spaced textfields in row using jetpack compose?
How to equally spaced textfields in row using jetpack compose?

Time:11-23

Here is my code

@Composable
fun OtpTextField() {
    TextField(
        maxLines = 1,
        singleLine = true,
        value = "1",
        onValueChange = {},
        modifier = Modifier
            .background(
                color = MaterialTheme.colors.surface,
                shape = RoundedCornerShape(
                    5.dp
                ),
            )
            .padding(start = 2.dp, end = 2.dp, top = 4.dp)
            .width(IntrinsicSize.Max),
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Number,
        ),
        textStyle = TextStyle(
            color = MaterialTheme.colors.secondary,
            fontFamily = FontFamily(Font(R.font.poppins_semibold)),
            fontSize = 32.sp, textAlign = TextAlign.Center
        ),
    )
}

=============================

Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.SpaceEvenly,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        OtpTextField()
//                        Spacer(modifier = Modifier.width(10.dp))
                        OtpTextField()
//                        Spacer(modifier = Modifier.width(10.dp))
                        OtpTextField()
//                        Spacer(modifier = Modifier.width(10.dp))
                        OtpTextField()
//                        Spacer(modifier = Modifier.width(10.dp))
                        OtpTextField()
                    }

The problem is the first textfield occupies the whole width. I can't assign a hardcoded width to textfield as it won't work on other mobile devices. I also tried assigning fullMaxWidth to textfield but same issue happens

CodePudding user response:

I believe that you need to need to set the width of each TextField to a fixed value but this value should be calculated based on the parent container's width that you want it to fit in. It isn't likely that you will fit it to the entire screen width. On a phone in portrait mode, this would be okay but not in landscape mode. For this reason, you should limit the parent container to a maximum width. For the example code shown here, I limit the total width to 500.dp:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var containerWidth = LocalConfiguration.current.screenWidthDp.dp

            if (containerWidth > 500.dp) {
                containerWidth = 500.dp
            }

            val textEditWidth = containerWidth / 8f

            Row(
                modifier = Modifier.requiredWidth(containerWidth).background(color = Color.Red),
                horizontalArrangement = Arrangement.SpaceEvenly,
                verticalAlignment = Alignment.CenterVertically
            ) {
                OtpTextField(width = textEditWidth)
                OtpTextField(width = textEditWidth)
                OtpTextField(width = textEditWidth)
                OtpTextField(width = textEditWidth)
                OtpTextField(width = textEditWidth)
                OtpTextField(width = textEditWidth)
            }
        }
    }
}

@Composable
fun OtpTextField(
    width: Dp
) {
    TextField(
        maxLines = 1,
        singleLine = true,
        value = "1",
        onValueChange = {},
        modifier = Modifier
            .requiredWidth(width)
            .background(
                color = MaterialTheme.colors.surface,
                shape = RoundedCornerShape(
                    5.dp
                ),
            )
            .padding(start = 2.dp, end = 2.dp, top = 4.dp),
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Number,
        ),
        textStyle = TextStyle(
            color = MaterialTheme.colors.secondary,
            fontSize = 32.sp, textAlign = TextAlign.Center
        ),
    )
}

CodePudding user response:

Though Johann answer is correct, I found an easy way of calculating device width and then divided it by 8 and passed that width to each textfield to occupy equal widths

LocalConfiguration.current.screenWidthDp.dp / 8f
  • Related