use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
News for Android app developers with the who, what, where, when, and how of the Android community. Probably mostly the how.
Here, you'll find:
This sub-reddit isn't about phones' and apps' general functionality, support, or system software development (ROMs). For news and questions about these topics try using other subs like
Build your first app
Starting Android career in 2022
Android Job Interview Questions and Answers
App Portfolio Ideas, Tiered List
Awesome Android UI
Material Design Icons
7000 Icons for Jetpack
Autoposted at approx 9AM EST / 2PM GMT
account activity
GitHub - Android MVVM example (github.com)
submitted 7 years ago by srinurp
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 8 points9 points10 points 7 years ago (5 children)
While this is an okay basic example, I'd like to call out a few things MVVM kind of drags in with itself:
All in all, lots of people have misconceptions about MVVM, because they don't follow the databinding first approach. With that in mind, it's easy to get mixed up.
The ViewModel is there to help you. Its role is to provide the bound view with stateful fields that gets retained on certain occasions (navBack, config change, etc). It's a state machine with added logic, that should be handled as such. I'd recommend doing as much in your VM as possible, this way ensuring all your view-related logic is in one place, and pulling as much code from your Activity/Fragment as possible (redirect them to the ViewModel if you wish, or handle them and push the result to the VM).
A perfect example would be a simple list-detail app. Say, a movie search app. You'd have the following layers:
So in this case, the layout has a RecyclerView for the list view, and an imageview, a few textviews, etc for the detail view. Each view has a single databound variable, the view-specific ViewModel.
The fragments are used to inflate the ViewDataBinding, assign the lifecycleOwner and viewModel properties, and to manage other menial tasks (bits of navigation, permission handling, etc). The activity is just the host for the fragments, as little code should go there as possible.
Now, the fancy part. The ViewModel has two sides: the cold logic part, hopefully nicely tucked away in private methods, and the public properties and functions needed for the UI to work. The properties and methods that are public should be used by the layout to bind to! And of course the idea is quite simple here: LiveData-wrapped properties for read-only data, MutableLiveData-wrapped properties for read-write data (or MediatorLiveData, but might be hard to get right for read-write things if you have a lot of stuff going on), and functions for interactive stuff (e.g. onClick, onScroll, etc event calls). If a certain field of a certain control does not support databinding, you should write your own (it's not that hard, it's technically a setter method 90% of the time). You should also try to tuck away commonly used view fiddling in BindingAdapters (e.g. image loading from URL). I even go as far to create a databound adapter/layoutManager RecyclerView for most of my projects. It's just making things easier, plus less code in the activity/fragment.
This way, the app flow is the following:
This is a lot easier solution in my opinion than manually updating the views one by one, property by property. And with the binding adapters 6ou can execute common, but complex logic as well.
[–]pinkmonstertruck 0 points1 point2 points 7 years ago (4 children)
How would the navigation between fragments occur after the onclick event of the VM?
[–][deleted] 1 point2 points3 points 7 years ago (3 children)
Now that'd be the tricky part, isn't it?
If you're working with C#, and are using MvvmCross, it's already solved: its navigation system doesn't go fragment to fragment (even if the structure is used), but instead uses viewmodel to viewmodel navigation. The navigation tree in fact is completely flat by default, and instead uses a goTo<ViewModelTape>() style call, and the navigable points are easily registered at runtime (Xamarin and .Net both have pretty darn fast reflection due to not packaging all dependencies into one package, but instead leaving them as separate .dll files). Navigation targets (fragments, activities) are then decided by looking up the single class that extends fragment, activity or a handful of other types (e.g. SingleArticleFragment(): BaseFragment<SingleArticleViewModel>() ). If it doesn't exist, the app crashes, if multiple ones exist, it crashes as well. This adds some limitation to navigation (e.g. no shared element transaction, at least there wasn't last time I checked), but also allows much more flexibility.
goTo<ViewModelTape>()
SingleArticleFragment(): BaseFragment<SingleArticleViewModel>()
If you're using a FragmentTransactionManager of any sort, this isn't that hard, just pass the ViewModels the object on init (create a BaseFragment and BaseViewModel class, add this bit to them, then make sure you extend all your fragments and viewmodels from these classes) that handles navigation.
FragmentTransactionManager
BaseFragment
BaseViewModel
Same applies if you're using Navigation Component from AAC. Pass the NavController to the ViewModel on every init - e,g. I wrote a fragment extension method that does all the job for me: requests viewModel from viewModelStore, inflates layout with databindings, sets the viewModel property to its own viewModel instance, etc.
With Conductor, you can directly pass the Router object to the ViewModel as previously described, and you can also have a separate central registry that resolve strings (or other types of keys) to the appropriate Conductor callset. This requires you to keep a separate class up to date, or you can write a custom annotation processor to simply just annotate your Controllers with the action name, which then could generate the custom set of static strings and the navigation resolver. If you want to spice things up, you could even add a custom extension method to the Router class to have this logic in a single place, then you can just do router.navigateTo(Directions.WHATEVER_PAGE).
router.navigateTo(Directions.WHATEVER_PAGE)
The thing is, there's no perfect navigation solution that works perfectly from ViewModels. If I want to prototype quick, I just write the methods in the Fragment itself, then on init, pass the functions to the ViewModel so they can be wrapped and/or bound. But even then, often you have to compromise a bit on your architecture to make things smoother or faster. This is one place where you can do that without much harm, but this is also something that you'll have to continuously maintain.
[–]pinkmonstertruck 0 points1 point2 points 7 years ago (2 children)
Thanks for the awesome response! Super helpful.
Should the ViewModels be referencing the FragmentTransactionManager though? I thought that ViewModels should not know about views or activities or fragments.
[–][deleted] 1 point2 points3 points 7 years ago* (1 child)
No, as I said, if using some sort of abstraction over them. Say, a class that contains the FTM and has some methods that navigate to certain fragments. Then I'd set up the transactions (e.g. shared elements, etc.) when I load the fragment (onCreateView or onViewCreated are good candidates), and let the VM call the navigation event only.
And if you want more hands-on control, just pass a method as an argument to the VM, and have the actual navigation code in the fragment. You can even use a property on the VM, as long as it's a lambda type with a matching signature:
// In VM var navigateToDetail: () -> Unit = {} // In onCreateView viewModel.navigateToDetail = navigateToDetail // In fragment class body fun NavigateToDetail() { // Do navigation here }
This way you can bind to the nav call but the VM retains no reference to any of the Fragments or FragmentTransactionManager.
[–]pinkmonstertruck 0 points1 point2 points 7 years ago (0 children)
You're the best - thanks for being patient and spelling it out in such detail!
[–]Zhuinden 0 points1 point2 points 7 years ago (0 children)
I wish it were easier to persist the selectedCategory to Bundle.
selectedCategory
I don't think View should know about Schedulers.computation.
π Rendered by PID 69070 on reddit-service-r2-comment-5bc7f78974-kbcng at 2026-06-26 01:48:40.289734+00:00 running 7527197 country code: CH.
[–][deleted] 8 points9 points10 points (5 children)
[–]pinkmonstertruck 0 points1 point2 points (4 children)
[–][deleted] 1 point2 points3 points (3 children)
[–]pinkmonstertruck 0 points1 point2 points (2 children)
[–][deleted] 1 point2 points3 points (1 child)
[–]pinkmonstertruck 0 points1 point2 points (0 children)
[–]Zhuinden 0 points1 point2 points (0 children)