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を追加する事が出来る

    1. Fragment#onCreate()でFragment#setHasOptionsMenu()を呼び、設定を行う
    2. Fragment#onCreateOptionsMenu()で実装を行う

Fragment内のViewに対してFragment#registerForContextMenu()でContext menuを提供する様出来る

*ただし、Menu itemに対するcallbackはActivityが始めに受け取り、Activityで処理を完結しなかった時のみFragmentに通知される



Fragment callbacks

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