There is CustomWebViewClient
with override function onPageFinished
. What is the shortest way to notify MainViewModel
about the function triggered? I mean some event.
I suppose that can use StateFlow
, something like this:
class MainViewModel : ViewModel() {
init {
val client = CustomWebViewClient()
viewModelScope.launch {
client.onPageFinished.collect {
// ...
}
}
}
}
class CustomWebViewClient() : WebViewClient() {
private val _onPageFinished = MutableStateFlow("")
val onPageFinished = _onPageFinished.asStateFlow()
override fun onPageFinished(view: WebView, url: String) {
_onPageFinished.update { "" }
}
}
But in this case need to transfer unnecessary empty string and will be occurs first call before onPageFinished
called because MutableStateFlow
has value. So appear required add some enum or class in order to do filter with when
keyword.
Maybe is there more shortest way to do that?
CodePudding user response:
You can add lambda parameter into CustomWebViewClient constructor that will get called once page is finished.
class MainViewModel : ViewModel() {
init {
val client = CustomWebViewClient({handle the event})
}
}
class CustomWebViewClient(onPageFinished: () -> Unit) : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
onPageFinished()
}
}
Please note that referencing anything from android.* package in a ViewModel is most often a big no-go.
CodePudding user response:
If you want to use the MutablStateFlow
approach, another option is to also override onPageStarted
as well and do something like
class CustomWebViewClient(): WebViewClient() {
private val _onPageFinished = MutableStateFlow(false)
val onPageFinished = _onPageFinished.asStateFlow()
override fun onPageStarted(
view: WebView?,
url: String?,
favicon: Bitmap?,
) {
_onPageFinished.update { false }
}
override fun onPageFinished(view: WebView?, url: String?) {
_onPageFinished.update { true }
}
}
class MainViewModel : ViewModel() {
init {
val client = CustomWebViewClient()
viewModelScope.launch {
client.onPageFinished.collect {
if (it) {
// Do stuff when page is loaded
} else {
// Do stuff when page starts loading
}
}
}
}
}
Though ultimately using flows for this is kinda overkill and using the lambda approach suggested by Mieszko Koźma is probably more straight forward.