如今,Android 应用程序倾向于实现 Android Navigation 组件(它简化了片段管理和导航),在这种情况下,建议采用不同于其他建议答案的方法,以避免直接操作片段并与片段管理器交互.当您需要做的只是更新适配器数据时,执行“刷新”以使您的片段状态保持最新会不必要地破坏并重新创建视图。
您可以改为使用事件驱动的方法并实现像事件总线这样的模式,消费者可以发布和订阅该模式。更新数据的组件将负责发布与更新相关的事件,而任何关心更新的组件都可以订阅这些事件。
这是 Kotlin 中的一个简单 EventBus 类,它利用协程和流等 Kotlin 语言特性来实现这种描述的模式:
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
class EventBus {
private val _events = MutableSharedFlow<AppEvent>()
val events = _events.asSharedFlow()
suspend fun emitEvent(event: AppEvent) {
_events.emit(event)
}
}
在这种情况下,AppEvent 是一个枚举,例如:
enum class AppEvent {
TODO_LIST_UPDATED
}
如果您想将数据与事件一起传递,您可以为您的AppEvent 实现Kotlin sealed classes 而不是枚举。
假设与您的片段无关的其他组件正在更新数据,一旦完成,它就会发出一个事件:
eventBus.emitEvent(AppEvent.TODO_LIST_UPDATED)
假设您使用的是 MVVM 架构,您的片段的视图模型在初始化时可以订阅事件总线:
init {
viewModelScope.launch {
eventBus.events
.filter { it == AppEvent.TODO_LIST_UPDATED }
.collectLatest {
val todosResponse = todoRepository.getTodos()
_todos.value = todosResponse.todos
}
}
}
一旦检索到新数据,您的片段将观察 LiveData 并在适配器上设置数据。
如果您没有视图模型,您可以直接在片段中执行此操作,使用 lifecycleScope,但现在建议使用视图模型并实现 MVVM 架构。
要确保的一件重要事情是,您的事件总线实例是一个单例实例,以便所有消费者都发布和订阅同一总线。您可以通过使用依赖注入框架并按照为该框架创建单例的说明来实现这一点。
您可以在blog post I wrote on this topic 上详细了解事件总线模式。