web-dev-qa-db-ja.com

FragmentStatePagerAdapterを使用してViewPagerからアイテムを動的に削除します

このトピックに関してはかなりの数の議論があります

私はさまざまな解決策を試しました(POSITION_NONEによる無効化を含む)。しかし、私はまだアイテムを適切に削除する方法を知りません。

何が起こるか

  • 空白のページが表示されます(フラグメントは破棄されましたが、instantiateItemは置換のために呼び出されませんでした)
  • または、おそらくAndroidがフラグメントインスタンスを管理する方法が、arraylist/sparsearrayにそれらを保持する方法と一致しないために全体がクラッシュします。

これが私のアダプタです

private class DatePickerPagerAdapter extends FragmentStatePagerAdapter {

    ArrayList<Fragment> registeredFragments = new ArrayList<Fragment>();

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

    @Override
    public Fragment getItem(int position) {
        return CreateWishFormDatePaginationFragment.newInstance(position);
    }

    @Override
    public int getItemPosition(Object object){ //doesnt change much.. 
        return PagerAdapter.POSITION_NONE;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.add(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, registeredFragments.get(position));
    }

    public void removePage(ViewGroup pager, int position) {
        destroyItem(pager, position, null);
        registeredFragments.remove(position);
        iPageCount--;
        pagerIndicator.notifyDataSetChanged();
        pagerAdapter.notifyDataSetChanged();
    }

    public void addPage() {

        iPageCount++;
        pagerIndicator.notifyDataSetChanged();
        pagerAdapter.notifyDataSetChanged();
    }
}

ViewPagerIndicatorでビューページャーを使用していますが、たとえば、その間にあるページを削除できるようにしたいです。

したがって、ViewPagerでフラグメントの追加と削除を処理する適切な方法は何ですか?

ありがとう!

11
Orkun Ozen

ViewPagerからアイテムを削除する場合、次のコードは意味がありません。

@Override
public Fragment getItem(int position) {
    return CreateWishFormDatePaginationFragment.newInstance(position);
}

基本的に、Fragmentに基づいてpositionを作成します。どのページを削除しても、positionの範囲は[0、iPageCountから[0、iPageCount-1、これは常に最後のFragmentを削除することを意味します。


必要なのは多かれ少なかれ次のとおりです。

public class DatePickerPagerAdapter extends FragmentStatePagerAdapter
{
    private ArrayList<Integer> pageIndexes;

    public DatePickerPagerAdapter(FragmentManager fm) {
        super(fm);
        pageIndexes = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            pageIndexes.add(new Integer(i));
        }
    }

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

    @Override
    public Fragment getItem(int position) {
        Integer index = pageIndexes.get(position);
        return CreateWishFormDatePaginationFragment.newInstance(index.intValue());
    }

    // This is called when notifyDataSetChanged() is called
    @Override
    public int getItemPosition(Object object) {
        // refresh all fragments when data set changed
        return PagerAdapter.POSITION_NONE;
    }

    // Delete a page at a `position`
    public void deletePage(int position)
    {
        // Remove the corresponding item in the data set 
        pageIndexes.remove(position);
        // Notify the adapter that the data set is changed
        notifyDataSetChanged();
    }
}

FragmentStatePagerAdapterからのアイテムの削除の詳細については、この完全な を参照してください。

19
Yuchen Zhong

ViewPagerは、複数のビュー(またはこの場合はフラグメント)をメモリにロードするため、上記のコードではフラグメントを削除しません。表示されているビューに加えて、表示されているビューのいずれかの側にビューをロードします。これにより、ビューからビューへのスムーズなスクロールが提供され、ViewPagerが非常にクールになります。

あなたが望む効果を達成するために、あなたはいくつかのことをする必要があります。

  1. FragmentPagerAdapterをFragmentStatePagerAdapterに変更します。これは、FragmentPagerAdapterがメモリにロードするすべてのビューを永久に保持するためです。 FragmentStatePagerAdapterが、現在のトラバース可能なビューの範囲外のビューを破棄する場所。
  2. アダプタメソッドgetItemPosition(以下に表示)をオーバーライドします。 mAdapter.notifyDataSetChanged();を呼び出すとき。 ViewPagerはアダプターに問い合わせて、配置に関して何が変更されたかを判別します。この方法を使用して、すべてが変更されたと言うので、すべてのビューの位置を再処理します。そしてここにコードがあります...

    private class MyPagerAdapter extends FragmentStatePagerAdapter {
        //... your existing code
        @Override
        public int getItemPosition(Object object){
            return PagerAdapter.POSITION_NONE;
        }
    }
    
9
Pankaj Talaviya