Home > Software design >  Jetpack Compose Floating Action Button is not showing up
Jetpack Compose Floating Action Button is not showing up

Time:03-14

I have a bottom sheet dialog. For the dialog, I'm using ModalBottomSheetDialog from the Accompanist navigation library. In the dialog which is a composable fun that named PlatformsScreen, I have a LazyColumn with items that has RadioButton. Whenever any of the radio buttons is selected I'm adding the selected item into the selectedPlatforms which is a mutableList:

@Composable
fun PlatformsScreen(
    modifier: Modifier = Modifier,
    navController: NavController,
    viewModel: PlatformsScreenViewModel = hiltViewModel(),
) {
    // this is the platforms that I fetch from network
    val platforms = viewModel.platforms.observeAsState()

    val listState = rememberLazyListState()

    //this is the platforms that I selected from the platforms list
    val selectedPlatforms by rememberSaveable {
        mutableStateOf(mutableListOf<Platform>())
    }
    
    DefaultScreenUI(toolbar = {
        BottomSheetDialogToolbar(title = "Platforms")
    },
        floatingActionButton = {
            //This is not working
            AnimatedVisibility(visible = selectedPlatforms.size > 0,
                enter = expandVertically(),
                exit = shrinkVertically())
            {
                ApplyFilterFab()
            }
        }
    ) {

        when (platforms.value) {
            is Resource.Loading -> {
                LoadingItem()
            }
            is Resource.Error -> {
                ErrorItem(message = platforms.value!!.error!!,
                    onRetryClick = viewModel::setRefresh)
            }
            is Resource.Success -> {
                if (platforms.value!!.data!!.isNotEmpty()) {
                    LazyColumn(modifier = modifier.fillMaxSize(), state = listState) {
                        items(count = platforms.value!!.data!!.size) {
                            //platform item
                            PlatformItem(
                                platform = platforms.value!!.data!![it],
                            ) { platform, selected ->
                                Timber.d(selectedPlatforms.size.toString())
                                if (!selected) {
                                    selectedPlatforms.remove(platform)
                                } else {
                                    selectedPlatforms.add(platform)
                                }
                            }
                        }
                    }
                } else {
                    //empty view
                }
            }

        }
}
}

The DefaultScreenUI is also a composable fun with Scaffold :

@Composable
fun DefaultScreenUI(
    toolbar: (@Composable () -> Unit)? = null,
    floatingActionButton: (@Composable () -> Unit)? = null,
    fabPos: FabPosition = FabPosition.End,
    content: @Composable () -> Unit,
) {
    val scaffoldState = rememberScaffoldState()
    Scaffold(
        scaffoldState = scaffoldState,
        topBar = { toolbar?.invoke() },
        floatingActionButton = { floatingActionButton?.invoke() },
        floatingActionButtonPosition = fabPos) {
        Box(modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colors.primary)) {
            content()
        }
    }
}

Here is also my PlatformItem composable:


@Composable
fun PlatformItem(
    modifier: Modifier = Modifier,
    platform: Platform,
    onItemSelected: (Platform,Boolean) -> Unit
) {
    var selected by rememberSaveable {
        mutableStateOf(false)
    }

    Row(modifier = modifier
        .fillMaxWidth()
        .height(40.dp)
        .clickable {
            selected = !selected
            onItemSelected(platform,selected)
        },
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {

        Text(
            modifier = Modifier.padding(start = dimensionResource(id = R.dimen.dimen_8)),
            text = platform.name!!,
            style = MaterialTheme.typography.subtitle1,
            color = MaterialTheme.colors.onPrimary)

        RadioButton(selected = selected, onClick = {
            selected = !selected
            onItemSelected(platform,selected)
        })

    }
}

What I'm trying to do is whenever any of the items in the list has selected which means selectedPlatforms.size > 0 I want to show the FloatingActionButton in the dialog and hide the button if selectedPlatforms is empty. Here is the result:

As you can see it is not showing up. What should I do?

CodePudding user response:

It's a bug and I've reported it.

Until it's fixed, the easiest solution at the moment is to switch to scaleIn / scaleOut transitions, they work fine.

An other option is putting AnimatedVisibility is a Box of FAB static size, which is 56.dp, in this case other transitions work fine, except the clipped shadow. The shadow can be disabled by zeroing the elevation parameter, which is not the best solution either.

  • Related