Nowadays, Android apps tend to implement the Android Navigation component (which simplifies fragment management and navigation), in which case it is recommended to take another approach than the other suggested answers to avoid directly manipulating fragments and interacting with the fragment manager. Performing a "refresh" to keep your fragment state up to date unnecessarily destroys and recreates the view when all you need to do is update your adapter data.
You could instead use an event-driven approach and implement a pattern like an Event Bus, to which consumers can publish and subscribe. Your component that is updating the data would be responsible for publishing an update-related event, while any components that care about the update can subscribe to these events.
Here is a simple EventBus class in Kotlin that leverages Kotlin language features like coroutines and flows to implement this described pattern:
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)
}
}
In this case, AppEvent
is an enum, for example:
enum class AppEvent {
TODO_LIST_UPDATED
}
If you'd like to pass the data alongside the event, you could implement Kotlin sealed classes for your AppEvent
instead of an enum.
Assuming some other component, unrelated to your fragment is updating the data, once it's complete it can emit an event:
eventBus.emitEvent(AppEvent.TODO_LIST_UPDATED)
Assuming you are using MVVM architecture, your fragment's view model can subscribe to the event bus when initialized:
init {
viewModelScope.launch {
eventBus.events
.filter { it == AppEvent.TODO_LIST_UPDATED }
.collectLatest {
val todosResponse = todoRepository.getTodos()
_todos.value = todosResponse.todos
}
}
}
Your fragment would observe the LiveData and set the data on the adapter once the new data is retrieved.
If you do not have a view model, you can do this directly in your fragment, using lifecycleScope
though nowadays, having a view model and implementing MVVM architecture is recommended.
One important thing to make sure of is that your event bus instance is a singleton instance so that all consumers are publishing and subscribing to the same bus. You can achieve this by using a dependency injection framework and following the directions on creating singletons for that framework.
You can read more about the event bus pattern in detail on a blog post I wrote on this topic.