底部导航栏与 Jetpack Compose 中的屏幕内容重叠

问题描述 投票:0回答:7

我有一个

BottomNavBar
,它在
bottomBar
Scaffold
内部被称为。
每个屏幕都包含一个
LazyColumn
,它显示一堆图像。
由于某种原因,当我完成滚动时,
BottomNavBar
与项目列表的下部重叠。
我该如何解决这个问题?

这里是MainActivity的设置内容

SetContent{
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(text = "tartufozon") },
                actions = {
                    IconButton(onClick = { Timber.d("Mail clicked") }) {
                        Icon(Icons.Default.Email, contentDescription = null)
                    }
                }
            )
        },
        bottomBar = {
            BottomNavBar(navController = navController)
        }
    ) {
    BottomNavScreensController(navController = navController)
    }
}
android android-jetpack android-jetpack-compose
7个回答
163
投票

根据 ScaffoldAPI 定义,您的内部内容(您的

BottomNavScreensController
所在的尾部 lambda)被赋予一个
PaddingValues
对象,该对象为您的顶部应用栏提供适量的填充,底栏等

现在,您根本没有引用该填充,因此,您的内容没有被填充。这就是导致重叠的原因。

您可以在

Box
周围添加
BottomNavScreensController
来应用填充,或者将填充直接传递到
BottomNavScreensController
中,以便每个单独的屏幕都可以正确应用填充;任一解决方案都有效。

Scaffold(
    topBar = {
      //
    },
    bottomBar = {
        //
    }
    ) { innerPadding ->
        // Apply the padding globally to the whole BottomNavScreensController
        Box(modifier = Modifier.padding(innerPadding)) {
            BottomNavScreensController(navController = navController)
        }
    }
}

13
投票

遵循 ianhanniballake 的回答及其评论,只是为了节省您几分钟的时间。代码类似于:

Scaffold(
    topBar = {
      //
    },
    bottomBar = {
        //
    }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(
          PaddingValues(bottom = innerPadding.calculateBottomPadding()) {
            BottomNavScreensController(navController = navController)
        }
    }
}

8
投票

您不再需要进行任何计算。在脚手架内容中,执行以下操作:

content = { padding ->
  Column(
    modifier = Modifier.padding(padding)
  ) {...

7
投票
Scaffold(
    bottomBar = {
       BottomNavigationBar(navController = navController)
   }
) { innerPadding ->
      Box(modifier = Modifier.padding(innerPadding)) {
               DestinationsNavHost(
                  navGraph = NavGraphs.root,
                  navController = navController,
                  engine = navHostEngine
                )
         }
}

1
投票

在内容中添加布局和视图及其填充,如示例所示:

Scaffold(
        content = {
            Box(modifier = Modifier.padding(it)) {
                //add your layout here
            }

        },
        topBar = { 
                 //your top bar
        },
        floatingActionButton = {
           //your floating action bar
        },
        bottomBar = {
            //your bottom navigation
        }
    )

0
投票

通过打开一个 Box 并给出我在其中写入的 paddingValues 值来解决问题。

Scaffold(
            bottomBar = {
                BottomBar(navController = navController, bottomBarState = bottomBarState)
            },
            content = {paddingValues->
                Box(modifier = Modifier.padding(paddingValues)){
                    SetupNavGraph(navHostController = navController)
                }
            })
    }

-1
投票

以下 ianhanniballake 答案,如果您的主屏幕中有一个列表并且想要显示/隐藏底部栏。当您返回列表屏幕(滚动状态位于最底部)并显示导航栏时,它会执行意外的行为。列表项会向上滚动一点,导致列表没有完全滚动到底部。

这是因为当您返回列表屏幕并想要显示底部栏时,列表已经存在。然后底部栏将显示,并且列表将不再计算innerPadding。

要处理这个问题,只需将innerPadding传递到列表屏幕中,如下所示:

            Scaffold(
                bottomBar = {
                BottomNavBar(navController)
            }) { innerPadding ->
            NavHost(
                navController = navController,
                startDestination = MovieListDirections.destination
            ) {
                MovieListDirections.screenWithPaddingBottomBar(
                    this,
                    innerPadding.calculateBottomPadding() // pass here
                )
            }

然后在列表屏幕中

@Composable
fun MovieListMainView(viewModel: MovieListViewModel = hiltViewModel(),
                  bottomBarHeight: Float) {
    val movieList by viewModel.movieList.collectAsState()
    var navBarHeight by rememberSaveable { mutableStateOf(0f) }

    if (bottomBarHeight != 0f) {
        navBarHeight = bottomBarHeight
    }

    MovieListLayout().MovieGridLayout(
        modifier = Modifier.padding(0.dp, 0.dp, 0.dp, navBarHeight.dp),
        movies = movieList.movieList.movieItems,
        onItemClick = {
            viewModel.onMovieClicked(it)
        })
}
© www.soinside.com 2019 - 2024. All rights reserved.