Skip to content

Instantly share code, notes, and snippets.

@alwarren
Created June 13, 2018 16:25
Show Gist options
  • Save alwarren/ff7670dc997f10a6c8a68559fe56d8a5 to your computer and use it in GitHub Desktop.
Save alwarren/ff7670dc997f10a6c8a68559fe56d8a5 to your computer and use it in GitHub Desktop.
Android ViewModel Using SwitchMap
class SwitchMapViewModel @Inject constructor(private val dataSource: Data) : ViewModel() {
// observed by ViewModel as a trigger to retrieve data from the source
private var liveTrigger: MutableLiveData<String> = MutableLiveData()
// observed by Activity/Fragment or some other class as a trigger to do something with the data
private var liveData: LiveData<String>
init {
// default observable trigger
liveTrigger.value = dataSource.defaultText
// observe liveTrigger and reload observable liveData when trigger changes
liveData = Transformations.switchMap(liveTrigger) {
dataSource.fetchData(liveTrigger.value!!)
}
}
// changing liveTrigger's value causes Transformations.switchMap to send a value to the Data
// model where it's live value is updated. Data model returns it's live data which replaces the
// ViewModel's live data. MainActivity's observer sees the change and updates it's UI
// with the new value.
fun setData(value: String) {
liveTrigger.value = value
}
// retrieve the observable data
fun getData(): LiveData<String> = liveData
}
class SwitchMapViewModelActivity : DaggerAppCompatActivity(), TextInputDialog.OnTextResult {
@Inject lateinit var data: Data
@Inject lateinit var factory: ViewModelProvider.Factory
private val viewModel by lazy(LazyThreadSafetyMode.NONE) {
ViewModelProviders.of(this, factory).get(SwitchMapViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
button.setOnClickListener {
// Custom Dialog Class
TextInputDialog(this, R.string.app_name).build().show()
}
// Observe the ViewModel's live data. When it changes, update the UI with the new value.
viewModel.getData().observe(this, Observer {
it?.let { data -> updateUI:: }
})
}
// Send the text from the Dialog to the ViewModel.
// Transformations.SwitchMap in the ViewModel will notice the change and
// fetch data from the model.
override fun onTextDialogResult(input: String) {
viewModel.setData(input)
}
// Update the TextView value
private fun updateUI(data: String) {
textView.text = data
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment