使用底部导航 android kotlin 在片段中实现 MVVM 的最佳实践 [英] Best practice to implement MVVM in fragment using Bottom navigation android kotlin

查看:47
本文介绍了使用底部导航 android kotlin 在片段中实现 MVVM 的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 firebase 的底部导航在片段中实现 MVVM.但这在我的情况下不起作用.我搜索了很多解决方案,但没有解决我的问题.

我在片段中实现了 viewModel 并将观察者应用于它.在 ViewModel 类中,从存储库调用返回类型为 LiveData 的方法(从 firebase 获取数据).

我正在使用这些依赖项

依赖

//使用 JetPack 的 Fragment 导航实现 'androidx.navigation:navigation-fragment-ktx:2.3.5'实现 'androidx.navigation:navigation-ui-ktx:2.3.5'

Repository.kt

<预><代码>//获取紧急请求fun getEmergencyRequests(): LiveData>{val mutableData = MutableLiveData>()val requestListener = 对象:ValueEventListener {覆盖乐趣 onDataChange(dataSnapshot: DataSnapshot) {如果 (dataSnapshot.exists() && dataSnapshot.hasChildren()) {//获取 Post 对象并使用这些值更新 UIval listData = mutableListOf()for(dataSnapshot.children 中的快照){val 模型 = snapshot.getValue(EmergencyRequests::class.java)模型?.let {model.requestId = snapshot.ref.key.toString()listData.add(it)}}listData.sortByDescending { it.timestamp }mutableData.value = listData}}覆盖乐趣 onCancelled(错误:DatabaseError){Log.e("EMERGENCIES_FAIL", error.message)}}EmergencyRequestRef?.addValueEventListener(requestListener)返回可变数据}

ViewModel.kt

私有val仓库:HomeRepository = HomeRepository()fun getRequests(): LiveData>{repository.getEmergencyRequests()val mutableData = MutableLiveData>()repository.getEmergencyRequests().observeForever {mutableData.value = 它}返回可变数据}

片段.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(视图,savedInstanceState)//初始化初始化()//回收器视图binding.recyclerView.layoutManager = LinearLayoutManager(mContext)适配器 = EmergenciesAdapter(mContext, object : OnRequestClick {覆盖乐趣 onClick(模型:紧急请求){}})binding.recyclerView.adapter = 适配器//获取紧急情况//获取紧急情况()viewModel = ViewModelProvider(mContext).get(HomeViewModel::class.java)观察者()}私人有趣的观察者(){viewModel.getRequests().observe(viewLifecycleOwner, {适配器.setDataList(it)适配器.notifyDataSetChanged()})}

解决方案

不确定这是否会为您解决,但如果您使用 bottom navigation view 并且想要 fragments为访问的目的地维护一个backstack,然后使用这个版本的Navigation dependency你可以自动保存backstacks,使用这些导航依赖:

实现'androidx.navigation:navigation-fragment-ktx:2.4.0-alpha01'实现 'androidx.navigation:navigation-ui-ktx:2.4.0-alpha01'

更新

在您的存储库中,您能取回数据吗?因为该函数可能会在从 firebase 获取数据之前返回.我建议像这样重构它:

<块引用>

Repository.kt

private val _data: MutableLiveData>= MutableLiveData()val 数据:LiveData>get() = _data//获取紧急请求有趣的 getEmergencyRequests() {val requestListener = 对象:ValueEventListener {覆盖乐趣 onDataChange(dataSnapshot: DataSnapshot) {如果 (dataSnapshot.exists() && dataSnapshot.hasChildren()) {//获取 Post 对象并使用这些值更新 UIval listData = mutableListOf()for(dataSnapshot.children 中的快照){val 模型 = snapshot.getValue(EmergencyRequests::class.java)模型?.let {model.requestId = snapshot.ref.key.toString()listData.add(it)}}listData.sortByDescending { it.timestamp }_data.value = 列表数据}}覆盖乐趣 onCancelled(错误:DatabaseError){Log.e("EMERGENCIES_FAIL", error.message)}}EmergencyRequestRef?.addValueEventListener(requestListener)}

<块引用>

ViewModel.kt

