読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

Fragment,Android間の通知_2

Android

概要

FragmentとActivity間の通知についてまとめる
今回はViewPagerなどで自動的に作成されるFragmentからActivityにイベントを通知する方法などについて

詳細

ViewPageerに設定されたFragmentを取得するにはgetItem()を使っては×
ダメなコード

public class MainActivity extends ActionBarActivity {

    MainFragment mMainFragment;

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

        ViewPager pager = (ViewPager)findViewById(R.id.pager);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
    }


    public class MyPagerAdapter extends FragmentPagerAdapter {

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int i) {
            switch (i) {
                case 0:
                    return (mMainFragment = new MainFragment());
            }
        }

        @Override
        public int getCount() {
            return 1;
        }
    }
}

これは画面回転などシステムからFragmentが再生成された時getItemメソッドに入らないため、mMainFragmentがnullになり、nullPointerExceptionになる
FragmentPagerAdapterは各ページに対応するFragmentがすでに誠意性さあれている場合、getItemメソッドを呼ばずにそれらのインスタンスを再利用する、システムからの復帰時にはFragmentが自動で再生成されるためgetItemメソッドは呼ばれない

...なのでどうしたらいいかというと、Fragmentのインスタンスを保持する

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if(mMainFragment != null) {
            getSupportFragmentManager().putFragment(outState, "main_fragment", mMainFragment);
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if(mMainFragment == null) {
            mMainFragment = (MainFragment) getSupportFragmentManager().getFragment(savedInstanceState, "main_fragment");
        }
    }

putFragmentはFragmentにタグをつけて保存しているようなイメージ
これによりシステムによりFragmentが破棄された後もfragmentインスタンスを取得できる

参考

tatsu-zine.com