gpt4 book ai didi

android - Kotlin与导航-如何将数据保留在先前的 fragment 中

转载 作者:行者123 更新时间:2023-12-02 13:40:07 25 4
gpt4 key购买 nike

我正在使用导航图,并且我的片段A具有RecylerView。回到片段B时,我不想丢失片段A中的数据。
我该怎么做?

最佳答案

分步解决方案。使用ViewModel更改片段后,创建导航图并将ListView内容保存在片段中:

  • 添加到build.gradle (Module: app)中:
  • dependencies { 
    ...

    def nav_version = "2.3.0"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

    def lifecycle_version = "2.2.0"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    }
    android {
    ...

    kotlinOptions {
    jvmTarget = "1.8"
    }
    }
  • 创建两个片段(FragemntSecond可以为空):
  • FragemntStart:
    <androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Start Fragment"
    />

    <Button
    android:id="@+id/butGoTo2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Go To Second"
    />

    <Button
    android:id="@+id/butAddRandomValue"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Add random value"
    />

    <ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

    </androidx.appcompat.widget.LinearLayoutCompat>
  • 创建导航图,添加两个片段并将它们连接到图上。在MainActivity中添加FragmentContainerView:
  • <androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/navigation"
    />
  • 创建一个ViewModel类:
  • import androidx.lifecycle.LiveData
    import androidx.lifecycle.MutableLiveData
    import androidx.lifecycle.ViewModel

    class CommonViewModel : ViewModel()
    {
    // This list will keep all values for Your ListView
    private val _list: MutableLiveData<ArrayList<String>> = MutableLiveData()
    val list: LiveData<ArrayList<String>>
    get() = _list

    init
    {
    _list.value = ArrayList()
    }

    // function which will add new values to Your list
    fun addNewValue()
    {
    _list.value!!.add((0..100).random().toString())
    _list.value = _list.value //this will notify observers
    }
    }
  • 将ViewModel添加到StartFragment中:
  • import android.os.Bundle
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import android.widget.ArrayAdapter
    import androidx.fragment.app.Fragment
    import androidx.lifecycle.ViewModelProvider
    import androidx.navigation.Navigation
    import kotlinx.android.synthetic.main.fragment_start.*

    class StartFragment : Fragment()
    {
    private lateinit var viewModel: CommonViewModel

    override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
    ): View?
    {
    viewModel = ViewModelProvider(requireActivity()).get(CommonViewModel::class.java) // init view model
    return inflater.inflate(R.layout.fragment_start, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?)
    {
    super.onViewCreated(view, savedInstanceState)

    butGoTo2.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_startFragment_to_secondFragment)) // set clickListener to navigate to second fragment
    butAddRandomValue.setOnClickListener { viewModel.addNewValue() } // listener for second button to add new value to ListView

    // set up observer. Every time You add sth to list, ListView will be updated
    viewModel.list.observe(viewLifecycleOwner, {
    listView.adapter = ArrayAdapter(
    requireContext(),
    android.R.layout.simple_list_item_1,
    it
    )
    })
    }
    }
    现在,您可以转到第二个片段,当您返回到“开始”时,您将不会丢失任何数据。这是一个简单的示例,说明如何使用ViewModel在ListView中保存数据。使用RecyclerView时,可以创建扩展ListAdapter的适配器,而在观察器中,只需编写 adapter.submitList(it)即可。

    如果您想从ViewModel访问第二个片段中的数据(例如this list),则可以这样操作:
    class SecondFragment : Fragment()
    {
    private val viewModel: CommonViewModel by activityViewModels() // retrieve the same view model

    override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
    ): View?
    {
    Log.d("MyTag", "${viewModel.list.value}") // here You can access list which is used in StartFragment
    return inflater.inflate(R.layout.fragment_second, container, false)
    }
    }

    关于android - Kotlin与导航-如何将数据保留在先前的 fragment 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64227265/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com