说实在的,敲代码和看书相比较,我还是看书或是看博文看得多,到现在好久都没练练手了,然后在简书上面看了别人对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,就没有什么了。
效果图
实力装了一次,以前看别人写这些代码,感觉好高大上啊,其实真的没有什么啊=_=,自己动手,丰衣足食。暑期以来第一篇,之前忙着看 安卓优化方面的书,等看完了,有了自己的心得,再来写一篇优化类的博文吧!!搞定!!
相关资源:RecyclerView Adapter 优雅封装 - CustomerAdapter,一个Adapter搞定所有列表