LoginSignup
26
26

More than 5 years have passed since last update.

Fragment の追加や削除をやりやすい PagerAdapter を作りました

Last updated at Posted at 2015-11-18

FragmentStatePagerAdapter の欠点

Android Support Library に含まれている FragmentStatePagerAdapter は ViewPager を用いたナビゲーションを実装する上でよく利用されるAPIです。

Fragment に bind したいデータのコレクションを管理させて、 Fragment のインスタンスを作らせるパターンが多いのではないでしょうか。

しかしそんな FragmentStatePagerAdapter ですが、任意の位置の Fragment を削除が難しい問題がありました。

ググると 色々情報が出てきますが、わりとよく見つけられたのが以下のパターン。

public int getItemPosition (Object object) {
    return PagerAdapter.POSITION_NONE;
}

確かにこうしておけば、 PagerAdapter#notifyDataSetChanged() を呼んだときに表示されている Fragment が消えてくれるますが、この方法ではキャッシュされている Fragment が全て破棄されるため Fragment の再生成や描画で割りと処理が重たくなってしまいました。

この問題に対応をするため、今回あらたなライブラリを作りました。

numa08/dynamicfragmentpageradapter

使い方

リポジトリの中のサンプルも見て頂きたいのですが、まずは依存関係を追加します。

compile 'net.numa08:dynamicfragmentpageradapter:0.6'

次にアダプターの実装を行ないます。 v4-support 向けの .support.DynamicFragmentStatePagerAdapter と、普通の Fragment 向けの DynamicFragmentStatePagerAdapter があります。


public class HeikeFragmentAdapter extends DynamicFragmentStatePagerAdapter {

    // bind したいデータのコレクション
    private final List<Heike> heikeList;

    public HeikeFragmentAdapter(FragmentManager fm, List<Heike> heikeList) {
        super(fm);
        this.heikeList = heikeList;
    }

    // Fragment のインスタンスの生成
    // 作られた Fragment は勝手にキャッシュされるので、何も考えずにインスタンスを作ればおk
    @Override
    public Fragment getItem(int position) {
        return HeikeFragment.newInstance(heikeList.get(position));
    }

    // タブとかと併用する場合はタイトルを返すと良い
    @Override
    public CharSequence getPageTitle(int position) {
        return heikeList.get(position).getName();
    }

    @Override
    public int getCount() {
        return heikeList.size();
    }

    // revemoItem では指定された position のデータを消してあげる
    @Override
    public void removeItem(int position) {
        heikeList.remove(position);
        super.removeItem(position);
    }
}

Fragment を削除するには、

final int position = mainPager.getCurrentItem();
adapter.removeItem(position);

な感じで removeItem を呼んで下さい。 notifyDataSetChanged は不要です。

こういう感じで、真ん中のタブだけを削除するUIの実装が可能になります。

今後の展開

FragmentStatePagerAdapter 相当の物はできたので次は FragmentPagerAdapter 相当のやつを作りますね。

26
26
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
26