Fragmentを勉強する - part2
今回も前回の続きでFragmentに関しての覚え書きです。今回はここから
Managing Fragment
Fragmentを管理するにはFragmentManagerを使用する。Activity#getFragmentManager()でFragmentManagerを取得する
FragmentManagerで出来る事の例
-
- FragmentManager#findFragmentById()やFragmentManager#findFragmentByTag()でFragmentを取得する
- FragmentManager#popbackStack()でback stackからFragmentを取得する(Back keyで戻る行為と同じ)
- FragmentManager#addOnBackStackChangedListener()でback stackのlistenerを登録する
Performing Fragment Transactions
-
- 1回のcommitでやりとりされる変更をtransactionと呼ぶ
- 1つのtransactionにFragmentに対する変更をFragmentTransaction#add(), FragmentTransaction#remove(), FragmentTransaction#replace()といったmethodでまとめる事が出来る
- UserがBack keyで以前の状態に戻るにはFragmentTransaction#commit()をする前にFragmentTransaction#addToBackStack()を呼ぶ
//FragmentとFragmentTransactionを生成する Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); //fragment_container viewにあるFragmentを生成したFragmentで入れ替えて //このreplace transactionをback stackに追加する transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // transactionをcommitする transaction.commit();
-
- いくつかの変更を追加したtransactionをcommitする前にback stackに追加するとBack keyで加えられた変更が一気に巻き戻される
- Transactionに変更を加える順番は影響しない。ただし、ひとつの親viewに複数のFragmentが付加される場合はaddされた順番でview hierarchyに現れる
- Fragmentをremoveするtransactionをcommitする前にback stackに登録しなければ、そのtransactionがcommitされると、そのFragmentはdestroyされる。一方、登録されたFragmentはstopされる
- Transaction毎にFragmentTransaction#setTransition()でFragmentのAnimationをすることが出来る
- Transactionは即座には実行されず、UI threadが実行可能になった際に実行される。即座に実行したい場合はFragmentManager#executePendingTransactions()を呼ぶ
- commitはActivityがonSaveInstanceState()が呼ばれる前に実行されなければいけない。状態を残さずにcommitしても良い場合はFragmentTransaction#commitAllowingStateLoss()で実行する
Communicating with the Activity
FragmentはActivityから独立しているがActivityと直接のつながりがある
//現在つながりのあるActivityを取得するにはFragment#getActivity()を呼ぶ
View listView = getActivity().findViewById(R.id.list);
//逆にActivityからFragmentを取得するには
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
Creating event callbacks to the activity
Activityとeventを共有したい場合はcallback interfaceを定義しActivityに実装させる
1. Interfaceを宣言する
public static class FragmentA extends ListFragment { ... // Activityがこのinterfaceを実装する public interface OnArticleSelectedListener { public void onArticleSelected(Uri articleUri); } ... }
2. Fragment#onAttach()で渡されるActivityをListener登録する
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnArticleSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); } } ... }
3. Eventを取得したらListener登録されたActivityに通知する
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l, View v, int position, long id) { Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id); //EventをListener登録されたActivityに通知 mListener.onArticleSelected(noteUri); } ... }
Adding items to the Action Bar
FragmentはOptionMenu(結果的にはAction Bar)にMenu itemを追加する事が出来る
-
- Fragment#onCreate()でFragment#setHasOptionsMenu()を呼び、設定を行う
- Fragment#onCreateOptionsMenu()で実装を行う
Fragment内のViewに対してFragment#registerForContextMenu()でContext menuを提供する様出来る
*ただし、Menu itemに対するcallbackはActivityが始めに受け取り、Activityで処理を完結しなかった時のみFragmentに通知される
Handling the Fragment Lifecycle
Fragmentのlife cycleはActivityのlife cycleと似ている
-
- Resumed
Fragmentが実行中のActivity内で表示される時
-
- Paused
他のActivityが全面に出ているが、FragmentをhostするActivityが見えている状態になった時
-
- Stopped
HostのActivityがstopしたか、FragmentがActivityからback stackに登録されremoveされた時
また、Activityと同様にFragment#onSavedInstanceState()で状態をBundle objectに保存することが出来る
Coordinating with the activity lifecycle
基本的にはActivityのcallbackが呼ばれた際にはFragmentの同じ様なcallbackが呼ばれる。ただし、Fragmentには追加で下記のcallbackが用意されている
-
- onAttach()
FragmentがActivityと結び付けられた時
-
- onCreateView()
FragmentのView hierarchyを作る時
-
- onActivityCreated()
Activity#onCreate()が終了した時
-
- onDestroyView()
FragmentのView hierarchyが取り除かれる時
-
- onDetach()
FragmentがActivityとの結び付けを解除された時
Fragmentに関連したcodeはここ
HashTag #Android, #Java, #Fragment, #FragmentManager, #FragmentTransaction