标签: android-jetpack-navigation

NavHostFragment 与 FragmentContainerView [Android]

您好,我正在浏览 Android 开发人员网站上的导航指南,并按照说明创建了一个NavHostFragment

<fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />
Run Code Online (Sandbox Code Playgroud)

然而,当该代码存在时,IDE 建议我将其替换NavHostFragmentFragmentContainerView.

它们有什么区别?什么时候应该使用它们而不是另一个?

谢谢

android android-studio android-architecture-navigation android-jetpack-navigation

6
推荐指数
1
解决办法
4585
查看次数

如何解决 java.lang.NoSuchFieldError: No field Companion of type Landroidx/compose/runtime/SlotTable$Companion?

我在所有 Jetpack compose 项目中多次收到此错误。这个错误是否与 Gradle 有关?因为我没有对主题进行任何更改。

java.lang.NoSuchFieldError: No field Companion of type Landroidx/compose/runtime/SlotTable$Companion; in class Landroidx/compose/runtime/SlotTable; or its superclasses (declaration of 'androidx.compose.runtime.SlotTable' appears in /data/app/~~-cK_xmGsJokhf6B_7aQseg==/com.swetajain.library-CN37OSea3A4uAWXYCBb63w==/base.apk)
Run Code Online (Sandbox Code Playgroud)

日志

应用程序.build.gradle

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.ui:ui-tooling:$compose_version"
    implementation "androidx.compose.runtime:runtime:$compose_version"
    implementation "androidx.compose.foundation:foundation:$compose_version"
    implementation "androidx.compose.foundation:foundation-layout:$compose_version"
    implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
    implementation "com.google.android.material:compose-theme-adapter:$compose_version"
    api 'com.github.bumptech.glide:glide:4.11.0'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-beta01'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0-beta01@aar'
    implementation 'androidx.activity:activity-ktx:1.2.0-beta01@aar'
    implementation "dev.chrisbanes.accompanist:accompanist-coil:0.3.3.1"
    def nav_compose_version = "1.0.0-alpha02"
    implementation "androidx.navigation:navigation-compose:$nav_compose_version"
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
Run Code Online (Sandbox Code Playgroud)

build.gradle-项目

