如何防止素材底部导航中的碎片重新创建?

时间:2020-10-15 09:35:05

标签: android android-layout kotlin android-fragments

您好,我正在使用Material Bottom Navigation。我有3个片段A(家庭),B和C。重新创建从b到c的片段时,数据也丢失了,并且正在发送新的网络呼叫。

我不想丢失数据,也不想发送新的网络呼叫。

请帮助我解决此问题。

1 个答案:

答案 0 :(得分:0)

您可以使用MVVM设计模式。如果您不知道它是什么,可以检查此Codelab。您也可以观看此YouTube tutorial。实际上,这只是关于ViewModel的。 ViewModel可以存储您的数据,即使重新创建您的片段(例如,当用户侧向翻转手机时),它也可以再次显示给您。

在ViewModel中,您需要一个私有MutableLiveData和一个公共LiveData,如下所示

private var _data = MutableLiveData<T>()
val data: LiveData<T>
    get() = _data

并且您需要一个功能来进行网络呼叫。

fun getData() {
    CoroutineScope(Dispatchers.IO).launch {
        _data.postValue(Your Data From Network)
    }
}

有!您的ViewModel完成。干得好!

现在我们可以在Fragment中使用它了。

在您的片段(您想使用哪个片段)里面,在类声明下面编写这段代码

private val yourViewModel: YourViewModel by activityViewModels()

activityViewModels()意味着,如果您对所有片段都使用相同的活动,它将不会被初始化超过一个,并且您的数据也不会被破坏。当您更改活动时,ViewModel会自行销毁。

您的片段中需要观察者。观察者可以观察数据,并在数据更改时调用。您可以像下面这样写观察者

private fun setupObserver() {
    yourViewModel.data.observe(this.viewLifecycleOwner, Observer {
        // This is a lambda function. When data change inside the viewModel data sending here.
        // Your code here
    })
}

现在,您可以使用yourViewModel调用getData()函数。 您可以将此代码用于此次通话。

private fun getDataIfEmpty() {
    yourViewModel.data.value.also { data: T? // This can be null ->
        if (data.isNullOrEmpty()) {
            // if data is null or blank than call getData() function
            yourViewModel.getData().also { setupObserver() }
        } else // if data is not null than you can setup your fragment
    }
}

在onStart()函数中使用此代码。

您必须在build.gradle(Module:app)文件中添加此依赖项

// ViewModel
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'androidx.activity:activity-ktx:1.1.0'
implementation 'androidx.fragment:fragment-ktx:1.1.0'

还要在buildTypes内部的以下build.gradle(Module:app)文件中添加此编译选项

   compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }