ViewPager使用FragmentPagerAdapter加载多个fragment,实现对已加载的list做插入、删除及排序操作

本文介绍了如何在Android中利用ViewPager结合FragmentPagerAdapter加载并管理多个Fragment。内容涵盖如何实现对已加载的Fragment列表进行插入、删除和排序的操作,提供了一个有效的UI动态更新方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ViewPager使用FragmentPagerAdapter加载多个fragment,实现对已加载的list做插入、删除及排序操作。

例子1:
List<Fragment> list = new ArrayList<>();
list.add(fragment1);
list.add(fragment2);
list.add(fragment3);

adapter = new MyListAdapter(list,fragmentManager);
viewpager.setAdapter(adapter);

//删除fragment2
list.remove(fragment2);
adapter.notifyDataSetChanged();
执行上面代码是没任何改变的,因为在调用adapter.notifyDataSetChanged()时adapter会通过getItemPosition(Object object)
来判断是否删除fragment:

这里写图片描述

通过重写getItemPosition:

    @Override
    public int getItemPosition(Object object) {
        //每次都刷新都调用instantiateItem 和destroyItem方法
        return POSITION_NONE;
    }
再次执行例子1,viewpager是有改变的但是不是期望的效果,继续看源码:

这里写图片描述

而getItemId(position)方法默认返回的是

这里写图片描述

到这里可以发现instantiateItem()新增fragment是通过position创建一个name然后在
fragmentManager中查询是否存在改name的fragment,存在就调用attch方法重新加载(这
里与destroyItem方法的detach对于的,attch会重新创建View)。

所以例子1删除fragment2时,list的size为2,调用notifyDataSetChanged,
adapter会删除所有的fragemnt调用instantiateItem重新添加,在创健fragment的name时
默认返回position,所以剩下两个的name是以position为0、1的tag,viewpager显示的
是fragment1、fragment2,而不是fragment1、fragment3。

接下来MyFragmentPagerAdapter:

public abstract class MyFragmentPagerAdapter extends PagerAdapter{
    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;
    private Fragment mCurrentPrimaryItem = null;

    public MyFragmentPagerAdapter(FragmentManager mFragmentManager){
        this.mFragmentManager =mFragmentManager;
    }

    public abstract Fragment getItem(int position);

    /**作为fragment的标识,每个fragment都有单独的标识,不能直接用position,否则在排序和删除会出现fragment错乱*/
    public abstract long getItemId(int position);
    @Override
    public void startUpdate(ViewGroup container) {
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        final long itemId = getItemId(position);

        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            /** mCurTransaction.attach(fragment);
              * 用show、hide代替attach、detach,这样fragment不会reCreateView
              */
            mCurTransaction.show(fragment);
        } else {
            fragment = getItem(position);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        /** mCurTransaction.detach((Fragment)object);*/
        mCurTransaction.hide((Fragment)object);
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment)object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
                mCurrentPrimaryItem.setUserVisibleHint(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
            }
            mCurrentPrimaryItem = fragment;
        }
    }

    @Override
    public int getItemPosition(Object object) {
        //每次都刷新都调用instantiateItem 和destroyItem方法
        return POSITION_NONE;
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        if (mCurTransaction != null) {
            mCurTransaction.commitAllowingStateLoss();
            mCurTransaction = null;
            mFragmentManager.executePendingTransactions();
        }
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return ((Fragment)object).getView() == view;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    private static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }
}
用法和FragmentPagerAdapter一样,将getItemId改为抽象方法,返回每个fragment的标识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值