buildscript {

    ext.compose_version = …
Run Code Online (Sandbox Code Playgroud)

android-studio android-jetpack material-components-android android-jetpack-navigation android-jetpack-compose

6
推荐指数
1
解决办法
3052
查看次数

java.lang.IllegalStateException:在将 NavBackStackEntry 的 ViewModel 添加到 NavController 的返回堆栈之前,您无法访问它

我创建了一个composable名为 ResolveAuth. ResolveAuth 是用户在 Splash 后打开应用程序时的第一个屏幕。它所做的只是检查数据存储中是否存在电子邮件。如果是,则重定向到主屏幕,如果不是,则重定向到教程屏幕

这是我的composable代码viewmodel

@Composable
fun ResolveAuth(resolveAuthViewModel: ResolveAuthViewModel, navController: NavController) {

Scaffold(content = {
    ProgressBar()

    when {
        resolveAuthViewModel.userEmail.value != "" -> {
            navController.navigate(Screen.Main.route) {
                popUpTo(0)
            }
            resolveAuthViewModel.userEmail.value = null
        }
        resolveAuthViewModel.userEmail.value == "" -> {
            navController.navigate(Screen.Tutorial.route) {
                popUpTo(0)
            }
            resolveAuthViewModel.userEmail.value = null
        }
    }
})
}


@HiltViewModel
class ResolveAuthViewModel @Inject constructor(
    private val dataStoreManager: DataStoreManager): ViewModel(){

    val userEmail = MutableLiveData<String>()

    init {
        viewModelScope.launch{
           val job = async {dataStoreManager.email.first()}
           val email = job.await() …
Run Code Online (Sandbox Code Playgroud)

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

6
推荐指数
1
解决办法
2963
查看次数

Jetpack Compose + 导航 - navigate() 上的无限循环

我正在使用 Jetpack Compose + Navigation(单一活动,无片段),并且我正在尝试执行如下导航路线:

SplashScreen---(延迟)---> AuthScreen---(如果成功)-->MainScreen

navigate()不幸的是,当我执行登录时,可组合项中的函数LoginScreen会导致无限循环。我不明白我是否正在触发重组或会发生什么。不幸的是,很难共享所有代码,但请记住:

  • 这个问题似乎与LoginScreenMainScreen组合项无关(您可以假设它们只是一个简单的Text可组合项)
  • 似乎也没有什么关系NavigationGraph。事实上,如果我只是进行SplashScreen-->MainScreen转换,就不会出现问题
  • 如果我删除该行,navController.navigate("main")则不再有循环;
  • 该代码基于(几乎复制粘贴)示例

这是AuthScreen出现问题的代码。

@Composable
fun AuthScreen(navController: NavController) {
    val signInRequestCode = 1
    val context = LocalContext.current

    val mSignInViewModel: SignInGoogleViewModel = viewModel(
        factory = SignInGoogleViewModelFactory(context.applicationContext as Application)
    )

    val state = mSignInViewModel.googleUser.observeAsState()
    val user = state.value

    val isError = rememberSaveable { mutableStateOf(false) }


    val authResultLauncher =
        rememberLauncherForActivityResult(contract …
Run Code Online (Sandbox Code Playgroud)

infinite-loop android-jetpack-navigation android-jetpack-compose

6
推荐指数
1
解决办法
2907
查看次数

添加多个后退堆栈支持后 Android jetpack 导航不起作用 [2.4.+]

我将导航库从2.3.5更新到2.4.2。更新后我开始收到此错误:java.lang.IllegalArgumentException: No destination with ID XXX is on the NavController's back stack. The current destination is null。执行以下步骤后会发生错误:FirstFragment -> SecondFragment [with another BottomNavigationView] -> ThirdFragment -> SecondFragment [crash]

我将尝试描述我正在做的事情:

我有两个片段BottomNavigationView

  • 第一个片段

    class MainBottomNavFragment : Fragment() {
    
        private lateinit var navController: NavController
    
        override fun onStart() {
            super.onStart()
            if (!::navController.isInitialized) {
                navController =
                    Navigation.findNavController(requireActivity(), R.id.mainBottomNavHostFragment)
            }
            binding.bottomNavigation.setupWithNavController(navController)
        }
    }

Run Code Online (Sandbox Code Playgroud)

布局


    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment
            android:id="@+id/mainBottomNavHostFragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:defaultNavHost="false" …
Run Code Online (Sandbox Code Playgroud)

android bottomnavigationview android-jetpack-navigation

6
推荐指数
0
解决办法
713
查看次数

将数据从一个ViewModel传递到另一个Android MVVM

你们有一个与设计有关的问题。

因此,我一直在遵循Google编写的《应用程序架构指南》,使用Kotlin,MVVM和数据绑定来构建我的应用程序。我正在使用Google规定的Jetpack组件(导航,实时数据等)。

问题是,在开发过程中,很多时候我需要将数据从一个片段传输到另一个片段。之前,我曾经创建片段的实例并添加复杂数据,然后移至片段,如下所示:

class Frag1: Fragment(){

    ...
    fun openFrag2(){
        val frg2 = frag2.newInstance(complexDataObj)
        childFragmentManager.addFragment(frg2,TAG)
    }
}

class Frag2: Fragment(){
    var cd: ComplexDataClass = null
    companion object{
    fun newInstance(complexData: ComplexDataClass): Fragment{
        val frag = ActivityFragment()
        frag.cd = complexData
        return frag
    }
    ....
}
Run Code Online (Sandbox Code Playgroud)

导航目的地之间传递数据应该是像这样或以使用共享视图模型也被同一文档中提到。>>

通常,强烈建议您仅在目标之间传递最少的数据量。例如,您应该传递键来检索对象,而不要传递对象本身,因为所有保存状态的总空间在Android上受到限制。如果您需要传递大量数据,请考虑使用在片段之间共享数据中所述的ViewModel。

这可行。

我的问题是,使用体系结构的主要原因之一是关注点分离。这样我们就可以编写干净且可维护的代码。根据我的理解,sharedviewmodel的这种用法无法达到目的,因为这会导致大型ViewModel类。

我将尝试使用非常常见的情况来解释问题。

我有一个带有数据列表的片段。列表中的每个项目都对应一个用户。当我们点击一​​个项目时,它将移至用户详细信息屏幕,如果我们点击编辑按钮,则应移至可编辑详细信息的编辑屏幕。

             View User Frag
             ____                 ____________
            |    |               |            |
 List Frag  |    |               |            |
 ______     |____|               |            |
|______| /
|______|/ …
Run Code Online (Sandbox Code Playgroud)

android mvvm android-architecture android-jetpack android-jetpack-navigation

5
推荐指数
1
解决办法
98
查看次数

使用 jetpack 从 ViewPager2 导航到另一个片段

我有一个活动,FragmentHome 包含 viewpager2。在viewpager 里面有FirstFragment。

在此处输入图片说明

当我想从 FirstFragment 导航到不在 viewpager2 中的 SecondFragment 时

在此处输入图片说明

它抛出

 java.lang.IllegalArgumentException: navigation destination com.example.mymessangerfcm:id/action_FirstFragment_to_SecondFragment is unknown to this NavController
Run Code Online (Sandbox Code Playgroud)

亲爱的社区如何处理这样的导航,为什么会抛出异常?

android android-viewpager2 android-jetpack-navigation

5
推荐指数
1
解决办法
1069
查看次数

导航资源显示未找到 NavHostFragments

我正在运行 Android Studio 3.6.3 并且我正在尝试使用作为 Android Jetpack 一部分的新导航资源。我做了Navigation Codelab来学习如何使用这个功能。

在我的项目中,我添加了一个导航资源,Android Studio 会自动添加此功能的依赖项。然后我创建了一个带有 a 的 Activity 布局NavHostFragment

但是,当我转到我的导航资源时,HOST左侧的部分显示No NavHostFragments found.

我试过同步 Gradle、清理和重建,但无济于事。

有趣的是,当我预览我的主要 Activity 布局时,“主目的地”片段会通过 偷看NavHostFragment,所以看起来关系是在一个方向上建立的,而不是另一个方向。

如何让我的NavHostFragment出现在导航资源中?

这是我的布局 XML:

<?xml version="1.0" encoding="utf-8"?>
<layout 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"
    tools:context="my.app.MyActivity"
    >

    <data>
        <variable
            name="viewModel"
            type="my.app.MyViewModel" />
    </data>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <fragment
                    android:id="@+id/my_nav_host"
                    android:name="androidx.navigation.fragment.NavHostFragment"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:defaultNavHost="true"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:navGraph="@navigation/central_navigation" />
            </LinearLayout>
        </androidx.core.widget.NestedScrollView>

        <com.google.android.material.appbar.AppBarLayout …
Run Code Online (Sandbox Code Playgroud)

android android-studio android-jetpack-navigation

5
推荐指数
1
解决办法
1603
查看次数

使用带有jetpack导航组件的导航抽屉时如何更改工具栏图标(汉堡包图标)

我正在使用 jetpack 导航组件来构建导航抽屉,我想更改工具栏的汉堡包图标,我尝试了很多解决方案,例如波纹管,但它们不起作用

app:navigationIcon="@drawable/menu"
Run Code Online (Sandbox Code Playgroud)

getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.menu);
Run Code Online (Sandbox Code Playgroud)

这是我的代码

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)
    navController=findNavController(R.id.nav_host_fragment)
    appBarConfiguration=AppBarConfiguration(setOf(R.id.nav_acceuil,R.id.nav_notifications,R.id.nav_gerer,R.id.nav_deconnexion),drawer_layout)
    setupActionBarWithNavController(navController,appBarConfiguration)
    nav_view.setupWithNavController(navController);
}
Run Code Online (Sandbox Code Playgroud)

android navigation-drawer hamburger-menu android-jetpack android-jetpack-navigation

5
推荐指数
1
解决办法
518
查看次数

如何在 Jetpack Compose 中从可组合导航到活动或片段?

可组合和活动之间的导航方式有哪些,反之亦然?我可以通过使用 StartActivity(..) 方法还是唯一的方法是创建屏幕和导航控制器?

在此处输入图片说明

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

5
推荐指数
2
解决办法
3235
查看次数