标签: android-jetpack-navigation

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
查看次数

setOnApplyWindowInsetsListener() 未应用填充并调用 2 次

我打电话setOnApplyWindowInsetsListener给我的视图添加填充/边距。我的 XML 包含android:fitsSystemWindows="true"

setOnApplyWindowInsetsListener被调用两次后(第二次插入 0)。

为什么 Android 返回 insets 两次并且第二次 insets 值为零?为什么当我将其设置为第一个值时,我的填充不适用?

代码:

drawer.setOnApplyWindowInsetsListener((v, insets) -> {
            profileButton.setPadding(
                    profileButton.getPaddingLeft(),
                    profileButton.getPaddingTop(),
                    insets.getSystemWindowInsetBottom(),
                    profileButton.getPaddingBottom()
            );
            Timber.d("Inset applied: %d", insets.getSystemWindowInsetBottom());
            return insets;
        });
Run Code Online (Sandbox Code Playgroud)

控制台输出:

D/MainActivity: Inset applied: 53
D/MainActivity: Inset applied: 0
Run Code Online (Sandbox Code Playgroud)

android android-layout android-jetpack android-jetpack-navigation

9
推荐指数
0
解决办法
883
查看次数

ViewPager2 崩溃

我正在使用带有 BottomNavigationView 的高级导航组件。

在一个选项卡中,我有 ViewPager2。当我第一次点击 Tab 时工作正常。

尽管第二次出现该选项卡应用程序不断崩溃。如果有人可以帮助,下面是崩溃日志,谢谢。

java.lang.IllegalArgumentException at androidx.core.util.Preconditions.checkArgument(Preconditions.java:36) at androidx.viewpager2.adapter.FragmentStateAdapter.onAttachedToRecyclerView(FragmentStateAdapter.java:140) at androidx.recyclerview.widget.set.RecyclerView() RecyclerView.java:1206) at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1158) at androidx.viewpager2.widget.ViewPager2.setAdapter(ViewPager2.java:460) at com。.ui.home.history.HistoryFragment.setupAdapter(HistoryFragment.kt:25) 在 com。.ui.home.history.HistoryFragment.viewSetup(HistoryFragment.kt:21) at com.****.base.BaseFragment.onViewCreated(BaseFragment.kt:37) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager. java:332) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356) 在 androidx.fragment.app.FragmentManager.moveFragmentToFragmentManager.moveFragment(FragmentManager.java:1187) .java:1434) 在 androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497) 在 androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625) 在 androidx.fragment.app.FragmentManager.dispatchCreatedActivity FragmentManager.java:2577) 在 androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2722) 在 androidx.fragment.app.FragmentStateManager。activityCreated(FragmentStateManager.java:346) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1188) at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224) at androidx.fragment.app.Fragment .executeOpsTogether(FragmentManager.java:1997) 在 androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953) 在 androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849) FragmentManager$4.run(FragmentManager.java:413) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop( Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6940) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os。RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

这是我的片段代码:

private val …
Run Code Online (Sandbox Code Playgroud)

android android-recyclerview android-jetpack android-viewpager2 android-jetpack-navigation

9
推荐指数
3
解决办法
3142
查看次数

使用 Compose 时如何在 Jetpack Navigation 中显示布局?

我开始使用 Jetpack Compose,我对它非常满意。我替换了几个由@Composable函数在 xml 中定义的布局。

当我回到我的 Navigation-xml 时,我注意到每个屏幕内的预览都是通过tools:layout属性完成的。以及对 xml 中布局的属性引用。不是一个@Composable函数。

@Composable是否已经有一种方法可以从导航 xml 中引用函数,tools:layout以便整个流程的预览可见?

android android-jetpack-navigation android-jetpack-compose

9
推荐指数
0
解决办法
644
查看次数

撰写导航中没有方法导航(字符串)

我正在尝试新的喷气背包库“ compose-navigation ”。

根据docs,要导航到路线,我应该使用navigate()采用String 的方法。

navController = rememberNavController()

// navigate
navController.navigate("/another_route")
Run Code Online (Sandbox Code Playgroud)

但是,不存在这样的方法, navigate(String)并且出现编译错误。

我错过了什么?

android android-jetpack-navigation android-jetpack-compose

9
推荐指数
1
解决办法
797
查看次数

如何从嵌套可组合 Jetpack Compose 访问 NavHostController

假设我的应用程序如下所示

