ViewPager + 对象池

     前言:之前公司实现了一个在线作业功能,要求是有多种题型,多道题。一看需求的时候,我就确定要使用ViewPager实现。方便快捷顶呱呱,然而~~~问~~~题~~~来~~~了。

     测试完后,发现的问题有:

(1)在一些机型上出现内存溢出的问题;

(2)用起来感觉非常笨重;

(3)滑动不是很流畅;


先说说我之前实现的方式:

根据题目的个数创建出对应的View(也就是说有50道题,就创建50个view),然后放到List中,直接setAdapter即可。

出现上面的问题,很可能是跟这种实现方式有关,所以决定换一种方式实现。


方式一: list中只存放5中题型的View,在adapter中根据type值获取相应的View。

           结果在Viewpager滑动的时候出现异常:

         

            字面的意思是view已经有一个parent了,要想用这个view的话得删除掉当前的parent;

            然后在网上乱找一通,还是没有解决!放弃!放弃!放弃!


方式二:使用RecycleView 设置成横向滑动,就能解决这个复用的问题了。

            在使用的时候出现1个问题:发现滑动使用有些卡顿;


方式三:使用对象池

             对象池可以解决 创建多个对象导致内存升高的问题;

             我创建了两个对象,分别代表了两种题型,直接上代码:

public class ViewTypeAEntity {
    public View view;

    private  static final Pools.SynchronizedPool<ViewTypeAEntity>  instance  = new Pools.SynchronizedPool<>(3);

    public static ViewTypeAEntity obtain(View contentView) {
        ViewTypeAEntity viewTypeBean = instance.acquire();
        if(viewTypeBean != null){
            return  viewTypeBean;
        }else{
            viewTypeBean = new ViewTypeAEntity();
            viewTypeBean.view = contentView;
            return  viewTypeBean;
        }
    }

    public void recycle() {
        instance.release(this);
    }
    
}

创建一个对象池;

创建一个方法用于返回对象;

还有一个对象回收的方法;


在PagerAdapter上使用:

public class PagesAdapter extends PagerAdapter {
    private Context context;
    private Map<Integer, Object> newsHash;

    public PagesAdapter(Context context) {
        newsHash = new HashMap<>();
        this.context = context;
    }


    @Override
    public int getCount() {
        return 6;
    }

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


    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int index = position % 2;
        View contentView = null;
        if (index == 0) {
            View view = LayoutInflater.from(context).inflate(R.layout.view_a, null);
            ViewTypeAEntity viewTypeAEntity = ViewTypeAEntity.obtain(view);
            contentView = viewTypeAEntity.view;
            newsHash.put(position, viewTypeAEntity);
        } else {
            View view = LayoutInflater.from(context).inflate(R.layout.view_b, null);
            ViewTypeBEntity viewTypeBEntity = ViewTypeBEntity.obtain(view);
            contentView = viewTypeBEntity.view;
            newsHash.put(position, viewTypeBEntity);
        }
        container.addView(contentView);
        return contentView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        int index = position % 2;
        View view = null;
        if (index == 0) {
            ViewTypeAEntity viewTypeAEntity = (ViewTypeAEntity) newsHash.get(position);
            view = viewTypeAEntity.view;
            container.removeView(view);
            viewTypeAEntity.recycle();
        } else {
            ViewTypeBEntity viewTypeBEntity = (ViewTypeBEntity) newsHash.get(position);
            view = viewTypeBEntity.view;
            container.removeView(view);
            viewTypeBEntity.recycle();
        }
    }
}

注意看instantiateItem():

创建了一个对象来使用;

既然有创建就有回收,我创建了一个Map,键为position,值为创建的对象。

destroyItem()中拿到对象,回收对象;










           


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值