RecyclerView
使用心得
之前一直用的listView ,没用过recyclerView。最近学习了一段时间之后发现有它的优势和缺点(也可能是刚开始使用不习惯,暂且定为缺点吧。)与listView相比,recycler也用于展示数据,但是在数据的展示方式上和数据增加删除上多了很多便利。比较特殊的地方是recyclerView的adapter是强制使用的,还有就是recycler没有提供onItemClick和onItemlongClick事件,具体用法往下看。
用法
1 引入依赖
主要是com.android.support包下的v7包。
compile 'com.android.support:recyclerview-v7:24.1.1'
2在xml中定义出
<android.support.v7.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
3定义adapter
有了view了,那么就是数据填充了。前面讲过recyclerView最大的区别就是有自己的adapter,不在继承于baseAdapter了,而是用他自己的adapter。
贴一个例子:
public class WorkTypeAdapter extends RecyclerView.Adapter<WorkTypeTWOAdapter.TypeHolder>{
@Override
public TypeHolder onCreateViewHolder(ViewGroup parent, int viewT) {
View view = layoutInflater.inflate(R.layout.work_type_item_layout, null);
TypeHolder typeHolder = new TypeHolder(view);
return typeHolder;
}
@Override
public void onBindViewHolder(final TypeHolder holder, int position) {
// 设置数据
TaskType taskType = taskTypeList.get(position);
holder.name.setText(taskType.getName());
// 设置点击事件
if(mOnItemClickLitener !=null){
holder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getLayoutPosition();
mOnItemClickLitener.onItemClick(holder.itemView,position);
}
});
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return taskTypeList != null ? taskTypeList.size() : 0;
}
public interface OnItemClickLitener
{
void onItemClick(View view, int position);
void onItemLongClick(View view , int position);
}
private OnItemClickLitener mOnItemClickLitener;
public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
{
this.mOnItemClickLitener = mOnItemClickLitener;
}
class TypeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView name;
public TypeHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.tv_work_name);
}
@Override
public void onClick(View v) {
}
}
}
- 如上可以看到,实现了recyView的adapter实现3个方法, onCreateViewHolder onBindViewHolder getItemCount
- viewHolder 。之前listView也用viewHolder,但是并不是强制使用的,但是在recyclerView里是必须要用recyClerView下的ViewHolder
- 由于recyclerView没提供OnItemClickListener ,onItemLongClickListener。不过这也没关系我们可以自定义接口。
第一步: 定义接口:
public interface OnItemClickLitener
{
void onItemClick(View view, int position);
void onItemLongClick(View view , int position);
}
第二步:定义供外部使用去设置listener
private OnItemClickLitener mOnItemClickLitener;
public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
{
this.mOnItemClickLitener = mOnItemClickLitener;
}
第三步:将view和listener绑定在一起
// 设置点击事件
if(mOnItemClickLitener !=null){
holder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getLayoutPosition();
mOnItemClickLitener.onItemClick(holder.itemView,position);
}
});
}
第四步:在adapter调用的地方是去实现listener,并且实现具体的方法。
4 设置布局管理器
adapter已经建立了,数据也有了。那接下来就是设置布局管理器,这也是recyClerView的特色和最强大的地方,可以依据布局的不同设置不同的展示效果。
// 设置布局管理器
// 线性布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
//设置为垂直布局,这也是默认的
linearLayoutManager.setOrientation(OrientationHelper. VERTICAL);
// 表格布局
//mRecyclerView.setLayoutManager(new GridLayoutManager( this,4));
//瀑布流式的布局
//mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
// 线性布局
mRecyclerView.setLayoutManager(linearLayoutManager);
分割线
// 设置分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
下面是分割线的代码:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
// 第一步
private static final int[] ATTRS = new int[]{
android.R.attr. listDivider
};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS );
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}
public void setOrientation( int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException( "invalid orientation");
}
mOrientation = orientation;
}
/*
@Override
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}*/
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
/* @Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
}else{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}*/
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(5, 5, 5, mDivider.getIntrinsicHeight());
}else{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
接下来我会再次讲解一次用RecyClerView 复杂的界面。