View BrowserActivity.kt
omnibarTextInput.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable) {
viewModel.onOmnibarInputStateChanged(omnibarTextInput.text.toString())
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
View BrowserViewModel.kt
// Using RxRelay's implementation of publish subject - https://github.com/JakeWharton/RxRelay
private val autoCompletePublishSubject = PublishRelay.create<String>()
...
/**
* Called only once when the `ViewModel` is being created
* Initialises the autocomplete publish subject
*/
private fun configureAutoComplete() {
View BrowserViewModel.kt
// user clicked on a `tel:` link
command.value = Command.DialNumber(telephoneNumber)
// user clicked on a `sms:` link
command.value = Command.SendSms(telephoneNumber)
// user clicked on a `mailto:` link
command.value = Command.SendEmail(emailAddress)
// need to refresh the `WebView`
View BrowserActivity.kt
viewModel.command.observe(this, Observer {
when (it) {
is BrowserViewModel.Command.Refresh -> webView.reload()
is BrowserViewModel.Command.Navigate -> webView.loadUrl(it.url)
is BrowserViewModel.Command.DialNumber -> {
val intent = Intent(Intent.ACTION_DIAL)
intent.data = Uri.parse("tel:${it.telephoneNumber}")
launchExternalActivity(intent)
}
is BrowserViewModel.Command.SendEmail -> {
View BrowserViewModel.kt
val command: SingleLiveEvent<Command> = SingleLiveEvent()
View BrowserViewModel.kt
sealed class Command {
class Refresh : Command()
class Navigate(val url: String) : Command()
class DialNumber(val telephoneNumber: String) : Command()
class SendSms(val telephoneNumber: String) : Command()
class SendEmail(val emailAddress: String) : Command()
}
View BrowserViewModel.kt
data class ViewState(
val isLoading: Boolean = false,
val progress: Int = 0,
val omnibarText: String? = null,
val isEditing: Boolean = false,
val browserShowing: Boolean = false,
val showClearButton: Boolean = false,
)
View BrowserActivity.kt
viewModel.viewState.observe(this, Observer<BrowserViewModel.ViewState> {
it?.let { render(it) }
})
View BrowserActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_browser)
viewModel.viewState.observe(this, Observer<BrowserViewModel.ViewState> {
it?.let { render(it) }
})
}
private fun render(viewState: BrowserViewModel.ViewState) {
View BrowserViewModel.kt
override fun progressChanged(newProgress: Int) {
viewState.value = currentViewState().copy(progress = newProgress)
}
override fun loadingStarted() {
viewState.value = currentViewState().copy(isLoading = true)
}
override fun loadingFinished() {
viewState.value = currentViewState().copy(isLoading = false)