@Composable
fun AppNavigation() {
    val navController = rememberNavController()

    NavHost(navController, startDestination = Route.Home.route) {
        /// other composes
        composable("Home") { HomeCompose(navController) }
    }
}

@Composable
fun HomeCompose(navController: NavHostController) {
    ChildCompose(navController)
}

@Composable
fun ChildCompose(navController: NavHostController) {
    navController.navigate("")
}
Run Code Online (Sandbox Code Playgroud)

我想访问嵌套可组合项中的 navController 进行导航,但我不想将 navController 从父可组合项传递到子可组合项,如上所述

无论如何,是否可以从 NavHost 内的任何位置访问 navController,而无需通过可组合层次结构传递它

编辑:现在,我可以使用 CompositionLocalProvider 访问嵌套组合中的 navController,如下所示

val AppNavController = compositionLocalOf<NavHostController>() { error("NavHostController error") }

@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    CompositionLocalProvider(
        AppNavController provides navController
    ) {
        NavHost(navController, startDestination = Route.Home.route) {
            /// other composes …
Run Code Online (Sandbox Code Playgroud)

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

9
推荐指数
1
解决办法
3708
查看次数

如何通过 hilt 在 compose ViewModel 中使用 NavController

我使用 jetpack compose 和导航撰写库来从一个屏幕导航到下一个屏幕。通常你会有一个ViewModel负责用户交互的(例如:)viewModel.addItem()。为了完成 addItem 命令,我想通过显示另一个屏幕navController.navigate()。其ViewModel本身通过 注入到可组合项中hiltNavGraphViewModel()

现在的问题是:我怎样才能将其注入到刀柄NavController中?ViewModel

@HiltViewModel
class ScreenViewModel @Inject constructor(
  private val navController: NavController // where does it come from?
) : ViewModel() {

  fun addItem() {
    navController.navigate("add-item-screen")
  }

}
Run Code Online (Sandbox Code Playgroud)

NavController是通过rememberNavController()可组合层次结构中的 up 方法创建的。我也不想将控制器传递到可组合层次结构或使用 CompositionLocal。首选方法是让控制器在 ViewModel 中可用。

android-jetpack-navigation android-jetpack-compose dagger-hilt

9
推荐指数
1
解决办法
3604
查看次数

Jetpack Compose &amp; Navigation:问题在嵌套图中共享 ViewModel

根据这个示例,我在嵌套导航图中实现了共享 viewModel。

设置

嵌套图:

private fun NavGraphBuilder.accountGraph(navController: NavHostController) {
   navigation(
      startDestination = "main",
      route = "account") {

       composable("main") {
          val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
          //... ui ...
       }

       composable("login") {
          val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
          //... ui ...
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

导航主机:

@Composable
private fun NavHost(navController: NavHostController, modifier: Modifier = Modifier){
   NavHost(
      navController = navController,
      startDestination = MainScreen.Home.route,
      modifier = modifier
   ) {
      composable("home") { HomeScreen(hiltViewModel()) }
      composable("otherRoute") { OtherScreen(hiltViewModel()) }
      accountGraph(navController)
   }
}
Run Code Online (Sandbox Code Playgroud)

底部导航栏:

@Composable
private fun ButtonNav(navController: NavHostController) …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack-navigation android-jetpack-compose dagger-hilt

9
推荐指数
1
解决办法
3267
查看次数

防止通过伴奏库点击背景关闭底部工作表

我已尝试从本文中进行伴奏库导航,并且我想防止当我单击底部工作表的背景(灰色区域)时关闭底部工作表并使其根本不可单击,我该如何实现这一点?

这是链接中的代码

@Composable
fun MyApp() {
    val navController = rememberNavController()
    val bottomSheetNavigator = rememberBottomSheetNavigator()
    navController.navigatorProvider += bottomSheetNavigator


    ModalBottomSheetLayout(
        bottomSheetNavigator = bottomSheetNavigator
    ) {
        NavHost(navController, startDestination = "home") {
            composable(route = "home") {
                Button(onClick = { navController.navigate("sheet") }) {
                    Text("Click me to see something cool!")
                }
            }
            bottomSheet(route = "sheet") {
                Text("This is a cool bottom sheet!")
                Button(onClick = { navController.navigate("home") }) {
                    Text("Take me back, please!")
                }
                Spacer(modifier = Modifier.padding(200.dp))
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

android-jetpack-navigation android-jetpack-compose jetpack-compose-accompanist

9
推荐指数
1
解决办法
6077
查看次数