RecyclerView
1. 为什么叫RecyclerView?
1. 不关心Item是否显示在正确的位置,如何显示。
2. 不关心Item之间如何分隔
3. 不关注Item的增加与删除的动画效果
4. 仅仅关注如何回收与复用View
2. 需要引入的类
LayoutManage确定显示的位置
1. ItemDecoration设置Item之间的分隔
2. ItemAnimation设置动画
3. Adapter适配器
4. ViewHolder复用
3. RecyclerView能做什么
1. Just likeListView
2. Just likeGridView
3. 横向ListView
4. 横向GridView
5. 瀑布流
6. 定制Item增加与删除动画
1. 前五个对应的是LayoutManage
2. 最后一个对应的是ItemAnimotion
1. 传统的BaseAdapter会在getView中去进行创建ViewHolder和对应的View进行赋值,而在该Adapter中,将这个过程分成两部分。
2. RecyclerView的Adapter的创建
1. 创建一个类,继承自RecyclerView.ViewHolder
class MyViewHolder extends RecyclerView.ViewHolder {TextView tv;public MyViewHolder(View itemView) {super(itemView);tv = ((TextView) itemView.findViewById(R.id.id_tv));} }
1. public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {private LayoutInflater inflater;private Context context;private List<String> datas;MyAdapter(Context context, List<String> datas) {this.context = context;this.datas = datas;inflater = LayoutInflater.from(context);}@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = inflater.inflate(R.layout.item1, parent, false);MyViewHolder viewHolder = new MyViewHolder(view);return viewHolder;}@Overridepublic void onBindViewHolder(final MyViewHolder holder, final int position) {holder.tv.setText(datas.get(position));}@Overridepublic int getItemCount() {return datas.size();}
}
1. MainActivity中的代码和ListView一样。
2. 分隔线分为两种
1. 使用布局的background来充当分隔线
2. 借助DividerItemDecoration类
3. package com.example.jash.recyclerview;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View;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;}@Overridepublic void onDraw(Canvas c, RecyclerView parent){ // Log.v("recyclerview - itemdecoration", "onDraw()");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);RecyclerView v = new RecyclerView(parent.getContext());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);}}@Overridepublic 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);}} }
4. 设置RecyclerView的分隔线recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
5. 设置动画
recyclerView.setItemAnimator(new DefaultItemAnimator())
1. 添加与删除
在Adapter中添加方法:
public void addData(int position) {datas.add(position,"Insert One");notifyItemInserted(position); }public void delData(int position) {datas.remove(position);notifyItemRemoved(position); }
注意此时的Adapter的刷新!添加notifyItemInserted
删除:notifyItemRemoved
2. 点击事件
在Adapter中定义一个接口:
public interface OnItemClickListener {void OnItemClick(View view, int position);void OnItemLongClick(View view, int posution); }private OnItemClickListener listener;public void setOnItemClickListeren(OnItemClickListener listeren) {this.listener = listeren; }
3. 在onBindViewHolder方法中使用:
4. if (listener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {int layoutPosition = holder.getLayoutPosition();listener.OnItemClick(holder.itemView, layoutPosition);}}); } holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View view) {int layoutPosition = holder.getLayoutPosition();listener.OnItemLongClick(holder.itemView, layoutPosition);return true;} });
5. 注意:
int layoutPosition = holder.getLayoutPosition(); listener.OnItemClick(holder.itemView, layoutPosition);
6. listener.OnItemClick(holder.itemView, layoutPosition);
layoutPosition 再点击Item的时候为真是的position
如果使用position则为开始我id,即……在position=1的地方添加一条,使用position,点击添加的Item id=1 无论添加多少条,id总为1
如果使用holder.getLayoutPosition ,添加的Item,点击Item之后获取到的Id为真的的id。
7. RecyclerView的布局设置:
Just like ListView(垂直方向)
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
Just like ListView(水平方向)
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
Just like GridView(三列)
recyclerView.setLayoutManager((new GridLayoutManager(this, 3)));
水平GradView(五行)
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.HORIZONTAL));
8. 瀑布流的设置
1. 只需要在Adapter中动态的设置Holder.ItemView的高度。
9. mHeight = new ArrayList<>(); for (int i = 0; i < mDatas.size(); i++) {mHeight.add((int) (100 + Math.random() * 300)); }
10. onBindViewHolder方法中
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams(); lp.height = mHeight.get(position); holder.itemView.setLayoutParams(lp);
此时可以实现瀑布流的效果。