Search code examples
androidandroid-studiokotlinandroid-jetpack-composeandroid-compose-textfield

Jetpack Compose: Textfield and FAB not using full width


I am trying to put a TextField and a FAB inside a bottomBar using Jetpack Compose. I wrapped the two with a box, which has the modifier "fillMaxWidth".

But the two controls dont use the full width.

Does anyone know, how to fix this issue?

Here is my Code:

    @Composable
    fun ChatView() {
        Scaffold(
            topBar= { ChannelButton() },
            bottomBar = { ChatBox() },
            modifier = Modifier
                .padding(10.dp)
        ) {
            ChatList()
        }
    }
@Composable
fun ChatBox() {
    Box(modifier = Modifier
        .background(DiscordDarkGray)
        .fillMaxWidth()
    ){
        Column(modifier = Modifier
            .padding(10.dp)
            .fillMaxWidth()) {
            HorizontalCenteredRow(modifier = Modifier
                .fillMaxWidth()) {
                val textState = remember { mutableStateOf(TextFieldValue()) }
                TextField(
                    value = textState.value,
                    onValueChange = { textState.value = it }
                )
                Spacer(modifier = Modifier.width(10.dp))
                FloatingIconActionButton (
                    icon = Icons.Default.Send,
                    onClick = { /*TODO*/ },
                    backgroundColor = DiscordBlue
                )
            }
            Spacer(modifier = Modifier.height(60.dp))
        }
    }
}

enter image description here

Here is the Code of the HorizontalCenteredRow:

@Composable
fun HorizontalCenteredRow(
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        modifier = modifier
            .wrapContentSize(Alignment.Center),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center,
        content = content
    )
}

Here is the code of the FAB:

@Composable
fun FloatingIconActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
    backgroundColor: Color = MaterialTheme.colors.secondary,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    icon: ImageVector = Icons.Default.QuestionAnswer,
    iconContentDescription: String = "",
) {
    Surface(
        modifier = modifier.let {
            if (enabled) {
                it.clickable(
                    onClick = onClick,
                    role = Role.Button,
                    interactionSource = interactionSource,
                    indication = null
                )
            } else it
        },
        shape = shape,
        color = backgroundColor,
        contentColor = contentColor,
        elevation = elevation.elevation(interactionSource).value
    ) {
        CompositionLocalProvider(LocalContentAlpha provides contentColor.alpha) {
            ProvideTextStyle(MaterialTheme.typography.button) {
                Box(
                    modifier = Modifier
                        .defaultMinSize(minWidth = FabSize, minHeight = FabSize)
                        .indication(interactionSource, rememberRipple()),
                    contentAlignment = Alignment.Center
                ) {
                    Icon(
                        icon,
                        iconContentDescription,
                        tint = if (enabled) {
                            colors().onPrimary
                        } else {
                            colors().onPrimary.transparentize(.6f)
                        }
                    )
                }
            }
        }
    }
}

Solution

  • Using

       HorizontalCenteredRow(
              modifier = Modifier.fillMaxWidth()
    

    the Row fills all the space, but it doesn't mean that the children occupy the entire space.
    If you want to fill all the space with the children you have to change the default dimensions of them.
    For example you can apply modifier = Modifier.weight(1f) to the TextField.

    Something like:

            HorizontalCenteredRow(modifier = Modifier
                .fillMaxWidth()) {
                val textState = remember { mutableStateOf(TextFieldValue()) }
                TextField(
                    value = textState.value,
                    onValueChange = { textState.value = it },
                    modifier = Modifier.weight(1f)
                )
    

    enter image description here