创建列表和卡片

阿里云产品限时红包,最高 ¥1888 元,立即领取

这是来自 Google 官方的 Material Design 培训教程的翻译,受个人水平所限,难免有翻译不对的地方,欢迎交流指正。

在应用程序中要创建具备 material design 风格的复杂列表和卡片,可以使用 RecyclerView 和 CardView 组件。

创建列表

RecyclerView 组件是一个更加高级,更加灵活的 ListView 版本。这个组件是这样一个容器,可以用来显示大量的数据集,并且通过维护有限数量的视图来非常高效的滚动。当你拥有大量的数据集,且其中的元素基于用户操作或者网络数据而在运行时改变时,使用 RecyclerView。

RecyclerView 通过提供以下两点来简化显示并处理大数据集:

  • 布局管理器来定位数据项
  • 为公共数据项的操作定义默认动画,如删除或者新增数据项

你可以灵活地为 RecyclerView 组件定义自定义的布局管理器和动画。

RecyclerView 组件

使用 RecyclerView 组件时,需要制定一个适配器和布局管理器。继承 RecyclerView.Adapter 类来创建一个适配器。具体的实现则依赖于特定的数据集和视图的类型。更多信息,可以查看下面的实例。

布局管理器在 RecyclerView 中定位项的视图,并决定当项的视图对用户不可见后何时被复用。要复用(或者回收)一个视图,布局管理器会要求适配从数据集中用一个不同的元素来替换视图的内容。用这种方式来复用视图可以避免由于不必要的视图创建和执行昂贵的 findViewById() 操作,从而提升性能。

RecyclerView 内置了下面的布局管理器:

  • LinearLayoutManager:在垂直或者水平滚动列表中显示项。
  • GridLayoutManager:通过网格显示项。
  • StaggeredGridLayout:在错落的网格中显示项。

继承 RecyclerView.LayoutManager 类来创建自定义的布局管理器。

Lists with RecyclerView

动画

在 RecyclerView 中添加和移除项的动画是默认支持的。要自定义这些动画,继承 RecyclerView.ItemAnimator 类并使用 RecyclerView.setItemAnimator() 方法。

实例

下面的代码实例展示如何添加 RecyclerView 到布局:

1
2
3
4
5
6
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

一旦添加一个 RecyclerView 组件到布局中,获得一个对象的句柄,并连接到布局管理器,然后关联一个需要显示的数据的适配器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MyActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

// 如果你已知 RecyclerView 的内容改变不会改变布局尺寸,使用这个设置可以提升效率。
mRecyclerView.setHasFixedSize(true);

// 使用线性布局管理器
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);

// 制定适配器
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
...
}

适配器提供对数据集中数据项的访问,为数据项创建视图,并且当原始数据项不再可见时使用新的数据项来替换这些视图的内容。下面的代码实例展示一个有字符串数组组成且使用 TextView 控件显示的简单数据集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;

// 为每个数据项的视图提供一个引用。复杂的数据项可能需要多余一个视图,并且在一个 view holder中为每个数据项的所有视图进行访问。
public static class ViewHolder extends RecyclerView.ViewHolder {
// 这个实例中,每个数据项是仅仅是一个字符串
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = v;
}
}

// 提供一个合适的构造方法(这取决于数据集类型)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}

// 创建新的视图(由布局管理器调用)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// 创建视图
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
// 设置视图的尺寸,外边距,内边距和布局参数
...
ViewHolder vh = new ViewHolder(v);
return vh;
}

// 替换视图的内容(由布局管理器调用)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - 从数据集中获取当前位置的元素
// - 用该元素替换视图的内容
holder.mTextView.setText(mDataset[position]);

}

// 返回数据集的大小(由布局管理器调用)
@Override
public int getItemCount() {
return mDataset.length;
}
}

创建卡片

CardView 集成自 FrameLayout 类,能够使显示在卡片中的信息在多个平台上拥有一致的外观。 CardView 控件可以拥有阴影和圆角。

使用 card_view:cardElevation 属性来创建带圆角的卡片。 CardView 在 Android 5.0 ( API 21) 及以上版本使用真正的海拔和动态阴影,在早先的版本中则使用可编程的阴影实现。更多信息,查看保持兼容性

使用下面的属性来自定义 CardView 组件的外观:

  • 在布局中使用 card_view:cardCornerRadius 属性来设置圆角半径。
  • 在代码中使用 CardView.setRadius 方法来设置圆角半径。
  • 使用 card_view:cardBackgroundColor 属性来设置卡片的背景色。

下面的代码实例展示如何在布局中包含 CardView 控件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
... >
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="200dp"
android:layout_height="200dp"
card_view:cardCornerRadius="4dp">

<TextView
android:id="@+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v7.widget.CardView>
</LinearLayout>

更多信息,查看 CardView 的 API 引用。

添加依赖

RecyclerView 和 CardView 控件是 Supprot V7 兼容包中的一部分。要在项目中使用这些组件,需要添加下面的 Gradle 依赖到应用模块中:

1
2
3
4
5
dependencies {
...
compile 'com.android.support:cardview-v7:21.0.+'
compile 'com.android.support:recyclerview-v7:21.0.+'
}