私有val仓库:HomeRepository = HomeRepository()fun getRequests(): LiveData>{repository.getEmergencyRequests()返回 repository.data}

I am implementing the MVVM in fragments using the bottom navigation with firebase. But it's not working in my case. I searched for many solutions but didn't solve my problem.

I implemented viewModel in the fragment and apply observer to it. In the ViewModel class, call the method(getting data from firebase) with return type LiveData from the repository.

I'm using these dependencies

dependencies

//    Fragment Navigation using JetPack
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'

Repository.kt


    // Get emergency requests
    fun getEmergencyRequests(): LiveData<MutableList<EmergencyRequests>> {
        val mutableData = MutableLiveData<MutableList<EmergencyRequests>>()

        val requestListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                if (dataSnapshot.exists() && dataSnapshot.hasChildren()) {

                    // Get Post object and use the values to update the UI
                    val listData = mutableListOf<EmergencyRequests>()

                    for (snapshot in dataSnapshot.children) {
                        val model = snapshot.getValue(EmergencyRequests::class.java)

                        model?.let {
                            model.requestId = snapshot.ref.key.toString()
                            listData.add(it)
                        }
                    }

                    listData.sortByDescending { it.timestamp }
                    mutableData.value = listData


                }
            }

            override fun onCancelled(error: DatabaseError) {
                Log.e("EMERGENCIES_FAIL", error.message)
            }

        }

        emergencyRequestRef?.addValueEventListener(requestListener)

        return mutableData
    }

ViewModel.kt

private val repository: HomeRepository = HomeRepository()

    fun getRequests(): LiveData<MutableList<EmergencyRequests>> {
        repository.getEmergencyRequests()
        val mutableData = MutableLiveData<MutableList<EmergencyRequests>>()
        repository.getEmergencyRequests().observeForever {
            mutableData.value = it
        }
        return mutableData
    }

Fragment.kt

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

//        Initialize
        initialization()

//        Recyclerview
        binding.recyclerView.layoutManager = LinearLayoutManager(mContext)
        adapter = EmergenciesAdapter(mContext,  object : OnRequestClick {
            override fun onClick(model: EmergencyRequests) {

            }
        })
        binding.recyclerView.adapter = adapter

//        Get emergencies
//        getEmergencies()
        viewModel = ViewModelProvider(mContext).get(HomeViewModel::class.java)


        observer()

    }

    private fun observer() {
        viewModel.getRequests().observe(viewLifecycleOwner, {
            adapter.setDataList(it)
            adapter.notifyDataSetChanged()
        })
    }

解决方案

Not sure if this will fix it for you, but if you are using bottom navigation view and want fragments to maintain a backstack for the visited destinations, then with this version of Navigation dependency you can get to save the backstacks automatically, use these Navigation dependencies:

implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0-alpha01'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.0-alpha01'

UPDATE

In your repository, are you able to get the data back? since the function might be returning before it gets data from firebase. I would suggest refactoring it a bit like this:

Repository.kt

private val _data: MutableLiveData<MutableList<EmergencyRequests>> = MutableLiveData()

val data: LiveData<MutableList<EmergencyRequests>> get() = _data

// Get emergency requests
fun getEmergencyRequests() {

    val requestListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            if (dataSnapshot.exists() && dataSnapshot.hasChildren()) {

                // Get Post object and use the values to update the UI
                val listData = mutableListOf<EmergencyRequests>()

                for (snapshot in dataSnapshot.children) {
                    val model = snapshot.getValue(EmergencyRequests::class.java)

                    model?.let {
                        model.requestId = snapshot.ref.key.toString()
                        listData.add(it)
                    }
                }

                listData.sortByDescending { it.timestamp }
                _data.value = listData


            }
        }

        override fun onCancelled(error: DatabaseError) {
            Log.e("EMERGENCIES_FAIL", error.message)
        }

    }

    emergencyRequestRef?.addValueEventListener(requestListener)
}

ViewModel.kt

private val repository: HomeRepository = HomeRepository()

fun getRequests(): LiveData<MutableList<EmergencyRequests>> {
    repository.getEmergencyRequests()
    
    return repository.data
}

这篇关于使用底部导航 android kotlin 在片段中实现 MVVM 的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