您好,我正在浏览 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 建议我将其替换NavHostFragment为FragmentContainerView.
它们有什么区别?什么时候应该使用它们而不是另一个?
谢谢
android android-studio android-architecture-navigation android-jetpack-navigation
我在所有 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
我创建了一个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
我正在使用 Jetpack Compose + Navigation(单一活动,无片段),并且我正在尝试执行如下导航路线:
SplashScreen---(延迟)---> AuthScreen---(如果成功)-->MainScreen
navigate()不幸的是,当我执行登录时,可组合项中的函数LoginScreen会导致无限循环。我不明白我是否正在触发重组或会发生什么。不幸的是,很难共享所有代码,但请记住:
LoginScreen可MainScreen组合项无关(您可以假设它们只是一个简单的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
我将导航库从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) 你们有一个与设计有关的问题。
因此,我一直在遵循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
我有一个活动,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 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) 我正在使用 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
android android-jetpack android-jetpack-navigation android-jetpack-compose
android-jetpack-navigation ×10
android ×8
android-architecture-navigation ×1
kotlin ×1
material-components-android ×1
mvvm ×1