Templato - An Example Android App

3 minute read

I recently updated my templato-android repository to the latest Android API’s. Which to me warrants a blog post because it means I care enough about the project to keep it updated - which means a lot.

Templato

The app, which I call Templato was initially built as a template Android application, but since then I’ve re-categorized it in my head as an example app.

The distinction?

A template app might be seen as more of a white label solution for releasing a bunch of re-skinned apps, but Templato doesn’t do that much. To me, it’s more of a reference point for the boiler plate in a simple 3-tabbed app if I were build one today.

The goal is to keep that ‘today’ up to ‘today’. If I would start an similar Android app differently in two months from now and Templato is still the same, then I’m letting the project down.

What does Templato have?

Templato includes a few boiler plate classes and layouts you can build from or refer to:

Project Layout

The basic Templato layout:

templato project layout java classes

MainActivity

The MainActivity essentially just contains the navigation for the app, managed using the ViewModel and LiveData.

Navigating using the toolbar responds to this listener.

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    // Let the ViewModel handle the navigation so it can be exposed to other fragments
    switch (item.getItemId()) {
        case R.id.navigation_home:
        case R.id.navigation_dashboard:
        case R.id.navigation_notifications:
            viewModel.setCurrentFragmentId(item.getItemId());
            return true;
    }
    return false;
}

Which is just setting state in the ViewModel, to which the Activity (and potentially the Fragments) respond.

viewModel.getCurrentFragmentId().observe(this, new Observer<Integer>() {
  @Override
  public void onChanged(@Nullable Integer fragmentId) {
      if (fragmentId != null) {
          switch (fragmentId) {
              case R.id.navigation_home:
                  moveToHomeFragment();
                  break;
              case R.id.navigation_dashboard:
                  moveToDashboardFragment();
                  break;
              case R.id.navigation_notifications:
                  moveToNotificationsFragment();
                  break;
          }
      }
  }
});

MainViewModel

The ViewModel just contains LiveData to manage the current Fragment ID, Name, and my list of dummy Notifications to fill the RecyclerView.

public class MainViewModel extends ViewModel {

    private MutableLiveData<Integer> currentFragmentId;
    private MutableLiveData<String> currentFragmentTitle;
    private MutableLiveData<List<Notification>> notifications;

    //...

}

While this ViewModel currently just has a method to mock out this dummy data, my normal ViewModels will often connect to some Module POJO to get and update LiveData from the network or database, etc.

Fragments

The HomeFragment and SettingsFragments are just stubs for a view with placeholder text that changes based on changes observed on the LiveData in the ViewModel.

The NotificationsFragment is essentially a RecyclerView that is populated based on my List of Notifications in the ViewModel

private void setupObservers() {

    //...

    viewModel.getNotifications().observe(getActivity(), new Observer<List<Notification>>() {
        @Override
        public void onChanged(@Nullable List<Notification> notifications) {
            if (notifications != null && adapter != null) {
                adapter.setNotifications(notifications);
            }
        }
    });
}

The RecyclerView uses the NotificationsRecyclerViewAdapter and it’s NotificationsViewHolder inner class. In addition to setting up each item view, it contains a callback method to react to users clicking on notifications.

/**
 *
 * Recycler View Interaction Callback
 */
public interface NotificationRecyclerViewCallback {
    void onNotificationRowTapped(int index);
}

Up Next?

Besides keeping everything up to date, I hope to add a bit to this template if it proves useful.

  • Create Network module and use Retrofit to make calls to an open API
  • Add UI’s to Home and Settings Fragments
  • Create Android UI and Unit tests

Contributing?

The main way for you to contribute is for you to tell me I did what I did wrong, and explain to me why. There’s no one way to build an Android app, and I don’t presume to have the best way, but if we can make this better let me know.

I’ll consider PR’s if they’re thoughtfully improving the application and explain why.

If you just want to discuss, hit me up @ajkuterman