Last active
December 1, 2018 09:42
-
-
Save jmatsu/536bdc7d453213b3817085c850a45484 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Application | |
import android.os.Bundle | |
import android.view.View | |
import android.widget.TextView | |
import androidx.appcompat.app.AppCompatActivity | |
import androidx.lifecycle.LiveData | |
import androidx.lifecycle.MutableLiveData | |
import androidx.lifecycle.Observer | |
import androidx.lifecycle.ViewModelProviders | |
class MainActivity : AppCompatActivity() { | |
class MainViewModel(application: Application) : ViewModel(application) { | |
val textLiveData: LiveData<String> by liveData(MutableLiveData()) | |
val mutableLiveData: LiveData<String> = MutableLiveData() | |
val crashTextLiveData: LiveData<String> by liveData(NotMutableLiveData()) | |
private class NotMutableLiveData : LiveData<String>() { | |
fun updateText(text: String) { | |
value = text | |
} | |
} | |
fun updateTextLiveData(text: String) { | |
textLiveData.mutate().value = text | |
} | |
fun updateMutableLiveData(text: String) { | |
mutableLiveData.mutate().value = text | |
} | |
fun updateCrashTextLiveDataSafely(text: String) { | |
(crashTextLiveData as NotMutableLiveData).updateText(text) | |
} | |
fun crash(text: String) { | |
crashTextLiveData.mutate().value = text | |
} | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
val textView = findViewById<TextView>(R.id.hello) | |
val textView1 = findViewById<TextView>(R.id.hello1) | |
val textView2 = findViewById<TextView>(R.id.hello2) | |
val vm = ViewModelProviders.of(this).get(MainViewModel::class.java) | |
vm.textLiveData.observe(this, Observer { | |
textView.text = "textLiveData:$it" | |
}) | |
vm.mutableLiveData.observe(this, Observer { | |
textView1.text = "textLiveData:$it" | |
}) | |
vm.crashTextLiveData.observe(this, Observer { | |
textView2.text = "crashTextLiveData:$it" | |
}) | |
findViewById<View>(R.id.helloButton).setOnClickListener { | |
vm.updateTextLiveData("hello!") | |
} | |
findViewById<View>(R.id.hello1Button).setOnClickListener { | |
vm.updateMutableLiveData("hello1") | |
} | |
findViewById<View>(R.id.hello2Button).setOnClickListener { | |
vm.updateCrashTextLiveDataSafely("hello2") | |
} | |
findViewById<View>(R.id.crash).setOnClickListener { | |
vm.crash("crash...") | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Application | |
import androidx.annotation.CallSuper | |
import androidx.lifecycle.AndroidViewModel | |
import androidx.lifecycle.LiveData | |
import androidx.lifecycle.MutableLiveData | |
import androidx.lifecycle.Observer | |
open class ViewModel(application: Application) : AndroidViewModel(application) { | |
protected fun <T> LiveData<T>.mutate(): MutableLiveData<T> { | |
return when (this) { | |
is LiveDataWrapper -> this.wrappedLiveData | |
is MutableLiveData -> this | |
else -> throw IllegalArgumentException("the given live data is not wrapped. Please use liveData delegation at declarations.") | |
} | |
} | |
protected inline fun <reified T> lazyLiveData(crossinline initializer: () -> LiveData<T>): Lazy<LiveData<T>> { | |
return lazy { | |
val liveData = initializer() | |
if (liveData is MutableLiveData) { | |
LiveDataWrapper(liveData) | |
} else { | |
liveData | |
} | |
} | |
} | |
protected inline fun <reified T> liveData(liveData: LiveData<T>): Lazy<LiveData<T>> { | |
return lazyOf( | |
if (liveData is MutableLiveData) { | |
LiveDataWrapper(liveData) | |
} else { | |
liveData | |
} | |
) | |
} | |
protected class LiveDataWrapper<T>(val wrappedLiveData: MutableLiveData<T>) : LiveData<T>() { | |
private val observer: Observer<T> = Observer { super.setValue(it) } | |
@CallSuper | |
override fun onActive() { | |
wrappedLiveData.observeForever(observer) | |
} | |
@CallSuper | |
override fun onInactive() { | |
wrappedLiveData.removeObserver(observer) | |
} | |
override fun postValue(value: T) { | |
wrappedLiveData.postValue(value) | |
} | |
override fun setValue(value: T) { | |
wrappedLiveData.value = value | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment