Home > Software design >  How to create custom event with the shortest way?
How to create custom event with the shortest way?

Time:07-08

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.

  • Related