Android中的RecyclerView: 基础知识

135人阅读 评论(0) 收藏 举报

这些天我一直在研究RecyclerView,并想在此给各位分享一下到目前为止我的成果。

RecyclerView是什么?

RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式。它被作为ListView和GridView控件的继承者,在最新的support-V7版本中提供支持。

在开发RecyclerView时充分考虑了扩展性,因此用它可以创建想到的任何种类的的布局。但在使用上也稍微有些不便。这就是Android——要完成一件事情总不是那么容易。

如果使用RecyclerView,你需要了解以下三个元素:

RecyclerView.Adapter
LayoutManager
ItemAnimator
RecyclerView.Adapter

RecyclerView包含了一种新型适配器。它与现在使用的适配器类似,但也稍有不同,例如它需要使用ViewHolder。使用时需要重写两个主要方法:一个用来展现视图和它的持有者,而另一个用来把数据绑定到视图上。这么做的好处是,第一种方法只有当我们真正需要创建一个新视图时才被调用,不需要检查它是否已经被回收。

; html-script: false ]
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {

    private List<ViewModel> items;
    private int itemLayout;

    public MyRecyclerAdapter(List<ViewModel> items, int itemLayout) {
        this.items = items;
        this.itemLayout = itemLayout;
    }

    @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
        return new ViewHolder(v);
    }

    @Override public void onBindViewHolder(ViewHolder holder, int position) {
        ViewModel item = items.get(position);
        holder.text.setText(item.getText());
        holder.image.setImageBitmap(null);
        Picasso.with(holder.image.getContext()).cancelRequest(holder.image);
        Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image);
        holder.itemView.setTag(item);
    }

    @Override public int getItemCount() {
        return items.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView image;
        public TextView text;

        public ViewHolder(View itemView) {
            super(itemView);
            image = (ImageView) itemView.findViewById(R.id.image);
            text = (TextView) itemView.findViewById(R.id.text);
        }
    }
}

这是一个简单的适配器,但是事情逐渐开始变得有点复杂。在RecyclerView中,没有一个onItemClickListener方法(至少我没有发现)。所以适配器是一个处理事件的良好的候选人。

如果想要从适配器上添加或移除条目,需要明确通知适配器。这与先前的notifyDataSetChanged()方法稍微有些不同。

; html-script: false ]
public void add(ViewModel item, int position) {
    items.add(position, item);
    notifyItemInserted(position);
}

public void remove(ViewModel item) {
    int position = items.indexOf(item);
    items.remove(position);
    notifyItemRemoved(position);
}

LayoutManager

这个类决定视图被放在画面中哪个位置,但这只是它的众多职责之一。它可以管理滚动和循环利用。

LayoutManager只有一个叫做LinearLayoutManager的实现类,它有1500多行代码。但从这一点就可以看出它有多复杂。管理器可以模拟列表视图(包括横向和纵向),但没有页眉和页尾。

为LayoutManager编写子类不太适合新手,我们需要依靠社区来发掘RecyclerView的全部潜力。与这个例子一起,在短时间内我会上传一个GridView控件的实现。

我认为这背后的关键是要仿照LinearLayoutManager的代码创建一个BaseLayoutManager,并且基于此进行扩展。或许support-v7的最终版本会提供更多、更好的实现。

ItemAnimator

ItemAnimator会根据适配器上收到的通知动画显示视图组的修改。基本上,它会自动显示添加和移除条目动画。这也不是一个简单的类,但我们发现DefaultItemAnimator已经可以运行得很好了。

RecyclerView设置

所以最后,如果想要初始化一个运行的RecyclerView,你需要做这样的事情:

; html-script: false ]
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(new MyRecyclerAdapter(createMockList(), R.layout.item));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());

setHasFixedSize()方法用来使RecyclerView保持固定的大小,该信息被用于自身的优化。

总结

RecyclerView确实是一个强大的视图,它为开发者提供了无限的扩展能力。学习曲线可能会非常陡峭。但我相信,不久Android社区就会发布LayoutManager超棒的实现。

我在创建一个github仓库,在那里可以找到这个例子。它是我计划创建的一个扩展库的基础。你可以测试GridView的实现。欢迎各种形式的反馈。

Github上的RecyclerViewExtensions

这里写图片描述

查看评论

Android前沿技术—《RecyclerView》

RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性、插拔性、高度解耦性与可替代性比listview更好。本视频详细讲解了RecyclerView的基本使用、设置Listview& Gridview效果、瀑布流效果、分割线、自定义设置item的点击事件以及删除和增加数据等功能。
  • 2016年11月21日 11:10

RecyclerView 最佳入门

ListView和RecyclerView ListView和RecyclerView ListView和RecyclerView ListView和RecyclerView Lis...
  • gusgao
  • gusgao
  • 2016-08-22 01:36:27
  • 1129

Android中RecyclerView嵌套RecyclerView

  • 2016年07月08日 18:20
  • 42.96MB
  • 下载

Android中Recyclerview使用8----Recyclerview的嵌套

Recyclerview嵌套Recyclerview常规思路,在外层Recyclerview的条目中写内层Recyclerview Recyclerview嵌套ListView或者GridView往往...
  • zhaihaohao1
  • zhaihaohao1
  • 2016-07-31 19:33:31
  • 977

Android RecyclerView中实现ChecckBox单选的正确方式

以前使用recyclerView时,如果item中有单选框需要选中,一般的实现方式是创建一个boolean类型的ArrayList用来存储列表中每个item的checkBox是否选中,设置一个标志位m...
  • qq402164452
  • qq402164452
  • 2016-12-05 12:04:18
  • 4997

android recyclerview jar包

  • 2018年01月03日 15:46
  • 188KB
  • 下载

RecyclerView嵌套Spinner onItemSelected问题

在使用RecyclerView嵌套Spinner时会出现这样一个问题,当recyclerView翻页后更改spinner的selection状态,此时不会触发刚才点击的spinner的itemsele...
  • Allen056
  • Allen056
  • 2017-10-31 18:03:50
  • 327

Android开发之RecyclerView的使用全解

人最先衰老的不是容貌,而是那份不顾一切的闯劲。
  • dmk877
  • dmk877
  • 2016-03-07 14:21:22
  • 13606

Android开发之RecyclerView完全解析(一)

本文来自红黑联盟,主要介绍一下recyclerview的基本用法,请看文章!
  • itluochen
  • itluochen
  • 2016-08-16 19:49:55
  • 858

安卓中RecyclerView的使用

1.创建一个主布局文件,里面只有FrameLayout,用于放置所要托管的活动:activity_main.xml: xml version="1.0" encoding="utf-8"?> Fra...
  • u010273007
  • u010273007
  • 2017-05-02 16:39:41
  • 848
    个人资料
    持之以恒
    等级:
    访问量: 6万+
    积分: 1439
    排名: 3万+
    最新评论