A collection of samples to discuss and showcase different architectural tools and patterns for Android apps.
Clone or download
JoseAlcerreca and florina-muntenescu Adds Room to todo-mvvm-live and updates versions (#459)
* Update todo-mvp README.md

Refactored the content around a new structure, with new standard titles used for each sample
Fixed various grammar issues
Applied formatting
Additional explanations and links where appropriate
Introduced pre-requisite topics

* Update README.md

Removed a redundant sentence.

* copies Firebase Test Lab results to CIRCLE_TEST_REPORTS

* Replaced deprecated attribute

* Bumps versions and fixes annotation imports

* Fixes toolbar title not being persisted after rotation

* Fixes navigation issue #287

* Bumps circle CI Android dependencies

* Fixes comment in test

* Bumps versions in travis.yml

* Moving the setting of the AddEditTaskPresenter in the constructor.
Tests added to check that the presenter is set to the view.

* Removing the `_id` column and making `entryid` primary key.
Moved the `TasksLocalDataSourceTest` to correct package.

* First commit: MPV with Room

* Readme updated

* Readme updated

* Fixing CI

* Fixing tests for local repository

* Using Idling resources for tests, for commands that are executed on the background thread

* comments updated

* Fixed Firebase Test Lab script

* fix typo in androidTest

* Fix typo (#415)

- Change "compliment" to "complement"

* Fixed the typo (#425)

* Tries to fix circle adding google repo

* Buildtools 26 is mandatory now, apparently

* More CI fixes

* CI caught some merge errors + circle fix

* Updates todo-mvvm-databinding with changes from todo-mvp (#437)

* Update todo-mvp README.md

Refactored the content around a new structure, with new standard titles used for each sample
Fixed various grammar issues
Applied formatting
Additional explanations and links where appropriate
Introduced pre-requisite topics

* Update README.md

Removed a redundant sentence.

* copies Firebase Test Lab results to CIRCLE_TEST_REPORTS

* Replaced deprecated attribute

* Bumps versions and fixes annotation imports

* Fixes toolbar title not being persisted after rotation

* Fixes navigation issue #287

* Bumps circle CI Android dependencies

* Fixes comment in test

* Bumps versions in travis.yml

* Moving the setting of the AddEditTaskPresenter in the constructor.
Tests added to check that the presenter is set to the view.

* Removing the `_id` column and making `entryid` primary key.
Moved the `TasksLocalDataSourceTest` to correct package.

* Fixed Firebase Test Lab script

* Tries to fix circle adding google repo

* Buildtools 26 is mandatory now, apparently

* More CI fixes

* CI caught some merge errors + circle fix

* Fixed Firebase Test Lab script (#440)

* Updates room branch to API 26, Espresso, Arch Components

* Adds google m2 repository

* Adding google() to repositories

* Reverts to todo-mvp's README

* No need for LicecycleActivities now
Latest commit 6419d4c Nov 10, 2017

README.md

todo-mvvm-live

This version of the app is called todo-mvvm-live, and it uses some Architecture Components like ViewModel, LiveData, and other lifecycle-aware classes. It's based on the todo-mvvm-databinding sample, which uses the Data Binding Library to display data and bind UI elements to actions.

What you need

Before exploring this sample, you should familiarize yourself with the following topics:

Implementing the app

Although the parent sample already used ViewModels, as it was following an MVVM architecture, the Architecture Components have different restrictions by design.

In the MVVM architecture, Views react to changes in the ViewModel without being explicitly called. However, the MVVM architecture presents some challenges when working with some Android components.

Live events

A new SingleLiveEvent class is created, which extends MutableLiveData so it's lifecycle-aware. It's used for communication between ViewModels and UI views (activities and fragments).

Instead of holding data, it dispatches data once. This is important to prevent events being fired after a rotation, for example.

A convenient use for this is navigation. There is no reference to the View from a ViewModel so the communication between them must happen via a subscription. ViewModels expose events like openTaskEvent and views subscribe to them. For example:

private void subscribeToNavigationChanges(TaskDetailViewModel viewModel) {
    // The activity observes the navigation commands in the ViewModel
    viewModel.getEditTaskCommand().observe(this, new Observer<Void>() {
        @Override
        public void onChanged(@Nullable Void _) {
            TaskDetailActivity.this.onStartEditTask();
        }
    });
    viewModel.getDeleteTaskCommand().observe(this, new Observer<Void>() {
        @Override
        public void onChanged(@Nullable Void _) {
            TaskDetailActivity.this.onTaskDeleted();
        }
    });
}

Snackbar

To show a Snackbar, you must use a static call to pass a view object:

Snackbar.make(View coordinatorLayout, String text, int length).show();

A ViewModel, however, doesn't have the necessary reference to the view hierarchy. Instead, you can manually subscribe the snackbar to a Snackbar event. In this case the subscription is made to a SnackbarMessage which extends a SingleLiveEvent and takes a string resource ID (an integer). There's only one snackbar and there should only be one active observer at a time. Messages are only shown once.

TasksAdapter

There is no TaskItemViewModel in this branch for each particular item in the list, so tasks in the list only communicate with the list's ViewModel.

Using ViewModels in bindings with the Data Binding Library

ViewModels are used to show data of a particular screen, but they don't handle user actions. For that it's much more convenient to create user actions listeners or even presenters that hold no state during configuration changes and hence are easy to recreate. See TaskItemUserActionsListener for an example.

Repository does not use LiveData

For simplicity and similarity with the parent branch, the repository does not use LiveData to expose its data.