Android ViewPager刷新问题

Android ViewPager刷新问题

问题描述

ViewPager的刷新机制和ListView不太一样,ListView中当调用Adapter的notifyDataSetChanged方法后会把列表所有itemView重新绘制一遍。ViewPager在初始化后会生成一些itemView(这个可以通过setOffscreenPageLimit方法设置),ViewPager相当于缓存了几个view,当调用notifyDataSetChanged方法后这几个view是不会重绘的,这就导致数据应该已经更新了,但是左右滑动发现itemView显示的还是之前的数据,滑到后面再滑回来又好了。

解决方法

PagerAdapter有个方法

	@Override
    public int getItemPosition(Object object) {
        return super.getItemPosition(object);
    }

当调用notifyDataSetChanged方法时会调用它,当它返回POSITION_NONE的时候就会重绘这个itemView。这里的object是instantiateItem方法的返回值,一般都是itemView。
之前用的比较简单粗暴的方法,直接返回POSITION_NONE,不管什么都重绘。直到我学会了利用View的tag。
在调用notifyDataSetChanged的时候才需要刷新缓存的view,那我们可以重写notifyDataSetChanged方法

	@Override
    public void notifyDataSetChanged() {
        for (int i = 0; i < viewPager.getChildCount(); i++) {
            View child = viewPager.getChildAt(i);
            child.setTag(R.id.isneedrefresh_tag, true);
        }
        super.notifyDataSetChanged();
    }

给ViewPager的已缓存item加上tag标志是否需要刷新,我这里直接通过viewPager.getChildAt方法获取了,这个自己用列表管理更好。
然后重写getItemPosition方法,获取view的tag,如果是需要刷新的就返回POSITION_NONE,这样就不会影响ViewPager原有的逻辑。

	@Override
    public int getItemPosition(Object object) {
        if ((boolean) ((View) object).getTag(R.id.isneedrefresh_tag)) {
            return POSITION_NONE;
        }
        return super.getItemPosition(object);
    }

每当生成新的itemView的时候,给view设置标志

	@Override
    public Object instantiateItem(ViewGroup container, int position) {
        View convertView;
        ViewHolder holder;
        if (viewRecycler.size() > 0) {
            convertView = viewRecycler.poll();
            holder = (ViewHolder) convertView.getTag(R.id.viewholder_tag);
        } else {
            convertView = inflater.inflate(R.layout.item, container, false);
            holder = new ViewHolder();
            convertView.setTag(R.id.viewholder_tag, holder);
        }

        convertView.setTag(R.id.isneedrefresh_tag, false);
        container.addView(convertView);
        return convertView;
    }

注:这里ViewHolder是仿照listView的复用View的思想,利用一个队列保存本应被销毁的View

	Queue<View> viewRecycler;

	@Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        View view = (View) object;
        container.removeView(view);
        viewRecycler.add(view);
    }
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值