当配置发生更改并因此重新创建我的 Activity 和 Fragment 时,我的导航图作用域 ViewModel 不可用,而 Fragments 已再次创建。
看起来 Fragment 是在 navGraph 之前重新创建的。
我使用此代码从我的片段初始化我的 navGraph 范围的 ViewModel:
private val myViewModel: MyViewModel by navGraphViewModels(R.id.nav_graph_id)
Run Code Online (Sandbox Code Playgroud)
myViewModel如果我尝试在片段函数中使用onViewCreated,我会IllegalArgumentException在配置更改后得到一个。例外情况:
java.lang.IllegalArgumentException: No destination with ID <destination id> is on the NavController's back stack
Run Code Online (Sandbox Code Playgroud)
我该如何处理这个问题?
编辑1:
这是我的activity_main.xml
<?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"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/main_nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:navGraph="@navigation/main_nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
这是我的 main_nav_graph.xml:
<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"
android:id="@+id/main_nav_graph"
app:startDestination="@id/main_nav_graph_1"> …Run Code Online (Sandbox Code Playgroud) 我最初想创建一个可以在构造函数中中止实例化的类,但根据此链接,我应该改用 Factory 类。但是现在我想阻止除工厂类之外的任何人创建“Inner”类的对象,同时向所有人提供对内部类方法的访问权限。
我已经尝试过这个答案。
import java.util.Date
object InnerFactory {
class Inner private constructor(startDate: Date? = null, endDate: Date? = null) {
fun getTimeDifference(): Long? {
//calculates time difference but doesn't matter to this example
}
}
fun createInnerObject(startDate: Date? = null, endDate: Date? = null): Inner? {
if (startDate != null && endDate != null && !endDate.after(startDate)) {
return null
}
return Inner(startDate, endDate)
}
}
Run Code Online (Sandbox Code Playgroud)
我会像下面这样使用它:
val date1 = Date(1547600000)
val date2 = Date(1547600600)
val …Run Code Online (Sandbox Code Playgroud)