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
To answer your question, No, It is not mandatory to use LiveData always inside ViewModel, it is just an observable pattern to inform the caller about updates in data. If you have something which won't be changed frequently and can be accessed by its instance. You can completely ignore wrapping it inside LiveData.
ViewModel allows the app's data to survive configuration changes. In this codelab, you'll learn how to integrate LiveData with the data in the ViewModel . The LiveData class is also part of the Android Architecture Components and is a data holder class that can be observed.
You usually create an Observer object in a UI controller, such as an activity or fragment. Attach the Observer object to the LiveData object using the observe() method. The observe() method takes a LifecycleOwner object. This subscribes the Observer object to the LiveData object so that it is notified of changes.
Why should you initialize and store LiveData in your ViewModel instead of a UI Controller? Both the ViewModel and LiveData are lifecycle aware. To ensure that the LiveData isn't destroyed when the UI Controller is destroyed. To hide or separate implementation details making your app more flexible.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With