ViewPager中View的复用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ViewPager中View的复用相关的知识,希望对你有一定的参考价值。

代码例如以下:

public class MyViewPagerAdapter extends PagerAdapter {

    //显示的数据
    private List<DataBean> datas = null;

    private LinkedList<View> mViewCache = null;

    private Context mContext ;

    private LayoutInflater mLayoutInflater = null;


    public MyViewPagerAdapter(List<DataBean> datas, Context context) {
        super();
        this.datas = datas;
        this.mContext = context ;
        this.mLayoutInflater = LayoutInflater.from(mContext) ;
        this.mViewCache = new LinkedList<>();
    }

    @Override
    public int getCount() {
        Log.e("test","getCount ");
        return this.datas.size();
    }

    @Override
    public int getItemPosition(Object object) {
        Log.e("test","getItemPosition ");
        return super.getItemPosition(object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Log.e("test","instantiateItem " + position);
        ViewHolder viewHolder = null;
        View convertView = null;
        if(mViewCache.size() == 0){
            convertView = this.mLayoutInflater.inflate(R.layout.viewadapter_item_layout ,
                    null ,false);
            TextView textView = (TextView)convertView.findViewById(R.id.view_pager_item_textview);
            viewHolder = new ViewHolder();
            viewHolder.textView = textView;
            convertView.setTag(viewHolder);
        }else {
            convertView = mViewCache.removeFirst();
            viewHolder = (ViewHolder)convertView.getTag();
        }

        viewHolder.textView.setText(datas.get(position).title);
        viewHolder.textView.setTextColor(Color.YELLOW);
        viewHolder.textView.setBackgroundColor(Color.GRAY);

        container.addView(convertView ,ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT );

        return convertView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Log.e("test","destroyItem " + position);
        View contentView = (View) object;
        container.removeView(contentView);
        this.mViewCache.add(contentView);
    }

    @Override
    public boolean isViewFromObject(View view, Object o) {
        Log.e("test","isViewFromObject ");
        return view == o;
    }

    public final class ViewHolder{
        public TextView textView ;
    }
}

首先须要了解ViewPager的Adapter各个方法的回调机制。
这里主要看两个方法:instantiateItem()和destroyItem()。
instantiateItem()方法,是在滑动到一个新的ViewItem的时候被调用的,而destroyItem()是在当用户滑到第3个ViewItem的时候被调用,在这个时候会先调用这种方法来回收第一个ViewItem,然后在调用instantiateItem()方法来实例化第3个ViewItem。能够在adapter的各个回调方法中打出log来看这种方法被调用的时机。
利用上面所说的机制,就能够在destroyItem()的时候将要被remove掉的view回收起来,然后在instantiateItme()的时候反复利用这个view。这样,就仅仅会有3个ViewHolder实例存在。即当前显示的。还有上一个Item和下一个Item。

以上是关于ViewPager中View的复用的主要内容,如果未能解决你的问题,请参考以下文章

在渲染之前触发ViewPager片段内嵌套片段的动画

IllegalArgumentException: No view found for id for fragment --- ViewPager in ViewPager

隐藏在标签栏后面的 View Pager 的片段

ViewPager2 中未显示图像(片段重新打开时)

无法更新 View Pager 中的中间片段。

Android内存优化之ViewPager的内存优化