RecyclerView 是在Android5.0之后推出的,距离现在已经过去很长时间了,是一个比ListView更加灵活更加高效的适配器类型控件。但是RecyclerView不同于其他类型的适配器,它还需要一个LayoutManager进行页面控制展示。
RecyclerView提供了三种布局管理器:
1、LinearLayoutManager:线性布局管理器,支持水平和垂直效果。
2、GridLayoutManager:网格布局管理器,支持水平和垂直效果。
3、StaggeredGridLayoutManager:分布型管理器,瀑布流效果。
布局管理器LayoutManager,控制其显示的方式。
控制Item间的间隔(可绘制),请通过ItemDecoration。
控制Item增删的动画,请通过ItemAnimator。
控制点击、长按事件,需要自己动手(QAQ)。
RecyclerView的使用:
1、引入RecyclerView依赖包,V7下的,兼容到API17.
2、在xml布局中声明,在Java代码中初始化。
3、设置布局管理器
4、创建适配器,设置数据源,绑定适配器
具体创建适配器:①创建一个类,继承RecyclerView.Adapter
②创建一个类ViewHolder,继承RecyclerView。VIewHolder,该类需要创建一个匹配父类的构造。
③重写适配器中的方法:getItemCount():获取数据源的个数(item的数量);onCreateViewHolder():该方法中导入布局,实例化VIewHolder;onBindViewHolder():绑定VIewHolder,加载数据。
注意一点:RecyclerView的LinearLayoutManager不同于一般的适配器的布局,RecyclerView的item最外层的布局参数是有效的,如高度宽度等,所以在使用的时候,第一种方法是在导入View的时候指定没有parent(不推荐使用),第二种方法是在item布局的最外层指定具体的参数。
RecyclerView 为开发者提供了强大的复用机制,但是所有的点击事件都丢了,没有提供默认的点击事件,所以需要我们自己为RecyclerView手动实现点击。
基本的使用:
xml:
item xml:
主界面与适配器代码:
public class ActRecycleview extends Activity {
private List list;
private LinearLayoutManager mLayoutManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_recycleview);
ButterKnife.bind(this);
getData();
RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
//创建线性布局
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//创建线性布局
mLayoutManager = new LinearLayoutManager(this);
// GridLayoutManager gridLayoutManager =new GridLayoutManager(this,4);
//瀑布流的效果
// StaggeredGridLayoutManager staggeredGridLayoutManager=new StaggeredGridLayoutManager(2,OrientationHelper.VERTICAL);
//垂直方向
mLayoutManager.setOrientation(OrientationHelper.VERTICAL);
//给RecyclerView设置布局管理器
mRecyclerView.setLayoutManager(mLayoutManager);
//添加分割线
mRecyclerView.addItemDecoration(new AdvanceDecoration(this, OrientationHelper.VERTICAL));
recyclerAdapter adapter = new recyclerAdapter();
mRecyclerView.setAdapter(adapter);
}
private void getData() {
list = new ArrayList();
for (int i = 0;i<20;i++){
list.add("indest"+i);
}
}
class recyclerAdapter extends RecyclerView.Adapter{
@Override
public MviewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MviewHolder holder = new MviewHolder(LayoutInflater.from(ActRecycleview.this)
.inflate(R.layout.recycleview_item,parent,false));
return holder;
}
@Override
public void onBindViewHolder(MviewHolder holder, int position) {
holder.tv.setText(list.get(position));
}
@Override
public int getItemCount() {
return list.size();
}
class MviewHolder extends RecyclerView.ViewHolder{
TextView tv;
public MviewHolder(View v){
super(v);
tv = (TextView) v.findViewById(R.id.item_tv);
}
}
}
}
分割线ItemDecoration,通过该方法添加分割线:
mRecyclerView.addItemDecoration()
(该方法的参数为RecyclerView.ItemDecoration,该类为抽象类)
public static abstract class ItemDecoration {
public void onDraw(Canvas c, RecyclerView parent, State state) {
onDraw(c, parent);
}
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
onDrawOver(c, parent);
}
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
parent);
}
@Deprecated
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
outRect.set(0, 0, 0, 0);
}
当我们调用mRecyclerView.addItemDecoration()方法添加decoration的时候,RecyclerView在绘制的时候,去会绘制decorator,即调用该类的onDraw和onDrawOver方法,
onDraw方法先于drawChildren
onDrawOver在drawChildren之后,一般我们选择复写其中一个即可。
getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,主要用于绘制Decorator。
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
//采用系统内置的风格的分割线
private static final int[] attrs = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
private int orientation;
public DividerItemDecoration(Context context, int orientation){
TypedArray typedArray = context.obtainStyledAttributes(attrs);
mDivider = typedArray.getDrawable(0);
typedArray.recycle();
this.orientation = orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
drawHDeraction(c,parent);
drawVDeraction(c,parent);
}
/**
* 绘制水平方向的分割线
* @param c
* @param parent
*/
private void drawHDeraction(Canvas c,RecyclerView parent){
int left = parent.getPaddingLeft();
int right = parent.getWidth()-parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i=0;i
效果图:
(其他效果请自行测试)