现象
功能需求:横屏查看大图,左右滑动切换大图,大图上有一些涂鸦、描述文字信息,可以通过title上面的按钮隐藏某一张的涂鸦、描述信息;
点击title.hiddenDoodleBtn去改变javabean中的值,执行adapter.notifyDataSetChanged()去更新UI,此时就会出现当前展示也闪烁的问题;
分析*
重写getItemPosition()使notifyDataSetChanged()去执行

@Override
public int getItemPosition(@NonNull Object object) {
    return POSITION_NONE;
}

使用POSITION_NONE模式可以达到notifyDataSetChanged()去更新的效果,但是会导致,每个item都是remove了之后,再重新新建后再添加到布局上,这就会导致更新时候闪烁的根本原因;
分析ViewPager.dataSetChanged()方法可以分析出结果:

void dataSetChanged() {
	………………
    for (int i = 0; i < mItems.size(); i++) {
        final ItemInfo ii = mItems.get(i);
        final int newPos = mAdapter.getItemPosition(ii.object);

        if (newPos == PagerAdapter.POSITION_UNCHANGED) {
            continue;
        }

        if (newPos == PagerAdapter.POSITION_NONE) {
            mItems.remove(i);	//删除item数据,导致闪烁根本原因
            i--;

            ………………
            continue;
        }

        ………………
    }

    ………………
}

解决
将instantiateItem()中得到的view保存在一个集合中,若需要更新的时候,直接从集合中得到item的View对象,用View直接去更新数据,就可以达到目的;
在使用这个过程中,原本是想做一个弱引用去保存View对象,避免View被回收抛nullException,但是用这种方法,无法更新;
错误代码:

public class ImgLabelPargeAdapter extends PagerAdapter {
    ………………
    private List<WeakReference<SimpleImgLoadingLayout>> mImageViews = new ArrayList<>();

    ………………
    @SuppressLint("CheckResult")
    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        final SimpleImgLoadingLayout view = new SimpleImgLoadingLayout(mContext);
        
        mImageViews.add(new WeakReference<>(view));
        container.addView(view);
        return view;
    }

    /**
     * 必须要实现的方法
     * 滑动切换的时销毁一个页面,ViewPager同时加载3个页面,假如此时你正在第二个页面,向左滑动,
     * 将销毁第1个页面
     */
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
        mImageViews.remove(object);
    }
}

正确逻辑
这里可以不用弱引用,集合里面的item数据不会一直增加,他跟你的设置有关ViewPager.setOffscreenPageLimit(3),集合里面的数据不会超过4个,会执行destroyItem()方法去释放item数据,所以直接使用强应用关系即可,此时就可以执行更新了;

public class ImgLabelPargeAdapter extends PagerAdapter {
    private Context mContext;
    private List<ImgLabelBean> lDatas;
    private List<SimpleImgLoadingLayout> mImageViews = new ArrayList<>();

    /**
     * 设置是否显示标注信息
     *
     * @param position 当前itemView的索引
     * @param showTag  true:显示标签;false:隐藏标签;
     */
    public void showTagOption(int position, boolean showTag) {
        if (null == mImageViews || position >= mImageViews.size()) {
            return;
        }

        SimpleImgLoadingLayout sll = mImageViews.get(position);
        ImgLabelBean bean = lDatas.get(position);
        if (null == sll || null == bean) {
            return;
        }

        bean.setShowMark(showTag);
        sll.showTagOption(showTag);
    }

    /**
     * 简称/全称 切换
     *
     * @param position     当前itemView的索引
     * @param showFullName true:全称;false:简称;
     */
    public void showFullTagName(int position, boolean showFullName) {
        if (null == mImageViews || position >= mImageViews.size()) {
            return;
        }

        SimpleImgLoadingLayout sll = mImageViews.get(position);
        ImgLabelBean bean = lDatas.get(position);
        if (null == sll || null == bean) {
            return;
        }

        bean.setShowFullName(showFullName);
        sll.showFullTagName(showFullName);
    }

    /**
     * 清空保存的Item View的数据
     */
    public void clearView() {
        if (null != mImageViews) {
            mImageViews.clear();
        }
    }

    public ImgLabelPargeAdapter(Context context, List<ImgLabelBean> lAllLabel) {
        mContext = context;
        this.lDatas = lAllLabel;
    }

    @Override
    public int getCount() {
        if (lDatas == null) {
            return 0;
        }

        return lDatas.size();
    }

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

    @Override
    public int getItemPosition(@NonNull Object object) {
        return POSITION_NONE;
    }

    /**
     * 必须要实现的方法
     * 每次滑动的时实例化一个页面,ViewPager同时加载3个页面,假如此时你正在第二个页面,向左滑动,
     * 将实例化第4个页面
     **/
    @SuppressLint("CheckResult")
    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
		//这里需要将每个position都要有占位操作,否则由于缓存的原因 mImageViews.size()会小于position大小
        while (mImageViews.size() <= position) {
            mImageViews.add(null);
        }

        final ImgLabelBean labelBean = lDatas.get(position);
        final SimpleImgLoadingLayout view = new SimpleImgLoadingLayout(mContext);
        view.loadImgUrl(labelBean.getImgUrl(), GlideLoadUtil.COMPRESS_TYPE_ORGINAL, GlideLoadUtil.ERROR_ONLY);
        view.showTagOption(labelBean.isShowMark());
        view.showFullTagName(labelBean.isShowFullName());

        //避免图片还没有被imageView渲染出来就发送了数据的问题
        Observable.timer(100, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        view.addMarkPoints(labelBean.getTagResults());
                    }
                });

        mImageViews.set(position, view);
        container.addView(view);
        return view;
    }

    /**
     * 必须要实现的方法
     * 滑动切换的时销毁一个页面,ViewPager同时加载3个页面,假如此时你正在第二个页面,向左滑动,
     * 将销毁第1个页面
     */
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
        mImageViews.set(position, null);
    }
}