RecyclerView.Adapter的优化与封装

说实在的,敲代码和看书相比较,我还是看书或是看博文看得多,到现在好久都没练练手了,然后在简书上面看了别人对adapter的封装和优化,嘿,还真的挺不错的,adapter真的简洁了不少,看完了思路,原来这么简单的啊,他的方法可能和我不同,但是思路都是差不多的,但是我觉得我的更通俗易懂(真是不要脸啊=_=!!)。好了,开始表演真正的技术了。

项目结构图

这里写图片描述

主要是对BaseRecycleAdapter和BaseViewHolder进行封装。

好了,开始讲课了^_^。

BaseRecycleAdapter.class

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;
import css.lontano.coordinatorlayouttest.javabean.BaseBean;

/**
 * Created by wangqi on 2016/7/16.
 */
public abstract class BaseRecycleAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    private int layoutId;
    private List<? extends BaseBean> data;
    private Context context;
    private OnItemClickListner onItemClickListner;//单击事件
    private OnItemLongClickListner onItemLongClickListner;//长按单击事件
    private boolean clickFlag = true;//单击事件和长单击事件的屏蔽标识

    /**
     *
     * @param context //上下文
     * @param layoutId  //布局id
     * @param data  //数据源
     */
    public BaseRecycleAdapter(Context context, int layoutId, List<? extends BaseBean> data) {
        this.layoutId = layoutId;
        this.data = data;
        this.context = context;
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(context).inflate(layoutId, parent, false);
        final BaseViewHolder holder = new BaseViewHolder(v, context);
        //单击事件回调
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (clickFlag) {
                    onItemClickListner.onItemClickListner(v,holder.getLayoutPosition());
                }
                clickFlag = true;
            }
        });
        //单击长按事件回调
        v.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                onItemLongClickListner.onItemLongClickListner(v,holder.getLayoutPosition());
                clickFlag = false;
                return false;
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        convert(holder, data.get(position));
    }

    protected abstract <T extends BaseBean> void convert(BaseViewHolder holder, T bean);

    @Override
    public int getItemCount() {
        return data.size();
    }

    public void setOnItemClickListner(OnItemClickListner onItemClickListner) {
        this.onItemClickListner = onItemClickListner;
    }

    public void setOnItemLongClickListner(OnItemLongClickListner onItemLongClickListner) {
        this.onItemLongClickListner = onItemLongClickListner;
    }

    public interface OnItemClickListner {
        void onItemClickListner(View v,int position);
    }

    public interface OnItemLongClickListner {
        void onItemLongClickListner(View v,int position);
    }
}

BaseRecycleAdapter类里面其实没什么,就和普通的adapter没什么区别,只是将数据的设置用抽象方法去表示,然后让继承类去实现结果操作。
看到上面的代码,大家应该看到了两个重点:
一、单击事件的回调:
RecyclerView默认是没有像ListView的onItemClick方法的,我们必须得自己去实现,我是直接给引用 的布局设置点击事件和长点击事件,这个点击事件最好是设置在onCreateViewHolder方法中,因为RecyclerAdapter初始化只调用一次,而有些人习惯设置在onBindViewHolder方法中,这样每次更新View都要去设置一遍监听事件,是没有必要的操作。大家看到我在两个事件的回调里面设置了一个clickFlag单击标记,大家知道是为了避免什么吗?操作实验过的同学应该就会知道了,假如不设置这些标志,在进行长点击操作松开手指会发现,他还会再触发一次短单击事件,所以为了避免长点击操作带来的两次回调效果,先设置clickFlag为true,此时可以短点击,当长单击操作开始时,我们设置clickFlag为false,这是长单击回调结束,进入了短单击,发现此时clickFlag是为false的,所以就不回调短单击的事件,最后又重新设置回可短单击效果,这部分要是不明白的可以给我留言。
二、数据传递用泛型
①List< ? extends BaseBean> data
② protected abstract void convert(BaseViewHolder holder, T bean);
这两个部分都是泛型的巧用,以前不会玩这些,java打的不牢,后来看鸿洋的博客,对于封装这块用的特别多,忽然发现泛型的重要性,然后重回宿舍,拿起李刚的《疯狂java讲义》狂看,看完之后,原来是这样的啊,? extends BaseBean表现为集合数据里面存储的类型是BaseBean或是BaseBean的子类,也就是向下,如果是? super BaseBean 则存储的数据类型为BaseBean或BaseBean的父类,也就是向上,大概好像是这么理解的,如有错误,大家指出来喔,
我这边存储的数据类型Model,bean都必须要继承BaseBean这个父类,因为泛型传递,所以我就这么做了,要是大家有什么好的方法的话,也可以告诉告诉我,就怕没有知识汲取。

