Android 屏幕旋转时使用 ViewModel 保存 Fragment 数据的解决方案

在 Android 开发中,屏幕旋转可能导致 Activity 重建,从而使 Fragment 的数据丢失。为了有效管理数据,在这种情况下使用 ViewModel 是一种推荐的做法。本文将介绍如何使用 ViewModel 保存 Fragment 数据,并提供相关示例代码。

解决方案概述

通过使用 Android Architecture Components 中的 ViewModel,您可以在屏幕旋转时保存 Fragment 的数据。ViewModel 可以存活于 Activity 或 Fragment 的生命周期之外,这使它们在配置更改(如屏幕旋转)时不被销毁。

相关类图

下面是使用 ViewModel 的基本类图结构:

classDiagram
    class MainActivity {
        +ViewModel viewModel
        +onCreate()
    }
    class MyFragment {
        +ViewModel viewModel
        +onCreateView()
    }
    class MyViewModel {
        +MutableLiveData data
        +setData(value)
        +getData()
    }
    MainActivity --> MyFragment
    MainActivity --> MyViewModel
    MyFragment --> MyViewModel

示例代码

1. 创建 ViewModel

首先,我们需要创建一个 ViewModel 来存储我们要保留的数据。

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> get() = _data

    fun setData(value: String) {
        _data.value = value
    }
}

2. 在 Fragment 中使用 ViewModel

在 Fragment 中,我们可以访问和更新 ViewModel 中的数据。以下代码展示了如何在 Fragment 的 onCreateView 中使用 ViewModel。

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Button

class MyFragment : Fragment() {
    private val viewModel: MyViewModel by activityViewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_my, container, false)

        val textView: TextView = view.findViewById(R.id.textView)
        val button: Button = view.findViewById(R.id.button)

        viewModel.data.observe(viewLifecycleOwner) { value ->
            textView.text = value
        }

        button.setOnClickListener {
            viewModel.setData("新数据:${System.currentTimeMillis()}")
        }

        return view
    }
}

3. 在 Activity 中初始化 Fragment

在 Activity 中创建 Fragment 实例时,只需初始化 ViewModel 并将其与 Fragment 关联。

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragment_container, MyFragment())
                .commit()
        }
    }
}

4. 关系图

下面展示了 ViewModel、Activity 和 Fragment 之间的关系:

erDiagram
    MainActivity ||--o{ MyFragment : contains
    MainActivity ||--o{ MyViewModel : manages
    MyFragment ||--o{ MyViewModel : uses

总结

通过使用 ViewModel,我们可以轻松地管理 Fragment 的数据,以确保在屏幕旋转等配置更改时不会丢失。本文提供了一个简单的示例,包括 ViewModel 的创建和在 Fragment 中的用法。这样,您可以专注于业务逻辑,而不必担心数据丢失的问题。使用这种架构不仅提升了应用的可维护性,也提升了用户体验。