Android: Fragmentを使って、画面の向きの変更時にデータを保持する
Created at Sun, Oct 9, 2016onSaveInstanceState
, onRestoreInstanceState
を使う方法もありますが, 今回はFragmentを使う方法を紹介します.
サンプルコードは https://github.com/satoshun-example/AndroidRetainData にあります.
ユースケース
ネットワークはコストが掛かるので, 1度データを取得したら, 画面回転でアクティビティが再生成されたとしてもデータを使いまわしたい, というケースがあるとします.
やり方
まず, データを保持するFragmentを定義します.
最初にonCreateで, setRetainInstance(true)をコールします.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
refresh();
}
次に, refreshでデータを取得します. ここではRxJava2 + Retrofitを使っています.
void refresh() {
disposables.clear();
disposables.add(provideGithubAPI()
.getRepositories("satoshun")
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
data -> subject.onNext(data),
e -> subject.onError(e)));
}
APIコールをして, 取得したデータをBehaviorSubject(subject)に与えます.
最後にobservableメソッドを定義し, データソース(subject)を他のオブジェクトからアクセス出来るようにします.
Observable<List<Repo>> observable() {
return subject;
}
Fragmentのフルソースコードはここにあります.
次に, Activityの準備をします. ActivityのonCreateでデータFragmentを使うようにするだけです.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataFrag = (RetainFragment) getSupportFragmentManager().findFragmentByTag("data");
if (dataFrag == null) {
dataFrag = RetainFragment.newInstance();
getSupportFragmentManager()
.beginTransaction()
.add(dataFrag, "data")
.commit();
}
// ここで, データFragmentからデータを取得する!!
disposables.add(dataFrag.observable()
.subscribe(
data -> {
binding.swipe.setRefreshing(false);
repoAdapter.addRepos(data);
},
e -> {
binding.swipe.setRefreshing(false);
Log.e("onDataSource", e.getMessage());
}));
}
Activityのフルソースコードはここにあります.
これで, データFragmentで取得したデータを使いまわせます!
まとめ
FragmentはUIだけでなく, データオブジェクトとしても有能.