LoginSignup
1
0

More than 5 years have passed since last update.

ViewModel を使用して Android アプリを雑に回転対応する

Last updated at Posted at 2018-05-31

まじめに回転対応すると Activity が破棄されたときどうするのかとか考える必要があって面倒ですが、細かいことは置いといて雑に回転対応するのであれば ViewModel を使用すると簡単にできます。

どうやるの?

回転対応前

例えば以下のような形で回転するたびに Toast で何回目の回転か表示する Activity があったとします。


public class MainActivity extends AppCompatActivity {

    // この値を回転しても保持したい
    int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        count++;
        Toast.makeText(this, String.valueOf(count) + "回目!!", Toast.LENGTH_SHORT).show();
    }
}

このコードを実行すると何度回転しても「1回目!!」と表示されます。回転されるたびに onCreate() からすべてやり直しになって、count が初期化されてしまうためです。

回転対応後

Google が提供している Architecture Compoennts というものを入れると簡単に回転対応ができます。

app/build.gradle を以下をします。

dependencies {
    ...
    compile 'android.arch.lifecycle:extensions:1.1.1'
    ...
}

上のライブラリは google のリポジトリにしかないので以下ような感じでプロジェクトルートにある build.gradle にも変更を加える必要があります。

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}

これで Architecture Components が使えるようになった。あとは先ほどの Activity を以下のように変更するだけです。


public class MainActivity extends AppCompatActivity {

    // 保持したい変数を ↓ の ViewModel に突っ込む!
    public static class MyModel extends ViewModel {
        int count = 0;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ViewModelProviders から上で定義した Model を取り出す
        // ここで取り出した model には回転前の値がちゃんと保持されている
        MyModel model = ViewModelProviders.of(this).get(MyModel.class);
        model.count++;
        Toast.makeText(this, String.valueOf(model.count) + "回目!!", Toast.LENGTH_SHORT).show();
    }
}

回転後も保持したい変数を ViewModel というののメンバ変数にして、ViewModelProvider からそれを引っ張り出してくるだけで回転対応が完了。簡単!

もちろん Fragment でも同じような感じで対応できます。

ViewModel はちゃんとライフサイクルに応じて解放もしてくれるので、リークの心配も不要です。ただ、View や Context を ViewModel に入れるとリークするので注意が必要です。

注意すべき点として、アプリがバックグラウンドになって、ある程度放置されたときなどに Activity が破棄されることがありますが、そのときは count が初期値(このコードの場合だと 0 )に戻ってしまいます。

ここもちゃんと対応したいのであれば、saveInstanceState, Room などを使用した回転対応が必要になります。

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0