原文:https://code.tutsplus.com/zh-...
原作:Ashraff Hathibelagal
翻译:作茧自缚

如果您有兴趣构建一个利用列表显示数据的Android应用程序,Android Lollipop具有两个新的轻松构建该类应用的小部件:RecyclerViewCardView。 使用这些小部件,很容易让您的应用程序的外观和感觉符合Google材料设计规范中提及的准则。

前提条件

构建这样的程序,您应该使用最新版本的Android Studio。 你可以从 Android 开发者网站获得。

1)支持旧版本

在写作的时候,小于 2%的 Android 设备运行 Android Lollipop系统。 然而,幸亏v7 支持库(Support Library),您可以在运行旧版本Android的设备上使用RecyclerViewCardView小部件,方法是将以下代码添加到项目build.grade文件中的依赖项(dependencies)部分:

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

2.创建CardView

CardView 是一个ViewGroup。像任何其他ViewGroup一样,它可以使用布局XML文件添加到您的ActivityFragment中。

要创建一个空的CardView,您必须将以下代码添加到布局XML中,如下代码片段所示:

<android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
 
</android.support.v7.widget.CardView>

作为一个更真实的例子,让我们现在创建一个LinearLayout并在其中放置一个CardView。 例如,CardView可以代表一个人,包含以下内容:

  • 一个TextView显示的人的名字

  • 一个TextView显示该人的年龄

  • 一个ImageView 来显示人的照片

XML会是下面这样子

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:padding="16dp"
    >
 
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv"
        >
 
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            >
 
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/person_photo"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginRight="16dp"
                />
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/person_name"
                android:layout_toRightOf="@+id/person_photo"
                android:layout_alignParentTop="true"
                android:textSize="30sp"
                />
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/person_age"
                android:layout_toRightOf="@+id/person_photo"
                android:layout_below="@+id/person_name"
                />
 
        </RelativeLayout>
 
    </android.support.v7.widget.CardView>
 
</LinearLayout>

如果此XML布局文件用作一个Activity的布局,将TextViewImageView 填充上有意义的值,那么在Android设备上选然后如下:

图片描述

3.创建 RecyclerView

步骤 1: 在布局中定义它

使用RecyclerView 实例稍微更复杂一点。 然而,在布局XML文件中定义它是相当简单的 您可以在布局中定义它,如下所示:

<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);

如果您确定RecyclerView的(item)数目不会改变,您可以添加以下内容来改善性能:

rv.setHasFixedSize(true);

步骤 2: 使用 LayoutManager

ListView不同,RecyclerView需要一个LayoutManager来管理其条目(item)的位置。 您可以通过扩展RecyclerView.LayoutManager类来定义自己的LayoutManager。 但是,在大多数情况下,您可以简单地使用一个预定义的LayoutManager子类:

  • LinearLayoutManager

  • GridLayoutManager

  • StaggeredGridLayoutManager

在本教程中,将使用LinearLayoutManager。 默认情况下,此LayoutManager子类将使您的RecyclerView看起来像一个ListView

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

步骤3:定义数据

就像ListView一样,RecyclerView需要一个适配器来访问它的数据。 但在创建适配器之前,让我们创建可以使用的数据。 创建一个简单的类来表示一个人,然后编写一个初始化Person对象List的方法:

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;
 
// This method creates an ArrayList that has three Person objects
// Checkout the project associated with this tutorial on Github if
// you want to use the same images.
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));
}

步骤4:创建适配器

要创建RecyclerView可以使用的适配器,必须扩展RecyclerView.Adapter。 该适配器遵循视图支架(view holder)设计模式,这意味着您可以自定义扩展RecyclerView.ViewHolder的类。 此模式最大限度地减少了对昂贵的findViewById方法的调用次数。

在本教程前面,我们已经为代表一个人的CardView定义了XML布局。 现在我们将重用那个布局。 在自定义ViewHolder的构造函数内,初始化属于RecyclerView条目的视图。

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方法开始。 它应该返回数据中现存的条目(item)数。 由于我们的数据是List的形式,我们只需要调用List对象的size方法:

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

接下来,覆盖onCreateViewHolder方法。 顾名思义,当需要初始化自定义ViewHolder时调用此方法。 我们指定RecyclerView每个条目应使用的布局。 这是通过使用LayoutInflater来填充(inflate)布局来完成的,将输出传递给自定义ViewHolder的构造函数。

覆盖onBindViewHolder以指定RecyclerView的每个项目的内容。 此方法与ListView适配器的getView方法非常相似。 在我们的示例中,您必须在此方法内设置CardView的名称,年龄和照片字段的值。

@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);
}

最后,您需要重写onAttachedToRecyclerView方法。 现在,我们可以简单地使用这个方法的超类实现,如下所示。

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

步骤5:使用适配器

现在适配器准备就绪,将以下代码添加到Activity中以通过调用适配器的构造函数和RecyclerViewsetAdapter方法来初始化并使用适配器:

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

步骤 6:编译并运行

当您在Android设备上运行RecyclerView示例时,应该会看到类似于以下结果的内容。

图片描述

结论

在本教程中,您已经学会了如何使用Android Lollipop中引入的CardViewRecyclerView小部件。 您还看到了如何在Material Design应用程序中使用这些小部件的示例。 请注意,尽管RecyclerView几乎可以完成ListView可以执行的所有操作,但对于小型数据集,使用ListView仍然是可取的,因为它需要较少的代码行。

有关CardViewRecyclerView类的更多信息,您可以查阅Android开发人员参考。

关于Envato艺云台

图片描述

Envato艺云台是数据资产和创造性人才汇聚的全球领先市场平台。全球数百万人都选择通过我们的市场平台、工作室和课程来购买文件、选聘自由职业者,或者学习创建网站、制作视频、应用、制图等所需的技能。我们的子网站包括Envato艺云台Tuts+ 网络,全球最大的H5、PS、插图、代码和摄影教程资源库,以及Envato艺云台市场,其中的900多万类数字资产均通过以下七大平台进行销售 - CodeCanyon、ThemeForest、GraphicRiver、VideoHive、PhotoDune、AudioJungle和3DOcean。


TriviumChina
81 声望2 粉丝

Envato艺云台是数据资产和创造性人才汇聚的全球领先市场平台。全球数百万人都选择通过我们的市场平台、工作室和课程来购买文件、选聘自由职业者,或者学习创建网站、制作视频、应用、制图等所需的技能。我们的子...