ViewModel で持ってる LiveData を Activity で observe してるとする。
- class MainActivity : AppCompatActivity() {
- private val viewModel: MainViewModel by viewModels()
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- viewModel.state.observe(this) {
- when (it) {
- is State.Data -> {
- println(it.value)
- }
- State.Loading -> {
- }
- }
- }
- }
- }
- class MainViewModel : ViewModel() {
- private val _state = MutableLiveData<State>()
- val state: LiveData<State>
- get() = _state
- fun doSomething() {
- val state = _state.value
- if (state is State.Data) {
- state.mutableValue = Random.nextInt()
- }
- }
- }
- sealed class State {
- object Loading : State()
- data class Data(val id: String) : State() {
- // 変更できるのは MainViewModel からだけにしたいが、
- // private にすると MainViewModel からも見えなくなる
- var mutableValue: Int = -1
- val value: Int
- get() = mutableValue
- }
- }
mutableValue に private は MainViewModel から見えなくなるのでダメ。
- private var mutableValue: Int = -1
- private sealed class State {
- private data class Data(val id: String) : State() {
- sealed class State
- object Loading : State()
- // MainViewModel から mutableValue は見えるが
- // Data が MainActivity からは見えなくなる
- private data class Data(val id: String) : State() {
- var mutableValue: Int = -1
- val value: Int
- get() = mutableValue
- }
ということで sealed interface を使います。
- class MainViewModel : ViewModel() {
- private val _state = MutableLiveData<State>()
- val state: LiveData<State>
- get() = _state
- fun doSomething() {
- val state = _state.value
- if (state is DataImpl) {
- state.mutableValue = Random.nextInt()
- }
- }
- }
- sealed interface State
- object Loading : State
- sealed interface Data : State {
- val value: Int
- }
- private class DataImpl(val id: Int) : Data {
- // private class なので変更できるのは同じファイルからだけ
- var mutableValue: Int = id
- override val value: Int
- get() = mutableValue
- }
0 件のコメント:
コメントを投稿