You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助Shared ViewModel在Android多Fragment间共享数据并同步至Firebase

用Shared ViewModel实现多Fragment数据收集并同步Firebase

1. 创建Shared ViewModel

定义一个继承自ViewModel的类,用MutableLiveData存储需要共享的用户数据,同时提供更新数据的方法:

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

class UserDataViewModel : ViewModel() {
    // 声明需要收集的用户数据字段
    val userName = MutableLiveData<String>()
    val userEmail = MutableLiveData<String>()
    val userPhone = MutableLiveData<String>()

    // 更新数据的方法,供Fragment调用
    fun updateName(name: String) {
        userName.value = name
    }

    fun updateEmail(email: String) {
        userEmail.value = email
    }

    fun updatePhone(phone: String) {
        userPhone.value = phone
    }
}

2. 获取共享的ViewModel实例

核心是通过Activity级别的ViewModelProvider获取实例,确保所有隶属于该Activity的Fragment拿到同一个ViewModel对象:

在Fragment中获取:

class NameFragment : Fragment() {
    private lateinit var viewModel: UserDataViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        viewModel = ViewModelProvider(requireActivity())[UserDataViewModel::class.java]
        return inflater.inflate(R.layout.fragment_name, container, false)
    }
}

在Activity中获取(用于统一监听或触发同步):

class MainActivity : AppCompatActivity() {
    private lateinit var viewModel: UserDataViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewModel = ViewModelProvider(this)[UserDataViewModel::class.java]
    }
}

3. 在Fragment中收集输入并更新ViewModel

以收集姓名的Fragment为例,监听输入框变化,实时同步到ViewModel:

class NameFragment : Fragment() {
    private lateinit var viewModel: UserDataViewModel
    private lateinit var etName: EditText

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_name, container, false)
        etName = view.findViewById(R.id.et_name)
        viewModel = ViewModelProvider(requireActivity())[UserDataViewModel::class.java]

        // 监听输入框内容变化,更新ViewModel
        etName.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable?) {
                s?.toString()?.let { viewModel.updateName(it) }
            }
        })
        return view
    }
}

其他收集邮箱、手机号的Fragment,按照同样逻辑监听输入并调用ViewModel对应的更新方法即可。

4. 将ViewModel数据同步到Firebase

在提交Fragment或Activity中,触发数据同步操作:

class SubmitFragment : Fragment() {
    private lateinit var viewModel: UserDataViewModel
    private lateinit var btnSubmit: Button
    private val db = FirebaseDatabase.getInstance().reference

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_submit, container, false)
        btnSubmit = view.findViewById(R.id.btn_submit)
        viewModel = ViewModelProvider(requireActivity())[UserDataViewModel::class.java]

        btnSubmit.setOnClickListener {
            // 从ViewModel获取所有数据
            val name = viewModel.userName.value ?: ""
            val email = viewModel.userEmail.value ?: ""
            val phone = viewModel.userPhone.value ?: ""

            // 简单数据校验
            if (name.isBlank() || email.isBlank() || phone.isBlank()) {
                Toast.makeText(context, "请填写完整信息", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            // 封装数据为Map
            val userData = mapOf(
                "name" to name,
                "email" to email,
                "phone" to phone
            )

            // 同步到Firebase数据库
            db.child("users").push().setValue(userData)
                .addOnSuccessListener {
                    Toast.makeText(context, "数据同步成功", Toast.LENGTH_SHORT).show()
                }
                .addOnFailureListener { e ->
                    Toast.makeText(context, "同步失败:${e.message}", Toast.LENGTH_SHORT).show()
                }
        }
        return view
    }
}

注意事项

  • 生命周期安全:LiveData会自动感知Fragment的活跃状态,仅在Fragment可见时推送数据更新,避免内存泄漏。
  • 配置变更兼容:ViewModel会在屏幕旋转等配置变更时保留数据,无需额外处理。
  • Firebase权限:开发阶段可暂时设置公开读写权限,上线前必须配置安全规则限制访问。

内容的提问来源于stack exchange,提问作者Vivek M Fauzdar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 07:24:19