BaseBean.class 和Person.class

这里写图片描述

BaseViewHolder.class

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by Administrator on 2016/7/16.
 */
public class BaseViewHolder extends RecyclerView.ViewHolder {
    View convertView;
    Context context;

    public BaseViewHolder(View itemView, Context context) {
        super(itemView);
        this.convertView = itemView;
        this.context = context;
    }

    public void setText(int id, String text) {
        TextView tx = (TextView) convertView.findViewById(id);
        tx.setText(text);
    }

    public void setImageResource(int id, int resouceId) {
        ImageView img= (ImageView) convertView.findViewById(id);
        img.setImageResource(resouceId);
    }

}

BaseViewHolder这个类呢一般都是拿来优化RecycleView的,然后拿到这个holder来设置数据,RecycleAdapter的onCreateViewHolder方法将填充的item布局返回给了BaseViewHolder,然后将这个view设置为全局,下面的那些setText或是setImageResource等等,大家都可以自己扩展,这些方法都是提供设置View数据的。


好了,base封装基本上完成了,接下来就是怎么用了。

RecycleAdapterTest.class

import android.content.Context;
import java.util.List;
import css.lontano.coordinatorlayouttest.BaseRecycleView.BaseRecycleAdapter;
import css.lontano.coordinatorlayouttest.BaseRecycleView.BaseViewHolder;
import css.lontano.coordinatorlayouttest.javabean.BaseBean;
import css.lontano.coordinatorlayouttest.javabean.Person;

/**
 * Created by wangqi 2016/7/16.
 */
public class RecycleAdapterTest extends BaseRecycleAdapter {


    public RecycleAdapterTest(Context context, List<Person> list) {
        super(context, R.layout.recycle_item, list);
    }


    @Override
    protected <T extends BaseBean> void convert(BaseViewHolder holder, T bean) {
        Person p = (Person) bean;
        holder.setText(R.id.text, p.getName());
    }
}

最后就是泛型的强转,然后下面调用ViewHolder的设置数据,将资源id和数据传递过去,就设置好了。

哇塞,adapter这么少的啊,真的好爽,我都佩服自己了。

主MAinActivity设置adapter就和普通设置数据一样一样的啦,基本没什么变化。

MainActivity.class

  recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //模拟数据
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Person p = new Person();
            p.setName(i+"ww");
            list.add(p);
        }

        RecycleAdapterTest adapter = new RecycleAdapterTest(this, list);
        recyclerView.setAdapter(adapter);
        adapter.setOnItemClickListner(new BaseRecycleAdapter.OnItemClickListner() {
            @Override
            public void onItemClickListner(View v, int position) {
                Toast.makeText(MainActivity.this,"单击事件回调"+position,Toast.LENGTH_SHORT).show();
            }
        });
      adapter.setOnItemLongClickListner(new BaseRecycleAdapter.OnItemLongClickListner() {
          @Override
          public void onItemLongClickListner(View v, int position) {
              Toast.makeText(MainActivity.this,"长单击事件回调"+position,Toast.LENGTH_SHORT).show();
          }
      });

item布局就是一个TextView,就没有什么了。

效果图

这里写图片描述


实力装了一次,以前看别人写这些代码,感觉好高大上啊,其实真的没有什么啊=_=,自己动手,丰衣足食。暑期以来第一篇,之前忙着看 安卓优化方面的书,等看完了,有了自己的心得,再来写一篇优化类的博文吧!!搞定!!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值