RecyclerView

RecyclerView简明

RecyclerView 在v7.21+包中,是一个用来展示大量数据的组件,或者说,就是ListView的改善版本(注:现阶段的功能没有ListView完善,因此想完全取代ListView的话并不明智)。
相比ListView,RecyclerView的扩展性更好,因此也更适合与android新曾的组件配合使用,这样使用起来更得心应手。

RecyclerView与ListView的原理差不多,本质上都是以适配器为核心。只不过ListView缓存的是view,viewHolder附着在view上,而RecyclerView缓存的是viewHolder,view包含在viewHolder内。

如果我们将ListViewAdapter稍作修改,也可以实现这种设计:

abstract class LvAdapter<VH extends LvAdapter.ViewHolder> extends BaseAdapter {    public class ViewHolder {        private View view;        public ViewHolder(View view) {            this.view = view;        }        public View getView() {            return view;        }    }    @Override    public int getCount() {        return 0;    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        VH vh = getViewHolder();        onBindViewHolder(vh, position);        return vh.getView();    }    public abstract VH getViewHolder();    public abstract void onBindViewHolder(VH holder, int position);}

这样有点不直观,所以更进一步,ListView的Adapter可以更抽象,将数据绑定方法交给viewHolder,这样adapter的工作就更单纯一点.

一个方便的ListViewAdapter可以参考base-adapter-helper

RecyclerView使用

适配器

既然都是以适配器为核心,因此,只需要写好适配器就行了:

class RvViewHolder extends RecyclerView.ViewHolder {    public TextView tv;    public RvViewHolder(View itemView) {        super(itemView);        tv = (TextView) itemView.findViewById(R.id.tv);    }}class RvAdapter extends RecyclerView.Adapter<RvViewHolder> {    Context context;    String[] items;    public RvAdapter(Context context, String[] items) {        this.context = context;        this.items = items;    }    @Override    public RvViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.apt_v7_recycler_view, parent, false);        return new RvViewHolder(view);    }    @Override    public void onBindViewHolder(RvViewHolder holder, int position) {        holder.tv.setText(items[position]);    }    @Override    public int getItemCount() {        return items.length;    }}rv.setAdapter(new RvAdapter(this, new String[]{        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D",        "A", "B", "C", "D"}));LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);linearLayoutManager.setOrientation(LinearLayout.VERTICAL);rv.setLayoutManager(linearLayoutManager);

布局管理器 与 横向列表

RecyclerView的另一个特点就是布局管理器(LayoutManager),个人觉得的一个比较方便的地方就是,终于可以方便的实现横向列表了!布局管理的作用就是负责摆放view以及回收view。
类似的

int findFirstVisibleItemPosition();int findLastVisibleItemPosition();

方法也在布局管理器中

设置item动画

rv.setItemAnimator(ItemAnimator);

分割线

由于RecyclerView的布局不固定,因此没有像ListView那样直接设定divider的方式,这些可能需要自己实现。一个简单粗鲁的纵向列表分割线如下:

rv.addItemDecoration(new RecyclerView.ItemDecoration() {    Paint paint = new Paint();    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDraw(c, parent, state);    }    @Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDrawOver(c, parent, state);        for (int i = 0, size = parent.getChildCount(); i < size; i++) {            View child = parent.getChildAt(i);            c.drawLine(child.getLeft(), child.getBottom(), child.getRight(), child.getBottom(), paint);        }    }    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);    }});

还可以参考:DividerItemDecoration

绑定事件

RecyclerView 没有 ListView 的 OnItemClick 等方法,所以,类似方法需要自己处理。

  1. 可以直接给itemView或者其子view绑定事件,绑定可以在viewHolder中进行事件绑定,也可以在adapter中进行。
    不过viewHolder中无法直观获取到原始的Item数据,需要进一步的处理(比如给itemView设置tag)才能实现获取原始数据的目的,所以怎么使用需要自己权衡。

    class RvViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView tv;public RvViewHolder(View itemView) {    super(itemView);    tv = (TextView) itemView.findViewById(R.id.tv);    itemView.setTag(this);    itemView.setOnClickListener(this);}@Overridepublic void onClick(View v) {    int vId = v.getId();    if (vId == R.id.tv) {        Toast.makeText(itemView.getContext(), getPosition() + "", Toast.LENGTH_SHORT).show();    }}

    }

  2. 可以使用

    addOnItemTouchListener(RecyclerView.OnItemTouchListener listener)

    来进行全局处理。当然,缺点就是需要处理事件细节,比较繁琐。

demo

demo

Android分享 Q群:315658668

更多相关文章

  1. android网易跟帖盖楼布局
  2. Android(安卓)DataBinding完全解析
  3. Android用户界面开发:TabHost
  4. Android自定义Dialog简单实例
  5. Android(安卓)Studio安装使用教程
  6. 高仿苹果通讯录布局
  7. 《宅男的android开发指南》(翻译)--5
  8. Android(安卓)Fragment基本介绍和用法
  9. Android(安卓)布局面试硬知识点

随机推荐

  1. android 数组排序
  2. 自定义ViewFlipperTest
  3. Android(安卓)广播接收器(短信拦截器 比较
  4. Android(安卓)decodeFile OutOfMemory
  5. java 封装解析 Json数据。
  6. 如何保持ListView中选中的Item高亮
  7. android 设置seekBar 和Progress背景色
  8. android native ALooper AHandler
  9. Android在锁屏状态下启动界面
  10. adb查看数据库