如何向屏幕添加滑动行为?

How to add swipe behavior to the screens?

我们的应用程序中有底部导航,我们想在我们的屏幕中添加滑动行为,这样如果用户滑动到 right/left,那么 s/he 应该导航到下一个屏幕。

我知道 AccompanistHorizontalPager 带标签。但我想知道我们是否可以通过底部导航实现这种行为。

如您在 Material Design Guidelines 中所见:

Using swipe gestures on the content area does not navigate between views.

还有:

Avoid using lateral motion to transition between views.

但是,如果你真的想这样做,你可以这样做:

fun BottomNavSwipeScreen() {
    // This scope is necessary to change the tab using animation
    val scope = rememberCoroutineScope()
    // I'm using a list of images here
    val images = listOf(R.drawable.img1, ...) 
    // This page state will be used by BottomAppbar and HorizontalPager
    val pageState = rememberPagerState(pageCount = images.size)
    val scaffoldState = rememberScaffoldState() 
    Scaffold(
        scaffoldState = scaffoldState,
        bottomBar = {
            BottomAppBar(
                backgroundColor = MaterialTheme.colors.primary,
                content = {
                    for (page in images.indices) {
                        BottomNavigationItem(
                            icon = { 
                                Icon(Icons.Filled.Home, "Page $page") 
                            },
                            // here's the trick. the selected tab is based
                            // on HorizontalPager state.
                            selected = page == pageState.currentPage,
                            onClick = {
                                // When a tab is selected, 
                                // the page is updated
                                scope.launch {
                                    pageState.animateScrollToPage(page)
                                }
                            },
                            selectedContentColor = Color.Magenta,
                            unselectedContentColor = Color.LightGray,
                            label = { Text(text = "Page $page") }
                        )
                    }
                }
            )
        },
    ) {
        HorizontalPager(
            state = pageState,
            offscreenLimit = 2
        ) { page ->
            Image(
                painterResource(id = images[page]),
                null,
                modifier = Modifier
                    .fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        }
    }
}

结果如下:

您可以使用 compose 中的动画库实现此目的: https://developer.android.com/jetpack/compose/animation

并且使用slideIntoContainer动画可以模拟滑动效果:

 composable("route1",
        enterTransition = {
            slideIntoContainer(
                towards = AnimatedContentScope.SlideDirection.Right,
                animationSpec = tween(
                    durationMillis = 250,
                    easing = LinearEasing // interpolator
                )
            )
        },
        exitTransition = {
            slideOutOfContainer(
                towards = AnimatedContentScope.SlideDirection.Left,
                animationSpec = tween(
                    durationMillis = 250,
                    easing = LinearEasing
                )
            )
        }) {
        Screen1()
    }
    composable("route2",
        enterTransition = {
            slideIntoContainer(
                towards = AnimatedContentScope.SlideDirection.Left,
                animationSpec = tween(
                    durationMillis = 250,
                    easing = LinearEasing // interpolator
                )
            )
        },
        exitTransition = {
            slideOutOfContainer(
                towards = AnimatedContentScope.SlideDirection.Right,
                animationSpec = tween(
                    durationMillis = 250,
                    easing = LinearEasing
                )
            )
        }) {
        Screen2()
    }