Row composable not taking up the full width of parent

736 Views Asked by At

I have a shopping list item composable that is not taking up the entire width of the parent, as you can see below with the red border. I want it to be flush against the parent's edge. And why is there some space or padding just before the checkbox? What needs to be modified?

enter image description here

Composable

@Composable
fun ShoppingListScreenItem(
    itemName: String,
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth().border(2.dp, Red),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Checkbox(
            modifier = Modifier.padding(0.dp),
            checked = checked,
            onCheckedChange = onCheckedChange
        )
        Text(
            modifier = Modifier.padding(start = 8.dp),
            fontWeight = FontWeight.Bold,
            text = itemName
        )
    }
}

Parent Composable

@Composable
fun ShoppingListScreen(
    navController: NavHostController,
    shoppingListScreenViewModel: ShoppingListScreenViewModel
) {
    val scope = rememberCoroutineScope()
    val name = stringResource(id = R.string.item_name)
    val nameError = stringResource(id = R.string.item_IsNameError)
    val category = stringResource(id = R.string.item_category)
    val categoryError = stringResource(id = R.string.item_IsCategoryError)

    val focusManager = LocalFocusManager.current
    val allItems =
        shoppingListScreenViewModel.shoppingListItemsState.value?.collectAsLazyPagingItems()

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(text = "AppBar") },
                backgroundColor = Color.White,
                navigationIcon = if (navController.previousBackStackEntry != null) {
                    {
                        IconButton(onClick = { navController.navigateUp() }) {
                            Icon(
                                imageVector = Icons.Filled.ArrowBack,
                                contentDescription = "Back"
                            )
                        }
                    }
                } else {
                    null
                }
            )
        },
        floatingActionButton = {
            FloatingActionButton(
                onClick = {
                    shoppingListScreenViewModel.setStateValue("ShowAddItemDialog", true)
                },
                backgroundColor = Color.Blue,
                contentColor = Color.White
            ) {
                Icon(Icons.Filled.Add, "")
            }
        },
        // Defaults to false
        isFloatingActionButtonDocked = false,
        bottomBar = { BottomNavigationBar(navController = navController) }
    ) {
        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            LazyColumn(
                contentPadding = PaddingValues(
                    vertical = 8.dp,
                    horizontal = 8.dp
                )
            ) {
                //todo change it to non null
                items(allItems!!) { item ->
                    ShoppingListScreenItem(
                        itemName = item?.name!!,
                        checked = item.isInCart
                    ) { isChecked ->
                        scope.launch {
                            shoppingListScreenViewModel.changeItemChecked(item, isChecked)
                        }
                    }
                }
            }

            if (shoppingListScreenViewModel.shoppingListScreenState.value.showAddItemDialog) {
                OnTheFlyAddItemDialog(
                    shoppingListScreenViewModel = shoppingListScreenViewModel,
                    focusManager = focusManager,
                    navController = navController,
                    onDismiss = {
                        shoppingListScreenViewModel.setStateValue(name, "")
                        shoppingListScreenViewModel.setStateValue(nameError, false)
                        shoppingListScreenViewModel.setStateValue(category, "")
                        shoppingListScreenViewModel.setStateValue(categoryError, false)
                        shoppingListScreenViewModel.setStateValue("ShowAddItemDialog", false)
                    }
                )
                {
                    scope.launch {
                        shoppingListScreenViewModel.addShoppingListItemToDb()
                        shoppingListScreenViewModel.setStateValue("ShowAddItemDialog", false)
                        shoppingListScreenViewModel.setStateValue(name, "")
                        shoppingListScreenViewModel.setStateValue(nameError, false)
                        shoppingListScreenViewModel.setStateValue(category, "")
                        shoppingListScreenViewModel.setStateValue(categoryError, false)
                        // triggerCount++
                    }
                }
            }

            Button(
                modifier = Modifier.padding(vertical = 24.dp),
                onClick = {
                    navController.navigate(NavScreens.AddItemScreen.route) {
                        popUpTo(NavScreens.AddItemScreen.route) {
                            inclusive = true
                        }
                    }
                }
            ) {
                Text("Goto add item screen")
            }
        }
    }
}
2

There are 2 best solutions below

0
On

You set a contentPadding in your LazyColumn that is responsible for the spaces. Remove it, or set it to zero.

LazyColumn(
    contentPadding = PaddingValues(
        vertical = 8.dp,
        horizontal = 0.dp
    )
)
1
On

The padding around the Checkbox depends on the minimumTouchTargetSize defined when the onClick is not null with a hardcoded value of 48.dp.

You can override it using:

    CompositionLocalProvider(
        LocalMinimumTouchTargetEnforcement provides false,
    ) {
        Checkbox(
            modifier = Modifier.padding(0.dp),  //4.dp 
            checked = false,
            onCheckedChange = {}
        )
    }

but it is not the best choice in term of accessibility.

enter image description here. enter image description here

The space around the Row depends on the contentPadding defined in the LazyColumn.