androidandroid-jetpack-composeandroid-jetpack-compose-listandroid-jetpack-compose-lazy-column

Push a LazyColumn item to end of screen if the LazyColumn is empty


I want to add a footer to LazyColumn that only appears when all the items are scrolled, but if there are no items in the LazyColumn or no enough items to cover the whole screen, I want the footer to show at the bottom of the screen.

Since we cannot set weights in LazyColumn is there any other way to achieve this?


Solution

  • You can use the LazyListState#layoutInfo to know if the list is empty or if there is available space at the bottom.

    val state = rememberLazyListState()
    
    val isIniatialLoading by remember {
        derivedStateOf {
            state.layoutInfo.viewportSize  == IntSize.Zero
        }
    }
    
    //Empty list or empty space
    val hasEmptySpace by remember {
        derivedStateOf {
            val layoutInfo = state.layoutInfo
            val visibleItemsInfo = layoutInfo.visibleItemsInfo
            if (layoutInfo.totalItemsCount == 0) {
                true
            } else {
                val lastVisibleItem = visibleItemsInfo.last()
                val viewportHeight = layoutInfo.viewportEndOffset + layoutInfo.viewportStartOffset
                
                (lastVisibleItem.index + 1 == layoutInfo.totalItemsCount &&
                        lastVisibleItem.offset + lastVisibleItem.size < viewportHeight)
            }
        }
    }
    

    Then wrap the LazyColumn with a Column and apply the weight modifier to the list.

    Column(Modifier.fillMaxSize()) {
    
        LazyColumn(
            state = state,
            modifier = Modifier.weight(1f)
        ){
            items(itemsList) {
               //....
            }
    
            //Footer when the list covers the entire screen
            if (!hasEmptySpace){
                item(){
                    //Footer()
                }
            }
        }
        
        // Display the Footer at the bottom of the screen if the list is empty or if there is an empty space
        if ( !isIniatialLoading && hasEmptySpace ){
           //Footer()
        }
    
    }
    

    enter image description here