I'm trying out the new Android Architecture components and have run into a road block when trying to use the MVVM model for a custom view.
Essentially I have created a custom view to encapsulate a common UI and it's respective logic to use throughout the app. I can set up the ViewModel in the custom view but then I'd have to either use observeForever()
or manually set a LifecycleOwner
in the custom view like below but neither seem correct.
observeForever()
Activity
class MyActivity : AppCompatActivity() {
lateinit var myCustomView : CustomView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myCustomView = findViewById(R.id.custom_view)
myCustomView.onAttach()
}
override fun onStop() {
myCustomView.onDetach()
}
}
Custom View
class (context: Context, attrs: AttributeSet) : RelativeLayout(context,attrs){
private val viewModel = CustomViewModel()
fun onAttach() {
viewModel.state.observeForever{ myObserver }
}
fun onDetach() {
viewModel.state.removeObserver{ myObserver }
}
}
Activity
class MyActivity : AppCompatActivity() {
lateinit var myCustomView : CustomView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myCustomView = findViewById(R.id.custom_view)
myCustomView.setLifeCycleOwner(this)
}
}
Custom View
class (context: Context, attrs: AttributeSet) : RelativeLayout(context,attrs){
private val viewModel = CustomViewModel()
fun setLifecycleOwner(lifecycleOwner: LifecycleOwner) {
viewModel.state.observe(lifecycleOwner)
}
}
Am I just misusing the patterns and components? I feel like there should be a cleaner way to compose complex views from multiple sub-views without tying them to the Activity/Fragment
1 Option -
With good intention, you still have to do some manual work - like, calling onAttach
\ onDetach
Main purpose of Architecture components is to prevent doing this.
2 Option -
In my opinion is better, but I would say it's a bit wrong to bind your logic around ViewModel
and View
. I believe you can do same logic inside Activity/Fragment
without passing ViewModel and LifecycleOwner
to CustomView
. Single method updateData
is enough for this purpose.
So, in this particular case, I would say it's overuse of Architecture Components.