解决ViewPager中调用FragmentPagerAdapter.notifyDataSetChanged() 不能更新数据以及删除某个页面后显示错乱的问题

在instantiateItem方法中会通过container.getID()和getItemId()结合起来作为tag寻找Fragment的缓存,如果有直接取,没有的话调用getItem来获取新的Fragment,一个ViewPager中的ID是不变的,所以我们需要每次更新getItemId()并根据它寻找需要更新的Fragment,增加或删除Fragment时也需要更新getItemId(),当要删除某个Fragment时需要重写destroyItem,在父类方法后面加上清除这个Fragment的功能,更新数据的方式有两种设置flag可以全部更新也可以只更新某一个Fragment,这里需要重写getItemPosition方法来实现,最终可以任意添加和删除Fragment并更新数据,更新数据只要求Fragment实现UpdateAble接口,以后Adapter只要继MyViewPagerAdapter就可以了,具体内容看下面代码,
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;


public class MyViewPagerAdapter extends FragmentPagerAdapter {
    private  final  String TAG=this.hashCode()+"";
    private FragmentManager fm;
    private List<Fragment> mlist=new ArrayList<>();//fragment列表
    private int action=0; //不需要增加或删除fragment
    private int updateId=0;//需要更新的第几个fragment
    private boolean flag=false;//false表示只更新一个fragment,true表示全部更新
    private List<Integer> itemID=new ArrayList<>();//用来返回getItemId的值

    public MyViewPagerAdapter(FragmentManager fm) {
        super(fm);
        this.fm=fm;

    }

    public void addFragment(Fragment fg){
        mlist.add(fg);
        action=1;//末尾增加一个Fragment
        itemID.add(mlist.size()-1);

    }

    public void addFragment(Fragment fg ,int position){
        mlist.add(position,fg);
        action=2;//非末尾插入一个Fragment
        itemID.add(position,mlist.size()-1);

    }

    public void removeFragment(){
        mlist.remove(mlist.get(mlist.size()-1));
        action=3;//末尾删除一个Fragment
        itemID.remove(itemID.size()-1);
        notifyDataSetChanged();
    }

    public void removeFragment(int position){
        mlist.remove(mlist.get(position));
        action=4;//非末尾删除一个Fragment
        itemID.remove(position);
        notifyDataSetChanged();
    }

    public void updateFragment(int position,String str,boolean flag){
        updateId=position;
        this.flag=flag;
        Fragment fragment =getItem(position);
        if(fragment instanceof UpdateAble){//这里唯一的要求是Fragment要实现UpdateAble接口
            ((UpdateAble)fragment).update(str);
            notifyDataSetChanged();
        }
    }

    public interface UpdateAble {
        public void update(String str);//更新数据
    }

    @Override
    public Fragment getItem(int arg0) {
        return mlist.get(arg0);//显示第几个页面

    }

    @Override
    public long getItemId(int position) {

        return itemID.get(position);

    }
    @Override
    public int getCount() {
        return mlist.size();//有几个页面
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Log.e(TAG, "instantiateItem:" );
        //int viewPagerId=container.getId();
        //makeFragmentName(viewPagerId,getItemId(position));
        return super.instantiateItem(container, position);
    }

    @Override
    public int getItemPosition(Object object) {
        if(mlist!=null&& !mlist.isEmpty()) {

            if(flag) return POSITION_NONE;
            else {
                if(!mlist.contains((Fragment)object)) {
                    Log.e(TAG, "getItemPosition: 没有找到");
                    return POSITION_NONE;

                }
                else {

                    Fragment fragment = getItem(updateId);
                    if(fragment==null) return POSITION_NONE;
                    if (fragment== (Fragment) object) {
                        Log.e(TAG, "getItemPosition: 找到");
                        return POSITION_NONE;
                    } else {

                        Log.e(TAG, "getItemPosition: 非更新项不变");
                        return POSITION_UNCHANGED;
                    }
                }

            }

        }
        Log.e(TAG, "getItemPosition: 超出范围");
        return POSITION_UNCHANGED;

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object){

        super.destroyItem(container, position, object);

        Log.e(TAG, "destroyItem");
        if (action >2) {
            FragmentTransaction transaction = fm.beginTransaction();

            transaction.remove((Fragment)object);
            transaction.commit();
            action=0;
        }


    }


    private static String makeFragmentName(int viewId, long id) {
        Log.e("viewId=", ""+viewId);
    return "android:switcher:" + viewId + ":" + id;
    }

}

猜你喜欢

转载自blog.csdn.net/boguesfei/article/details/81978742