ボクココ

個人開発に関するテックブログ

Android の ViewPager で使う Fragment の注意点

Android アプリ開発で便利な ViewPager . 画面のスワイプが簡単に実装できるのでどんなアプリを作るにも役立つ。

これはFragmentを使っていて、今回そのFragment周りを中心にどう実装するのかをまとめる。

ViewPager に FragmentStatePagerAdapter を setAdapter

これがまず基本。 FragmentStatePagerAdapter を継承したクラスを作り、

   @Override
    public Fragment getItem(int i) {
    }

ここに作った各Fragmentを返すように作ってあげる。 詳細は他に任せるとして、今回はこのFragment のライフサイクル的なのをまとめたい。

ライフサイクルの使い分け

まずは典型? と思われるコードを書く。

public class BoardFragment extends Fragment {
    private static BoardFragment boardFragment;

    public static BoardFragment getInstance() {
        if (boardFragment == null) {
            boardFragment = new BoardFragment();
        }
        return boardFragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_board, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 1
    }

    @Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (visible && isAdded()) {
            // 2
        }
    }
}

getInstance()

シングルトンにするケースが多いみたい。

onCreateView

ここで使うレイアウトを指定する。

onViewCreated

ここで view.findViewById で各要素が取って来れる。 この処理内での呼び出しであれば、 getActivity() が問題なく取って来れる。 自分はActivityでいうonCreate に該当する処理をここで書いている。

setMenuVisibility

今回の落とし穴。 自分はここで onResume() 的な処理を書いていた。例えば2つのFragmentA, FragmentBがあったとして、FragmentAの値を更新した後にそのままFragmentBに移ったときに FragmentAの更新した内容をFragmentBでも反映させる必要があった場合など使える。 注意点としてisAdded() は、 Activityが対象Fragment をアタッチしたかどうかを返すので、falseだったら setMenuVisibility内の getActivity() の呼び出しは null が返ってくる。ここのifは重要。

んで、 View の処理を setMenuVisibilityだけに書くと、このisAdded()がfalseを返したときに処理が何も走らない、ということが起きる場合がある。

これを回避するためにも、Viewの処理、特にgetActivity()でアクティビティやコンテキストが欲しい場合はonViewCreated にその処理を書かないといけない。

所感

Fragment は難しい。。 Fragment に関する本とかが出始めているようだ。 これからのAndroidアプリ開発にFragmentの知識は切っても切れないので頑張って学んでいくしかない。