«

学习RecyclerView和CardView

时间:2024-3-2 19:16     作者:韩俊     分类: Android


之前在GitHub上看一些开源项目源码时,发现有这两个控件,貌似之前一直没有见到过,所以现在决定学习下。
先来看RecyclerView,RecyclerView 组件是一个更高级和伸缩性更强的 ListView,是Android Lollipop中的新widget,使用时和LIstView相比多了一个RecyclerView.LayoutManager,用来测量和定位RecyclerView中每个item的视图,并决定什么时候重用不可见的元素视图。要重用(或回收)视图时,layout manager 会让 adapter 用另外的元素内容替换视图内的内容。

RecyclerView 提供以下内建的 layout manager:
LinearLayoutManage:用于显示横向或纵向的滚动列表
GridLayoutManager :用于显示方格元素
StaggeredGridLayoutManager :在 staggered 方格中显示元素

而且还提供了默认的动画,添加和删除元素的动画在 RecyclerView 中是默认被启用的。要自定义动画,你需要继承RecyclerView.ItemAnimator 类,使用RecyclerView.setItemAnimator()方法。

CardView多和RecyclerView一起使用,作为RecyclerView的item,CardView 是一个容器类,继承于 FrameLayout 类,也就拥有FrameLayout 的属性,CardView的最主要的一个特点是可以说设置阴影和圆角:

使用以下属性来自定义CardView:
使用card_view:cardCornerRadius在layout中设置圆角
使用CardView.setRadius在代码中设置圆角
使用card_view: cardElevation来设置 shadow
使用card_view:carBackgroundColor来设置背景颜色,可以让card看起来在浮在背景上

有了一个大概的认识后,就具体通过一个例子学习:

为了使用RecyclerView和CardView需要引入v7 Support Library,这里使用的是Android studio,在项目中的 build.grade文件中的dependencies块中加入如下代码,就可以在老的Android版本使用:

dependencies {
    ...
    compile 'com.android.support:cardview-v7:21.0.+'
    compile 'com.android.support:recyclerview-v7:21.0.+'
}

1、 先创建一个CardView
利用一个LinearLayout来放置 CardView,CardView包含两个TextView,用来显示人名和年龄,一个ImageView,用来显示头像。这里要注意因为CardView 是由the Android v7 support library提供,所以他的attributes 不在android:这个命名空间中,必须定义自己的命名空间,并且作为cardView属性的前缀,例如

    xmlns:card_view="http://schemas.android.com/apk/res-auto"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <android.support.v7.widget.CardView
        android:id="@+id/cv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardBackgroundColor="#6495ed"
        card_view:cardCornerRadius="20dp"
        card_view:cardElevation="14dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp">

            <ImageView
                android:id="@+id/person_photo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginRight="16dp"
                android:src="@drawable/ic_launcher" />

            <TextView
                android:id="@+id/person_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_toRightOf="@+id/person_photo"
                android:text="张三"
                android:textSize="30sp" />

            <TextView
                android:id="@+id/person_age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/person_name"
                android:layout_toRightOf="@+id/person_photo"
                android:text="20 岁" />

        </RelativeLayout>

    </android.support.v7.widget.CardView>

</LinearLayout>

效果如下:

可以看到CardView四个边角有一个圆角,并且有一个shadow,同时有一个背景色。

2、 创建一个RecyclerView:
步骤一: 在Layout定义

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rv"
    />

在activity 中获取到:

RecyclerView rv = (RecyclerView)findViewById(R.id.rv);

步骤二:使用LayoutManager
与ListView不同,RecyclerView 需要LayoutManager来管理其中的Item的位置,可以通过继承RecyclerView.LayoutManager类定义自己的LayoutManager,但是,大多数情况下,只需要使用
LayoutManager 预先定义的子类:
LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager

这里使用LinearLayoutManager

LinearLayoutManager llm = new LinearLayoutManager(context);
rv.setLayoutManager(llm);

步骤三:定义Data

同LIstView相同,RecyclerView也需要一个adapter来获取它的数据,在创建一个adapter之前,先创建一个person类,然后写一个方法来初始化一个List的Person对象:

class Person {
    String name;
    String age;
    int photoId;

    Person(String name, String age, int photoId) {
        this.name = name;
        this.age = age;
        this.photoId = photoId;
    }
}

private List<Person> persons;
private void initializeData(){
    persons = new ArrayList<>();
    persons.add(new Person("Emma Wilson", "23 years old", R.drawable.emma));
    persons.add(new Person("Lavery Maiss", "25 years old", R.drawable.lavery));
    persons.add(new Person("Lillie Watts", "35 years old", R.drawable.lillie));
}

步骤四:创建一个adapter

继承RecyclerView.Adapter,这个adapter遵循View holder的设计,意味着要定义一个类继承 RecyclerView.ViewHolder,在ListView中一般是我们自己定义的。

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{

    public static class PersonViewHolder extends RecyclerView.ViewHolder {      
        CardView cv;
        TextView personName;
        TextView personAge;
        ImageView personPhoto;

        PersonViewHolder(View itemView) {
            super(itemView);
            cv = (CardView)itemView.findViewById(R.id.cv);
            personName = (TextView)itemView.findViewById(R.id.person_name);
            personAge = (TextView)itemView.findViewById(R.id.person_age);
            personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
        }
    }

}

接下来,定义一个构造方法,可以将RecyclerView 用来显示的数据传进来,这里,我们的数据格式是一个Person的List

List<Person> persons;

RVAdapter(List<Person> persons){
    this.persons = persons;
}

RecyclerView.Adapter有三个我们必须重写的抽象方法,先来看getItemCount()方法,这个方法返回传进来的数据的条数:

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

接下来是重写onCreateViewHolder ()方法,这个方法在自定的ViewHolder 需要初始化的时候调用,需要指明RecyclerView 每个Item需要使用的layout,通过LayoutInflater加载进来。

@Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
    PersonViewHolder pvh = new PersonViewHolder(v);
    return pvh;
}

最后,重写onBindViewHolder ()方法,来指明每个Item中的内容,有点类似ListView的adapter中的getView()方法。

@Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
    personViewHolder.personName.setText(persons.get(i).name);
    personViewHolder.personAge.setText(persons.get(i).age);
    personViewHolder.personPhoto.setImageResource(persons.get(i).photoId);
}

步骤五:使用Adapter

这个就很简单了.

RVAdapter adapter = new RVAdapter(persons);
rv.setAdapter(adapter);

最后的效果如下:

标签: android

热门推荐