Tabbed Activity で Android の MVVM を学ぶ


はじめに

Android Studio 3.6.3でTabbed Activityを作ってみたところ、MVVMの仕込みが入っていることに気がついたので、まとめてみました。

目次

  1. Tabbed Activityのプロジェクトの新規作成
  2. ファイル構成を確認する
  3. 使用されている要素でViewーViewModelの関係を確認する

1. Tabbed Activityのプロジェクトを新規作成

まず、Android Studioの新規プロジェクトを作成します。

続けて「Tabbed Activity」を選択します。

適当に名前をつけて「Finish」します。

2. ファイル構成を確認する

作成されたプロジェクトの構成を確認します。

定義されているクラスは下の通りでした。

Class Super Class 役割
PageViewModel ViewModel 1ページのUI関連データの格納
PlaceholderFragment Fragment 1ページの画面
SectionsPagerAdapter FragmentPagerAdapter 複数ページのアダプタ
MainActivity AppCompatActivity 言わずがな

*タブで切替えされる画面をページと表現。

3. 使用されている要素でViewーViewModelの関係を確認する

3.1 ViewModel

ViewModelProvidersにPlaceholderFragment自身を渡して、Fragment毎にViewModelを保持しています。このViewModelはオーナーとなるFragmentのUIで必要となるデータをFragmentの生存期間で保持してくれます。

PlaceholderFragment.java
        pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class);

3.2 LiveData

LiveDataはobserverを備えていて、値に変更があると通知してくれます。
FragmentでtextViewにViewModelのデータをバインディングしています。

PageViewModel.java
public class PageViewModel extends ViewModel {
    ...
    private LiveData<String> mText = Transformations.map(mIndex, new Function<Integer, String>() {
        ...
    });
    ...
    public LiveData<String> getText() {
        return mText;
    }
}
PlaceholderFragment.java
    @Override
    public View onCreateView(...)
        ...
        pageViewModel.getText().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        return root;
    }

3.3 Transformations.map

Transformations.mapでは値の変更を契機に、別の値を変更できます。
mIndexの値に変更があると、mTextの値も変更されます。

PageViewModel.java
public class PageViewModel extends ViewModel {

    private MutableLiveData<Integer> mIndex = new MutableLiveData<>();
    private LiveData<String> mText = Transformations.map(mIndex, new Function<Integer, String>() {
        @Override
        public String apply(Integer input) {
            return "Hello world from section: " + input;
        }
    });
    ...
}

3.4 MutableLiveData

"Mutable"とは「可変」という意味。
LiveDataには値を変更するPublic Methodが公開されていないので、値を変更する場合はMutableLiveDataを用います。
ページが変わった時に、index

PageViewModel.java
public class PageViewModel extends ViewModel {

    private MutableLiveData<Integer> mIndex = new MutableLiveData<>();
    ...
    public void setIndex(int index) {
        mIndex.setValue(index);
    }

おわりに

Tabbed Activityのプロジェクトを新規作成するだけで、View-ViewModel間の要素が詰まっていることに驚きでした。

参考ページ

LiveData の概要
https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ja