2015.05.28
【Android SDK】Fragmentをうまく使う
使い慣れると便利ですよ。
最近のAndroidアプリはActivityを継承して作っていくのではなく
FragmentActivityを継承したもので作成していくのが基本になっている。
デフォルトではFragmentActivityを継承したActionBarActivityで作られることが多い。
Link:FragmentActivity | Android Developers
Link:ActionBarActivity | Android Developers
Activityでいいじゃんと思うわけですけど、全てがActivityに集中して
他での利用が出来なかったりと不便なところが多い。
それを解決するためにViewを分離して各画面ごとに処理を作成することで
ソースが分散されて再利用も可能になってハッピーになったという流れらしい。
いわゆるMVCになったということなのでしょう。
Link:Java Solution FAQ:MVCモデルという言葉をよく聞きますが何のことですか?
・Fragmentを継承したレイアウトの作成
Fragmentの動作を確認するならこれくらいでよい。
package com.example.frageasy; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragTest extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.frag, container, false); } }
onCreateViewをオーバーライドして表示したいViewを返せばそれが表示されます。
今回は簡単にinflateでレイアウトファイルをロードしています。
・Activityで表示を切り替える
作成したフラグメントをメインビューへ変更します。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fm; FragmentTransaction ft; FragTest fTest; fTest = new FragTest(); fm = getSupportFragmentManager(); ft = fm.beginTransaction(); ft.replace(R.id.a_frag, fTest ); ft.commit(); }
手っ取り早くActivity.onCreateで差し替えます。
まず、今回作成したフラグメントをおもむろに作成。
次にActivityが持っているFragmentManagerを取得。
FragmentManager.beginTransactionで切り替え処理の開始を宣言。
FragmentTransaction.replaceで切り替えるViewのIDと切り替えたいフラグメントを指定。
FragmentTransaction.commitで変更終了を通知。
これだけでフラグメントの切り替えは完成です。
細かい処理は新規作成したFragmentに書いていくことが出来ます。
これだけだと単なる画面の分割だけなので便利そうな機能を紹介。
FragmentTransactionの処理中に以下のものを入れる。
ft.addToBackStack(null);
さらに、Activity.onBackPressedをオーバーライドして
以下のような処理を記述。
/** * 戻るキーをおした時 */ @Override public void onBackPressed() { int backStackCnt = getSupportFragmentManager().getBackStackEntryCount(); //まだスタックあり if (backStackCnt != 0) { //BackStackに乗っているFragmentを戻す getSupportFragmentManager().popBackStack(); } else { //最後の画面まで戻ってきたらアプリ終了 super.onBackPressed(); } }
これを実行してバックボタンを押すと
1つ前の画面に戻り、終わったらアプリが終了するという
画面のスタック機能があっさりと実装出来ます。
画面がスタックされるかはFragmentTransaction.addToBackStackを呼ぶからしいので
単なる画面切り替えであれば呼ばなければスタックされずに画面切り替えだけになる。
これだけの処理で画面のスタック機能ができるのは便利ですね。
自分のハマった問題点をまとめておく。
・Fragmentのバージョンを注意すること
GoogleはFragmentへの移行を積極的に推進しているので
昔のバージョンへの対応もしている。
しかし、新しいライブラリとは別枠で作ってあるので
importを間違えたり違うバージョンでやり取りを行うとあっさりとハングします。
Fragmentだとこんな感じで分かれています。
・android.app.Fragment
Link:Fragment | Android Developers
・android.support.v4.app.Fragment
Link:Fragment | Android Developers
もっとわかりにくいのはFragmentManagerの取得方法です。
・getFragmentManager()
Link:Activity | Android Developers
・getSupportFragmentManager()
Link:FragmentActivity | Android Developers
基本的には古いバージョンでも対応ができているv4のついたほうで処理していくのがいいと思う。
だけど、今後はFragment自体にアニメーション機能とかも実装されていくみたいなので
問題ないのであればandroid.app.Fragmentをつかったほうがいいと思います。
・Fragmentのライフサイクルを理解しておくこと
FragmentのライフサイクルはActivityに似ていますが相当ピーキーな動きをします。
画面を切り替えながらonCreateViewとonDestroyViewの動きを見ていると
表示されるときにonCreateViewが呼び出されて非表示になるとonDestroyViewが呼び出されています。
なのでTextView内部に残っているテキストなどはどこかに退避しておき
再表示時に再度設定して表示しないといけない作りになっています。
外部から呼び出すイベントでTextView等を更新するときも非表示時には
View自体削除されているのでアクセスするとハングする。
こういう所も対処していかないといけない。
Fragmentをある程度理解するために相当な時間が取られてしまいました。
いかんせん作るのが面倒だけど利点も大きいので便利に使っていきたいところです。
[aws asin="477416335X"]
関連記事