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