gpt4 book ai didi

android - 从 MvvM 架构和 Kotlin 中的广播接收器更新 fragment ui

转载 作者:行者123 更新时间:2023-12-02 12:56:28 27 4
gpt4 key购买 nike

作为 kotlin 和 mvvm 架构的新手,我浪费了过去两天来寻找这个问题的答案,但没有任何成功。所以我正在寻找一个干净的解决方案来更改 fragment ui(在我的情况下它只是一个 TextView ),当设备在互联网上连接/断开时。我正在使用 mvvm 架构和 android 架构组件(viewmodels、livedata、数据绑定(bind)......)。我有一个带有底部导航和多个 fragment 的基本 Activity 。

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

我的第一个想法是使用接口(interface)。此接口(interface)由广播接收器的 onreceive 触发,并在我的 fragment 或 View 模型中实现,因此当互联网事件发生时, TextView 在我的 fragment 中更新。但是我不确定如何在广播接收器中使用该接口(interface),或者我不知道这是否可行或一个好的做法。

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

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


在我的基本 Activity 中注册/注销它
    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)
interface ConnectionStatusChange{
fun onChange()
}

并在我的 fragment 中实现接口(interface)
class myFragment : Fragment(), ConnectionStatusChange {
override fun onChange() {
// do the ui changes here
}
}

我想知道这种方法是否是一种好的做法,以及如何使其发挥作用。如果不可能这样做,请给我一些建议(代码总是很感激!=))。此外,最好有一个现代的,而不是 5 年前的解决方案。先感谢您。

最佳答案

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

所以它是这样工作的:

创建一个包含网络状态的枚举。

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)
}
}

最后,我观察了 fragment 中的 LiveData。
ConnectionStateLiveData.get(context).observe(viewLifecycleOwner, Observer {
if (it == NetworkAvailability.CONNECTED) {
binding.noInternetTextView.visibility = View.GONE
}
})

关于android - 从 MvvM 架构和 Kotlin 中的广播接收器更新 fragment ui,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61226618/

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