从MvvM架构和Kotlin中的广播接收器更新片段ui

康斯坦丁诺斯

作为Kotlin和mvvm架构的新手,我浪费了过去两天的时间,没有找到成功的答案。因此,我正在寻找一种干净的解决方案,以在设备在Internet中连接/断开连接时更改片段ui(在我的情况下,它只是一个textview)。我正在使用mvvm架构和android架构组件(viewmodels,livedata,数据绑定...)。我有一个基础活动,其中包含一个底部导航和多个片段。

我正在尝试从自定义广播接收器获取连接事件,并且我想以某种方式在viewmodel或我的片段中传递该事件。

我的第一个想法是使用界面。此接口由广播接收器的onreceive触发,并且在我的片段或视图模型中实现,因此,当发生Internet事件时,textview在我的片段中进行更新。但是我不确定如何在广播接收器中使用该接口,或者即使这是可行的还是好的做法,我也不知道。

我到目前为止所做的就是创建广播接收器

class ConnectionStateObserver: BroadcastReceiver() {
    override fun onReceive(p0: Context?, p1: Intent?) {
       //somehow use the interface in here
    }
}

在我的基本活动中注册/注销

    override fun onResume() {
        super.onResume()
        val broadcastIntent = IntentFilter()
        broadcastIntent.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
        registerReceiver(ConnectionStateObserver(), broadcastIntent)
    }
    override fun onPause() {
        super.onPause()
        unregisterReceiver(ConnectionStateObserver())
    }

(我知道ConnectivityManager.CONNECTIVITY_ACTION已过时,但找不到更好的解决方案)。

创建一个界面

interface ConnectionStatusChange{
    fun onChange()
}

并在我的Fragment中实现接口

class myFragment : Fragment(), ConnectionStatusChange {
override fun onChange() {
        // do the ui changes here
    }
}

我想知道这种方法是否是一种好的做法,以及如何使它可行。如果不可能那样做,那么请给我一些建议(始终赞赏代码!=))。还有一个现代的解决方案,而不是5年的解决方案也将是一件好事。先感谢您。

康斯坦丁诺斯

最终,我找到了想要的一种干净,现代的解决方案。诀窍是将BroadcastReceiver包装在LiveData中。通过使用此模式,您可以直接从片段中观察LiveDada的连接并更新ui。当然,也有可能(如提到的sergiy tikhonov一样)在基本活动中有一个随播对象,该对象带有一个从BroadcastReceiver更新的LiveData,您可以从片段中观察到它,但是我不喜欢这种方法。

所以它是这样的:

用网络状态创建一个枚举。

enum class NetworkAvailability {
    UNKNOWN,
    CONNECTED,
    DISCONNECTED
}

创建扩展LiveData的类。我使用单例模式,因为我不需要多个实例。我创建一个BroadcastReceiver实例,并在LiveData的onActive和onInactive方法中注册/注销它。

class ConnectionStateLiveData(val context: Context) : LiveData<NetworkAvailability>() {

    companion object {
        private lateinit var instance: ConnectionStateLiveData

        fun get(context: Context): ConnectionStateLiveData {
            instance = if (::instance.isInitialized){
                instance
            }else{
                ConnectionStateLiveData(context)
            }
            return instance
        }
    }

    private val connectivityBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(p0: Context?, p1: Intent?) {
            val connectivityManager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val netInfo = connectivityManager.activeNetworkInfo

            value = if (netInfo != null && netInfo.isConnected) {
                NetworkAvailability.CONNECTED
            } else {
                NetworkAvailability.DISCONNECTED
            }
        }
    }

    override fun onActive() {
        super.onActive()
        value = NetworkAvailability.UNKNOWN
        val broadcastIntent = IntentFilter()
        broadcastIntent.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
        context.registerReceiver(connectivityBroadcastReceiver, broadcastIntent)
    }

    override fun onInactive() {
        super.onInactive()
        context.unregisterReceiver(connectivityBroadcastReceiver)
    }
}

最后,我在片段中观察了LiveData。

ConnectionStateLiveData.get(context).observe(viewLifecycleOwner, Observer {
                if (it == NetworkAvailability.CONNECTED) {
                    binding.noInternetTextView.visibility = View.GONE
                }
            })

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从广播接收器更新ui

来自分类Dev

在广播接收器中更新TextView

来自分类Dev

片段中的广播接收器无法从服务接收意图

来自分类Dev

从广播接收器更新活动UI组件?

来自分类Dev

通知广播接收器的片段或活动

来自分类Dev

广播接收器和屏幕关闭

来自分类Dev

注册和注销广播接收器?

来自分类Dev

广播接收器

来自分类Dev

广播接收器中的吐司

来自分类Dev

BaseAdaper中的广播接收器

来自分类Dev

即使不在视线中也能保持片段广播接收器处于活动状态

来自分类Dev

广播接收器未在android中接收意图数据。

来自分类Dev

广播接收器vs唤醒广播接收器

来自分类Dev

在循环js中动态更新源和接收器?

来自分类Dev

如何使用 Service 类中的广播接收器更新 Recyclerview?

来自分类Dev

广播接收器或服务?

来自分类Dev

活动中的意图过滤器和广播接收器之间有什么区别?

来自分类Dev

如何在服务和广播接收器中检测关键事件

来自分类Dev

广播接收器类和registerReceiver方法

来自分类Dev

AndroidViewClient删除包和广播接收器

来自分类Dev

服务和广播接收器,以检查网络是否可用

来自分类Dev

ViewPager和更新片段

来自分类Dev

接收并注册广播接收器

来自分类Dev

访问广播接收器中的应用程序类

来自分类Dev

在广播接收器中管理多个警报

来自分类Dev

在广播接收器中访问ViewModel生成的数据

来自分类Dev

如何管理服务中的广播接收器

来自分类Dev

整个应用程序中的广播接收器

来自分类Dev

广播接收器中PACKAGE_INSTALL的替代方法