Skip to content

Instantly share code, notes, and snippets.

@johnbear724
Last active August 29, 2015 14:08
Show Gist options
  • Save johnbear724/3c1df87f3a001d9cfaa2 to your computer and use it in GitHub Desktop.
Save johnbear724/3c1df87f3a001d9cfaa2 to your computer and use it in GitHub Desktop.
创建列表和卡片

该文档翻译自 Android 5.0 文档中对 Material Design 的介绍,原文地址:http://developer.android.com/training/material/lists-cards.html

要在你的应用中使用 Material Design 创建复杂的列表和卡片,你可以使用 RecycleView 和 CardView 组件。

##创建列表

RecyclerView 是更高级和更灵活的 ListView。该组件是一个存放了大量数据集合的容器,它可以通过维护有限数量的视图,来有效率的滚动显示其中的大数据集。当你有一个需要在运行时根据用户的行为或网络事件而改变其中元素的数据集合时,你可以使用 RecyclerView 组件。

RecyclerView 类通过提供以下功能来简化大数据集合的显示和操作:

  • 用布局管理器(Layout manager)来放置项目
  • 为常见的项目操作提供默认动画,比如移除或添加项目。

你还可以用多种方式为 RecyclerVIew 组件定义自定义布局管理器(Layout manager)和动画。

图例1.The RecyclerView 组件

要使用 RecyclerView 组件,你需要指定一个适配器(Adapter)和布局管理器(Layout manager)。要创建一个适配器(Adapter),需要继承 RecyclerView.Adapter 类。实现该适配器的细节取决于你所指定的数据集和视图类型。更多信息请查看下面的示例。

一个布局管理器(Layout Manager)将每一项视图放置在 RecyclerView 的指定位置中,同时决定何时重用那些不再显示给用户的项目视图。要重用(或回收)一个视图,一个布局管理器将会询问适配器替换视图中的内容为数据集中其它的元素。通过这种方式回收视图,可以避免创建不必要的视图或是执行消耗资源的 findViewById() 查找,以此来提升性能。

RecyclerView提供了这些内建的布局管理器:

  • LinearLayoutManager 将项目展示在垂直或水平方向列表中
  • GridLayoutManager 将项目展示在网格中
  • StaggeredGridLayoutManager 将项目展示在交错的网格中。

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

图例2 - Lists with RecyclerView.

###动画

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

###示例

下面的代码示例演示了如何将 RecyclerView 添加到布局中:

<!-- 一个有着常用属性的 RecyclerView -->
<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 组件添加到你的布局中,获得该对象的操作权,将其连接到一个布局管理器,并设置一个适配器来显示数据:

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

        //如果知道内容的改变不会改变 Recycler 的
        // 布局大小,那么使用该设置可以提供性能
        mRecyclerView.setHasFixedSize(true);

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

        // 指定一个适配器(下个例子中)
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }
    ...
}

该适配器用于访问你的数据集中的每一项,为其创建视图,并在最初的项目不再显示时用新的数据项目替换掉该视图中的一些内容。下面的代码示例展示了一个数组集合的简单实现,其统一使用 TextView 显示字符串数组:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;

    // 为每个数据项提供一个视图的引用
    // 复杂的数据项每一项可能需要1个以上的视图
    // 并且在一个 ViewHolder 中提供对一个数据项的所有视图的访问
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // 在本例中每一个数据项只是一个字符串
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }

    // 提供适当的构造函数(基于数据集的类型)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // 创建新视图(由布局管理器(Layout manager)调用)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // 创建一个新视图
        View v = LayoutInflater.from(parent.getContext())
                               .inflate(R.layout.my_text_view, parent, false);
        // 设置视图的大小、边距、填充和布局管理器(Layout manager)
        ...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

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

    }

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

##创建卡片

CardView 继承自 FrameLayout 类让你可以用跨平台的统一外观在卡片中展示信息。CardView 组件可以有阴影和边角。

要创建有阴影的卡片,使用 card_view:cardElevation 属性。CardView 在 Android 5.0(API level 21)及以上使用真实的高度和动态阴影,回滚到之前的版本使用编程实现的阴影。更多信息,请查看兼容性维护。

使用这些特性来自定义 CardView 组件的外观:

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

下面的代码示例展示了如何在你的布局中包含 CardView 组件。

<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"
    ... >
    <!-- 包含了一个 TextView 的 CardView -->
    <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>

更多信息,请查看 API 文档 CardView 。

##添加依赖关系

RecyclerView 和 CardView 组件都是 v7 Support Libraries 的一部分。要在你的项目中使用这些组件,添加这些 Gradle 依赖项到你的应用模块:

dependencies {
    ...
    compile 'com.android.support:cardview-v7:+'
    compile 'com.android.support:recyclerview-v7:+'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment