标签: android-jetpack-navigation

我们可以使用带有设置首选项的 Android Jetpack 导航组件吗?

是否可以使用 Android Jetpack 导航组件来导航设置首选项的片段?我有一个带有多个嵌套首选项片段的设置屏幕。我想知道使用 Android Jetpack 导航组件来简化我的任务是否可行?

android android-preferences kotlin android-jetpack-navigation

11
推荐指数
1
解决办法
1522
查看次数

防止导航到同一片段

我正在使用带有BottomNavigationView 的Android 导航jetpack 库。我已经实现了 NavHost、NavGraph 和我的片段。当我使用操作进行导航时,一切都按预期工作。

我使用以下代码来设置一切:

 val navController = Navigation.findNavController(this, R.id.nav_host)
 bottom_navigation.setupWithNavController(navController)
Run Code Online (Sandbox Code Playgroud)

问题是,如果我单击选项卡 2 次,则片段会重新创建两次。有没有办法拦截导航?我不想导航到正在显示的同一个片段。

android kotlin android-jetpack android-jetpack-navigation

11
推荐指数
1
解决办法
4073
查看次数

使用导航组件将参数安全地传递给嵌套图

我正在使用 Android Jetpack 导航组件。我有一个带有 id 的嵌套导航图,比如说嵌套图R.id.nested_graph 的第一个Fragment接收一个参数。

<navigation
        android:id="@+id/nested_graph"
        android:label="Nested Graph"
        app:startDestination="@id/firstFragment">
        <fragment
            android:id="@+id/firstFragment"
            android:name="...."
            android:label="....">
            <argument
                android:name="item_id"
                app:argType="integer" />
        </fragment>
        [...]
    </navigation>
Run Code Online (Sandbox Code Playgroud)

如何使用安全 args将参数传递给嵌套图?

目前,我需要在包中手动传递参数,使用直接接收嵌套图的 id 的 API:

        val args = Bundle()
        args.putInt("item_id", itemId)
        navController.navigate(R.id.nested_graph, args)
Run Code Online (Sandbox Code Playgroud)

我想使用安全参数,并执行以下操作:

        val directions = OrigininFragmentDirections.nestedGraph(itemId)
        navController.navigate(directions)
Run Code Online (Sandbox Code Playgroud)

但是在尝试时,我在构建时收到以下错误:

Too many arguments for public final fun nestedGraph(): NavDirections defined 
Run Code Online (Sandbox Code Playgroud)

问题是导航图预处理正在生成工厂方法来创建没有签名中所需参数的NavDirections对象。

嵌套图的声明如下所示:

android android-navigation android-jetpack-navigation android-navigation-graph

11
推荐指数
2
解决办法
3654
查看次数

使用 Paging 3 时保存并保留 LazyColumn 滚动位置

我在我的活动中使用 Paging 3 Library with Lazy Column 和 BottomNavigation Menu。附加到 BottomNavMenu 的每个可组合屏幕都使用一个可组合,而后者又使用惰性列。当我使用 compose 导航库在可组合物之间导航时,我希望重新组合的可组合物保留滚动位置和 lazyListState

我尝试了以下但不起作用:

val listState = rememberLazyListState()
val scrollState = rememberScrollState()

LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .padding(bottom = 56.dp)
            .scrollable(scrollState, Orientation.Vertical),
        state = listState,
    ) {

//draw the items and hook the loadState to the lazy paging items
Run Code Online (Sandbox Code Playgroud)

每次我导航到这个可组合时,它都会重新组合,滚动位置设置为 0,这不是我想要的。处理这个问题的正确方法是什么

kotlin android-jetpack android-jetpack-navigation android-jetpack-compose

11
推荐指数
2
解决办法
1030
查看次数

如何使用嵌套的 navGraph 和底部导航视图进行导航

我有 3 个项目的底部导航视图,我navGraph看起来像这样:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/nested_navigation"

<navigation
    android:id="@+id/nested_navigation"
    app:startDestination="@id/mainFragment" >
    <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.app.ui.main.MainFragment"
        android:label="main_fragment"
        tools:layout="@layout/main_fragment" />
    <fragment
        android:id="@+id/list"
        android:name="com.example.app.ui.main.List"
        android:label="fragment_news_list"
        tools:layout="@layout/fragment_list" />
</navigation>

<fragment
    android:id="@+id/settings"
    android:name="com.example.app.ui.main.Settings"
    android:label="Settings" />
</navigation>
Run Code Online (Sandbox Code Playgroud)

带有嵌套 navGraph 片段的底部导航视图中的导航工作正常,但是如果我导航到settings_fragment嵌套 navGraph 之外的 ,并且我单击其他项目/片段我无法导航到其他片段,我基本上卡住在这个屏幕上。

我检查了发生了什么是如果我把settings_fragment嵌套的 navGraph放在里面,它的效果很好。

我该如何解决这个问题?

顺便说一句 - 我很确定它不相关,但设置片段是PreferenceScreen位于 XML 资源中的布局,而不是布局资源

我的菜单项:

<item
    android:id="@+id/mainFragment"
    android:icon="@drawable/ic_home_black_24dp"
    android:title="@string/home"
    app:showAsAction="ifRoom"
    />
<item
    android:id="@+id/list"
    android:icon="@drawable/ic_format_list_bulleted_black_24dp"
    android:title="@string/news_list"
    app:showAsAction="ifRoom"
    />
<item
    android:id="@+id/settings"
    android:icon="@drawable/ic_settings_black_24dp"
    android:title="@string/settings"
    app:showAsAction="ifRoom"
    />
Run Code Online (Sandbox Code Playgroud)

android kotlin android-navigation bottomnavigationview android-jetpack-navigation

10
推荐指数
1
解决办法
1795
查看次数

Android 中缺少slide_in_right 和slide_out_left 动画?

我正在尝试使用 Jetpack 导航组件。这里的文档讨论了动画过渡。示例代码使用动画slide_in_right和 ,slide_out_left其行为就像它们默认存在一样 - 没有关于如何创建它们的说明。

<action
    ...
    app:enterAnim="@anim/slide_in_right"
    app:exitAnim="@anim/slide_out_left"
    app:popEnterAnim="@anim/slide_in_left"
    app:popExitAnim="@anim/slide_out_right" />
Run Code Online (Sandbox Code Playgroud)

但是,当我单击如下所示的属性时,在导航图资源的设计视图中,我只看到slide_in_leftside_out_right。为什么另外两个人不在?

我的目标是制作类似推/弹出的动画,其中新视图从右侧进入,旧视图从左侧移出。(相反,“弹出”回到导航堆栈中。)

我确实看到了一些关于这些动画的其他问题,但他们的答案很旧,而且听起来可能存在错误,所以我想知道 2020 年现在的答案是什么。

在此输入图像描述

在此输入图像描述

android android-animation android-jetpack-navigation

10
推荐指数
1
解决办法
2940
查看次数

撰写导航 - 替换起始路线并清除后退堆栈

我正在使用 JetPack Compose 和可组合 NavHost。

我有一个场景,我需要一个连接蓝牙设备的启动屏幕,因此我将其设置为 NavHost 中的起始路线。

连接完成后,我想进入主屏幕,并且永远不会返回到启动屏幕。

因此,连接完成后启动屏幕我正在这样做:

   navController.graph.setStartDestination(newHomeRoute)
   navController.navigate(newHomeRoute) {
      popUpTo(0)
      launchSingleTop = true
   }
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我不断循环返回到 LaunchScreen 并前进到 Home。

那么也许我应该以其他方式做到这一点?

android android-jetpack-navigation android-jetpack-compose

10
推荐指数
3
解决办法
6973
查看次数

在 jetpack 撰写导航中返回导航时分页 3 列表自动刷新

我正在使用 Jetpack Compose,以及 Paging 3 库和 Jetpack Navigation。我面临的问题是我有一个 LazyList,它使用分页库从远程源获取数据。

视图模型

fun getImages(): Flow<PagingData<ObjectImage>> = Pager(
        PagingConfig(PAGE_SIZE, enablePlaceholders = false)
    ) { DataHome(RANDOM) }.flow.cachedIn(viewModelScope)
Run Code Online (Sandbox Code Playgroud)

主页视图

val images = viewModelHome.getImages().collectAsLazyPagingItems()
LazyColumn {
  ...
}
Run Code Online (Sandbox Code Playgroud)

现在发生的情况是,当我使用导航到另一个视图navHostController.navigate(),然后按返回返回到 HomeView 时...LazyColumn 会重置自身并开始再次从网络加载项目。

所以我被这个问题困扰了。我尝试在 viewModel 变量中手动缓存...虽然它有效,但它搞砸了 SwipeRefresh (停止显示刷新状态)

data.apply {
            when {
                // refresh
                loadState.refresh is LoadState.Loading -> {
                    ItemLoading()
                }

                // reload
                loadState.append is LoadState.Loading -> {...}

                // refresh error
                loadState.refresh is LoadState.Error -> {...}

                // reload error
                loadState.append is LoadState.Error -> {...}
            } …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack android-paging android-jetpack-navigation android-jetpack-compose

10
推荐指数
1
解决办法
7981
查看次数

ViewModel中的SavedStateHandle和currentBackStackEntry是否相同?

我想使用 saveStateHandle 将一些数据从活动直接传递到片段的视图模型。

在我的活动中我有:

navController.addOnDestinationChangedListener { controller, _, _ ->
    controller.currentBackStackEntry?.savedStateHandle?.set(
        "foo",
         "bar"
    )
}
Run Code Online (Sandbox Code Playgroud)

所以viewModel中的代码如下所示:

MyViewModel(state: SavedStateHandle) : ViewModel() {

    init {
        state
            ?.getStateFlow("foo", "")
            ?.onEach { /* do something */ }
            ?.launchIn(viewModelScope)
    }

Run Code Online (Sandbox Code Playgroud)

由于某种原因,期望值bar永远不会被发出。

我已经检查了Fragment本身,数据就在那里:

val handle = findNavController().currentBackStackEntry?.savedStateHandle

handle?.getLiveData<String>("foo")?.observe(viewLifecycleOwner) {
    // here it is

}
Run Code Online (Sandbox Code Playgroud)

但是是否有可能将数据直接传递到 viewModel 的 savingStateHandle ?我相信应该是这样,因为导航器以某种方式通过了。

android android-savedstate android-viewmodel android-jetpack-navigation viewmodel-savedstate

10
推荐指数
0
解决办法
558
查看次数

如何在 Jetpack Compose (NavHostController) 中添加监听器并在导航转换完成时接收回调?

我正在尝试添加一个侦听器,并在 Jetpack Compose 中完成导航转换时接收回调。

我尝试使用 NavController API addOnDestinationChangedListener,但它会立即发送到我的侦听器,并且不会等待合成完成。


val navController = rememberNavController()

// Register the destination changed listener
navController.addOnDestinationChangedListener { _, destination, _ ->
    // destination change is sent immediately and isnt waiting for the composable to finish
}
Run Code Online (Sandbox Code Playgroud)

我的目标是添加一个侦听器,仅在合成完成且目的地更改后才会触发该侦听器。

像这样的东西:

// Register the transition finished listener
navController.transitionFinished{ _, destination ->
    // Do something when the navigation transition has finished
}

    NavHost(navController = navController, startDestination = "Home") {
        composable("Home") { 
            // THE CALLBACK IS FIRED HERE, IMMEDITIETLY
            Text("FIRST SITE") …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack android-jetpack-navigation android-jetpack-compose

10
推荐指数
1
解决办法
2706
查看次数