Demo8 掌握RecyclerView(1):告别ListView

在Holo的年代,要说到最复杂的组件绝对要数ListView,基于其视图和数据的分离的设计,我们要使用它要费劲周折来写自己的适配器。如今,Google在新的V7支持包中开放了RecyclerView这个旨在替代ListView的全新组件,其功能和ListView大致相同,作为新一代的数据列表组件,其自由度更大,也就是我们可以通过代码来控制列表的各种行为,代价当然是更复杂的代码实现。不过这绝对不影响我们学习这个组件,毕竟它真的太受我们开发者喜爱了。关于RecyclerView更多介绍,请看CSDN上的这篇译文: RecycleView译文

我们今天要实现RecyclerView显示简单的列表,在此之前,要先讲解一下理论知识。
RecyclerView与ListView不同的是,RecyclerView不再负责Item的摆放等显示方面的功能。所有 和布局、绘制等方面的工作Google都其拆分成不同的类进行管理。所以开发者可以自定义各种各样满足定制需求的的功能类。
下面是一些和RecyclerView相关的非常重要的类列表。

类名说明
RecyclerView.Adapter托管数据集合,为每个Item创建视图
RecyclerView.ViewHolder承载Item视图的子视图
RecyclerView.LayoutManager负责Item视图的布局
RecyclerView.ItemDecoration为每个Item视图添加子视图,在Demo中被用来绘制Divider
RecyclerView.ItemAnimator负责添加、删除数据时的动画效果

或许对于刚接触RecyclerView的你来说会有点难理解,简单来说就是我们可以通过代码来设置、修改列表的各种状态和属性,以上的几个类是我们常用到的,不过不是必须的。对于一般的列表,有了适配器Adapter、视图加载器ViewHolder以及布局管理器LayoutManger就足够了。当然,要想实现更酷炫的效果,剩下的分割线管理器ItemDecoration和修改数据动画ItemAnimator(这个可以指定默认的效果,比较方便)必不可少。接下来就是你最期待的讲解Demo部分了。有一点要先说明,虽然RecyclerView是support-labrary的一部分,但是我们使用android studio时工程自动加载的support:appcompat-v7并没有包含RecyclerView,所以我们要在使用之前加入这个组件:

bulid.gradle:

compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:recyclerview-v7:23.3.0'

引用了组件,就可以在布局文件直接使用了,我们的这个历程布局比较直观,只加入一个RecyclerView:

main_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
</LinearLayout>

跟ListView类似,接下来我们要定义列表的子布局:

item_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:src="@android:drawable/sym_def_app_icon"
        android:layout_width="0sp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <LinearLayout
        android:layout_width="0sp"
        android:layout_height="wrap_content"
        android:layout_weight="5"
        android:orientation="vertical">
        <TextView
            android:id="@+id/name"
            android:text="name"
            android:textColor="@android:color/white"
            android:background="@android:color/holo_blue_light"
            android:layout_width="match_parent"
            android:layout_height="0sp"
            android:layout_weight="3"
            android:textSize="20sp" />
        <TextView
            android:id="@+id/messgae"
            android:text="message"
            android:layout_width="match_parent"
            android:layout_height="0sp"
            android:layout_weight="1"/>
    </LinearLayout>
</LinearLayout>

基本上布局部分的代码没有新的内容,这难不倒你,甚至到了设置RecyclerView的代码部分也没有多大问题,因为跟我们使用ListView基本类似,当然前提是仅仅要实现列表功能,并假设我们的适配器已经实现好(RecyclerView的一大特点是其提供了自己的适配器RecyclerView.Adapter,所以我们不用纠结于使用哪种类型的适配器),关于适配器的实现会放在本历程讲解的最后面。现在先来看看在主活动中的代码:

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private RecyclerAdapter adapter;
    private List<Message> list = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        recyclerView = (RecyclerView)findViewById(R.id.list);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));       //设置RecyclerLayout的显示方式,我们使用垂直布局
        initData();     //加载数据
        adapter = new RecyclerAdapter(list);
        recyclerView.setAdapter(adapter);       //加载适配器
    }

    private void initData() {
        String message = "abcdefghijklmnopqrstuvwxyz";
        for(int i = 0; i < 26; i ++) {
            list.add(new Message(String.format("%c%c%c", 'A'+i,'A'+i,'A'+i), message));
        }
    }

    public class Message {
        public String name;
        public String message;

        public Message(String name, String message) {
            this.name = name;
            this.message = message;
        }
    }
}

假设RecyclerAdapter是已经实现好的RecyclerView.Adpater的集成类。其实步骤大致上跟ListView相同的,不过还是要解释下。首先定义了一个Message类用来表示列表数据,其中只有两个与列表对应的字段name和message,接下来在initData方法中初始化数据。最后我们看到onCreate里面,对于下面几行代码:

recyclerView.setLayoutManager(new LinearLayoutManager(this));       //设置RecyclerLayout的显示方式,我们使用垂直布局
initData();     //加载数据
adapter = new RecyclerAdapter(list);
recyclerView.setAdapter(adapter);       //加载适配器

有必要解释下第一行,这个方法就是指定之前说明的重要的类的其中之一的RecyclerView.LayoutManager,基本上有四种种类型可以选择,垂直线性布局、横向线性布局、矩阵布局(GridLayoutManager)和流布局(StaggeredGridLayoutManager)。这里我们使用了垂直线性布局,因为对于LinearLayoutManager默认的效果是垂直,要想切换到横向的布局可以通过设置LinearLayoutManager的orientation属性完成:

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);

RecyclerAdpater是继承了RecyclerView.Adpater的类,接下来就让我们详细来讲解这个过程。首先上代码:

RecyclerAdapter.java

//这里的泛型类型是我们定义好的内部类RecyclerAdapter.ViewHolder
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
    List<?> list;       //数据集

    public RecyclerAdapter(List<?> list) {
        this.list = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //创建新View,被LayoutManager所调用
        ViewHolder holder = new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false));
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //将数据与界面进行绑定的操作
        holder.name.setText(((MainActivity.Message)list.get(position)).name);
        holder.message.setText(((MainActivity.Message)list.get(position)).message);
    }

    @Override
    public int getItemCount() {
        //获取数据的数量
        return list.size();
    }

    //内部类,继承RecyclerView.ViewHolder,持有每个Item的的所有界面元素
    class ViewHolder extends RecyclerView.ViewHolder {
        TextView name;
        TextView message;

        public ViewHolder(View view) {
            super(view);
            name = (TextView)view.findViewById(R.id.name);
            message = (TextView)view.findViewById(R.id.messgae);
        }
    }
}

我们应该从ViewHolder先入手,要注意,无论是RecyclerAdapter类实现时指定的泛型类型ViewHolder还是这里的内部类ViewHolder,都是我们的自己实现的继承自RecyclerView.ViewHolder的子类,就是上面的摆在最后的内部类。
其实要实现Adapter,需要重写三个方法:

方法名说明
onCreateViewHolder加载视图到ViewHolder
onBindViewHolder加载数据到ViewHolder
getItemCount返回数据的数量

不知道你对RecyclerView有没有更加深入的了解,有没有觉得其实也不过如此,没错,其实用起来还是挺像ListView的,当然如果只实现列表效果的话。最后效果如下:

Demo源码下载地址:Demo8:Recyclerview1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值