Android RecyclerView,Android CardView示例教程

Android RecyclerView and Android CardView got introduced in Android Lollipop with Material Design. For those who’re not aware of Material Design, its a comprehensive guide of UI Widgets introduced since Android 5.0 and it improves the visual appeal of the apps.

Android RecyclerViewAndroid CardView通过Material DesignAndroid Lollipop中引入。 对于那些不知道Material Design的用户,它提供了全面的UI Widgets指南,自Android 5.0起引入,它改善了应用程序的视觉吸引力。

Android RecyclerView (Android RecyclerView)

Android RecyclerView is a more advanced, powerful and flexible version of the ListView. Android RecyclerView is similar to ListView except that it forces us to use RecyclerView.ViewHolder class to hold the elements which is not a compulsion in ListView.

Android RecyclerView是ListView的更高级,强大和灵活的版本。 Android RecyclerView与ListView相似,除了它迫使我们使用RecyclerView.ViewHolder类来保存不是ListView中的强制元素。

As the name suggests, Android RecyclerView is used to reuse cells when scrolling up and down by recycling the items in the list. Another improvement in RecyclerView is that it allows us to set the LayoutManagers dynamically at runtime, unlike the ListView which was only available in a Vertical scrolling List. RecyclerView allows us to set the following types of Layouts at runtime.

顾名思义,当通过滚动列表中的项目上下滚动时,Android RecyclerView用于重用单元格。 RecyclerView的另一个改进是,它使我们可以在运行时动态设置LayoutManager ,这与ListView不同,后者仅在垂直滚动列表中可用。 RecyclerView允许我们在运行时设置以下类型的布局。

  • LinearLayoutManager : it supports both vertical and horizontal lists

    LinearLayoutManager :它支持垂直和水平列表
  • StaggeredLayoutManager : it supports staggered lists

    StaggeredLayoutManager :它支持交错列表
  • GridLayoutManager : it supports displaying grids as seen in GalleryView earlier

    GridLayoutManager :它支持显示网格,如先前在GalleryView中所见

Android RecyclerView类 (Android RecyclerView Classes)

  • The RecyclerView.ItemAnimator class provides better support to animating the views unlike the ListViews

    与ListViews不同, RecyclerView.ItemAnimator类为动画视图提供了更好的支持。
  • The RecyclerView.ItemDecorator class provides better support when it comes to adding borders and dividers thereby giving huge control to us

    RecyclerView.ItemDecorator类在添加边框和分隔线时提供了更好的支持,从而为我们提供了巨大的控制权

Hence a RecyclerView is more customizable when compared to ListView and gives greater control to the users.
The RecyclerView is available in the support library. So we need to modify our gradle script to add the following dependency.

因此,与ListView相比,RecyclerView更可自定义,并为用户提供更好的控制。
RecyclerView在支持库中可用。 因此,我们需要修改gradle脚本以添加以下依赖关系。

dependencies {
       compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
 }

Android CardView (Android CardView)

Android CardView UI component shows information inside cards. This component is generally used to show contact information. This component is available in another support library so we have to add its dependency too.

Android CardView UI组件显示卡内的信息。 此组件通常用于显示联系信息。 该组件在另一个支持库中可用,因此我们也必须添加其依赖项。

dependencies {
        compile 'com.android.support:cardview-v7:21.0.0-rc1'
        compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
 }

Android CardView widget allows us to control the background color, shadow, corner radius, elevation etc. For using the custom attributes in XML, we need to add the following namespace declaration to the parent layout. Following is the namespace declaration with some attributes from our project.

Android CardView小部件允许我们控制背景颜色,阴影,角半径,高程等。要在XML中使用自定义属性,我们需要在父布局中添加以下名称空间声明。 以下是命名空间声明,其中包含我们项目中的某些属性。

<android.support.v7.widget.CardView
        android:id="@+id/card_view"
        xmlns:card_view="https://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardBackgroundColor="@color/grey_300"
        card_view:cardCornerRadius="10dp"
        card_view:cardElevation="5dp"
        card_view:cardUseCompatPadding="true">

The important attributes used above are:

上面使用的重要属性是:

  • card_view:cardCornerRadius : Used to set the corner radius in our layouts

    card_view:cardCornerRadius :用于设置布局中的拐角半径
  • card_view:cardBackgroundColor : Used to set the background color of the view

    card_view:cardBackgroundColor :用于设置视图的背景色

In our example project, we’ll add a RecyclerView to display a list of CardViews that contains Android Version Names and Numbers along with a sample logo. The CardView onclick is programmed to remove that Card from the list. We’ve added a menu option in the ActionBar to add back the removed cards in order.

在示例项目中,我们将添加一个RecyclerView来显示CardViews列表,其中包含Android版本名称和编号以及示例徽标。 CardView onclick已编程为从列表中删除该卡。 我们在ActionBar中添加了一个菜单选项,以便按顺序添加回去的卡片。

Note: The logo images are taken at random from Google. So sizes would vary.

注意:徽标图像是从Google随机获取的。 因此大小会有所不同。

Android RecyclerView和CardView示例 (Android RecyclerView and CardView Example)

The project consists of a MainActivity that displays the RecyclerView. The CardView is added to the RecyclerView from the CustomAdapter class. The DataModel is used to retrieve the data for each CardView through getters. The MyData class holds the arrays of textviews and drawables along with their ids.

该项目由一个MainActivity组成,它显示RecyclerView 。 CardView从CustomAdapter类添加到RecyclerView。 DataModel用于通过getter检索每个CardView的数据。 MyData类保存textviews和drawable的数组以及它们的ID。

Android RecyclerView和CardView示例代码 (Android RecyclerView and CardView Example Code)

The activity_main.xml holds the RecyclerView inside a RelativeLayout as shown below.

activity_main.xml将RecyclerView保留在RelativeLayout中,如下所示。

activity_main.xml code:

activity_main.xml代码:

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="@color/grey_300"
    >

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

</RelativeLayout>

Android CardView layout is defined below:

Android CardView布局定义如下:

cards_layout.xml code:

cards_layout.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:tag="cards main container">

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        xmlns:card_view="https://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardBackgroundColor="@color/color_white"
        card_view:cardCornerRadius="10dp"
        card_view:cardElevation="5dp"
        card_view:cardUseCompatPadding="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >

            <ImageView
                android:id="@+id/imageView"
                android:tag="image_tag"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:src="@drawable/ic_launcher"/>

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:layout_weight="2"
                android:orientation="vertical"
                >

                <TextView
                    android:id="@+id/textViewName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:layout_marginTop="10dp"
                    android:text="Android Name"
                    android:textAppearance="?android:attr/textAppearanceLarge"/>

                <TextView
                    android:id="@+id/textViewVersion"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:layout_marginTop="10dp"

                    android:text="Android Version"
                    android:textAppearance="?android:attr/textAppearanceMedium"/>

            </LinearLayout>
        </LinearLayout>

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

</LinearLayout>

Android CardView holds an ImageView along with two TextViews in a Nested Linear Layout. The menu_main.xml contains a single item to add back the cards removed.

Android CardView在嵌套线性布局中包含一个ImageView以及两个TextViews。 menu_main.xml包含一个单项,用于添加回去的卡。

menu_main.xml code:

menu_main.xml代码:

<menu xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    tools:context=".MainActivity">
    <item android:id="@+id/add_item"
        android:title="Add"
        android:orderInCategory="100"
        app:showAsAction="always"/>
</menu>

The MainActivity.java class is defined below :

MainActivity.java类的定义如下:

package com.journaldev.recyclerviewcardview;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private static RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private static RecyclerView recyclerView;
    private static ArrayList<DataModel> data;
    static View.OnClickListener myOnClickListener;
    private static ArrayList<Integer> removedItems;

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

        myOnClickListener = new MyOnClickListener(this);

        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        recyclerView.setHasFixedSize(true);

        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        data = new ArrayList<DataModel>();
        for (int i = 0; i < MyData.nameArray.length; i++) {
            data.add(new DataModel(
                    MyData.nameArray[i],
                    MyData.versionArray[i],
                    MyData.id_[i],
                    MyData.drawableArray[i]
            ));
        }

        removedItems = new ArrayList<Integer>();

        adapter = new CustomAdapter(data);
        recyclerView.setAdapter(adapter);
    }


    private static class MyOnClickListener implements View.OnClickListener {

        private final Context context;

        private MyOnClickListener(Context context) {
            this.context = context;
        }

        @Override
        public void onClick(View v) {
            removeItem(v);
        }

        private void removeItem(View v) {
            int selectedItemPosition = recyclerView.getChildPosition(v);
            RecyclerView.ViewHolder viewHolder
                    = recyclerView.findViewHolderForPosition(selectedItemPosition);
            TextView textViewName
                    = (TextView) viewHolder.itemView.findViewById(R.id.textViewName);
            String selectedName = (String) textViewName.getText();
            int selectedItemId = -1;
            for (int i = 0; i < MyData.nameArray.length; i++) {
                if (selectedName.equals(MyData.nameArray[i])) {
                    selectedItemId = MyData.id_[i];
                }
            }
            removedItems.add(selectedItemId);
            data.remove(selectedItemPosition);
            adapter.notifyItemRemoved(selectedItemPosition);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        if (item.getItemId() == R.id.add_item) {
           //check if any items to add
            if (removedItems.size() != 0) {
                addRemovedItemToList();
            } else {
                Toast.makeText(this, "Nothing to add", Toast.LENGTH_SHORT).show();
            }
        }
        return true;
    }

    private void addRemovedItemToList() {
        int addItemAtListPosition = 3;
        data.add(addItemAtListPosition, new DataModel(
                MyData.nameArray[removedItems.get(0)],
                MyData.versionArray[removedItems.get(0)],
                MyData.id_[removedItems.get(0)],
                MyData.drawableArray[removedItems.get(0)]
        ));
        adapter.notifyItemInserted(addItemAtListPosition);
        removedItems.remove(0);
    }
}

The removeItems() method is invoked from the listener method to remove the CardView clicked. Its respective id is stored in an array to retrieve later. To add the view later we’ve implemented another method named addRemovedItemToList(). In this method, we add that view at a predefined position in the list and remove its id from the removedItems array. The CustomAdapter is notified in both the cases.

从侦听器方法中调用removeItems()方法以删除单击的CardView。 其各自的ID存储在数组中以供以后检索。 为了稍后添加视图,我们实现了另一个名为addRemovedItemToList()方法。 在此方法中,我们将该视图添加到列表中的预定义位置,并从removedItems数组中删除其ID。 在两种情况下都会通知CustomAdapter。

The CustomeAdapter.java class is defined below :

CustomeAdapter.java类的定义如下:

package com.journaldev.recyclerviewcardview;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {

    private ArrayList<DataModel> dataSet;

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        TextView textViewName;
        TextView textViewVersion;
        ImageView imageViewIcon;

        public MyViewHolder(View itemView) {
            super(itemView);
            this.textViewName = (TextView) itemView.findViewById(R.id.textViewName);
            this.textViewVersion = (TextView) itemView.findViewById(R.id.textViewVersion);
            this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView);
        }
    }

    public CustomAdapter(ArrayList<DataModel> data) {
        this.dataSet = data;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent,
                                           int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cards_layout, parent, false);

        view.setOnClickListener(MainActivity.myOnClickListener);

        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {

        TextView textViewName = holder.textViewName;
        TextView textViewVersion = holder.textViewVersion;
        ImageView imageView = holder.imageViewIcon;

        textViewName.setText(dataSet.get(listPosition).getName());
        textViewVersion.setText(dataSet.get(listPosition).getVersion());
        imageView.setImageResource(dataSet.get(listPosition).getImage());
    }

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

In the above code, we’ve implemented our own ViewHolder by extending RecyclerView.ViewHolder. The view is inflated from the cards_layout.xml which we had defined in the layouts directory. The onClickListener in the MainActivity is attached to this view in the below snippet.

在上面的代码中,我们通过扩展RecyclerView.ViewHolder实现了自己的ViewHolder。 该视图从我们在布局目录中定义的cards_layout.xml进行了cards_layout.xml 。 以下代码段将MainActivity中的onClickListener附加到此视图。

view.setOnClickListener(MainActivity.myOnClickListener);

An ArrayList stores all the data in the form of a DataModel class object in an ArrayList and adds them to the respective cards in the list.

ArrayList将所有数据以DataModel类对象的形式存储在ArrayList中,并将它们添加到列表中的各个卡中。

The DataModel.java and MyData.java class which contains the data specific to this application are given below :

下面给出了包含该应用程序特定数据的DataModel.javaMyData.java类:

package com.journaldev.recyclerviewcardview;

public class DataModel {

    String name;
    String version;
    int id_;
    int image;

    public DataModel(String name, String version, int id_, int image) {
        this.name = name;
        this.version = version;
        this.id_ = id_;
        this.image=image;
    }

    public String getName() {
        return name;
    }

    public String getVersion() {
        return version;
    }

    public int getImage() {
        return image;
    }

    public int getId() {
        return id_;
    }
}
package com.journaldev.recyclerviewcardview;

public class MyData {

    static String[] nameArray = {"Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich","JellyBean", "Kitkat", "Lollipop", "Marshmallow"};
    static String[] versionArray = {"1.5", "1.6", "2.0-2.1", "2.2-2.2.3", "2.3-2.3.7", "3.0-3.2.6", "4.0-4.0.4", "4.1-4.3.1", "4.4-4.4.4", "5.0-5.1.1","6.0-6.0.1"};

    static Integer[] drawableArray = {R.drawable.cupcake, R.drawable.donut, R.drawable.eclair,
            R.drawable.froyo, R.drawable.gingerbread, R.drawable.honeycomb, R.drawable.ics,
            R.drawable.jellybean, R.drawable.kitkat, R.drawable.lollipop,R.drawable.marsh};

    static Integer[] id_ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
}

Below is the output produced by our android RecyclerView and CardView example application.

以下是我们的android RecyclerView和CardView示例应用程序产生的输出。

As you can see the removed item is always added at the third index (fourth position in the list)

如您所见,被删除的项目始终添加在第三个索引(列表中的第四个位置)上

This brings an end to this tutorial about android RecyclerView and CardView. You can download the Android RecyclerView CardView Example Project from the below link.

这结束了有关android RecyclerView和CardView的本教程。 您可以从下面的链接下载Android RecyclerView CardView示例项目

翻译自: https://www.journaldev.com/10024/android-recyclerview-android-cardview-example-tutorial

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,我可以回答你的问题。 首先,要实现Android RecyclerView的两行多列布局,你需要设置LayoutManager。在这个LayoutManager中,你需要使用GridLayoutManager,将显示的项目数设置为2并充满整个可用区域。以下是设置LayoutManager的代码示例RecyclerView recyclerView = findViewById(R.id.recycler_view); GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2); recyclerView.setLayoutManager(gridLayoutManager); 接下来,你需要为RecyclerView创建一个Adapter。为了实现两行多列布局,你可以使用cardView作为每个项目的容器。以下是创建Adapter的代码示例: public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { private List<MyData> myDataList; public MyAdapter(List<MyData> myDataList) { this.myDataList = myDataList; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_card_view, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { MyData data = myDataList.get(position); holder.bindData(data); } @Override public int getItemCount() { return myDataList.size(); } } 其中,R.layout.my_card_view是每个项目的布局文件。你需要创建该文件并定义cardView,并将其中的内容绑定到ViewHolder对象上。 要添加一个底部提示,你可以使用RecyclerView的addOnScrollListener() 方法。在scroll事件触发时,你可以检查RecyclerView是否滑动到了底部,如果是,你可以在底部添加一个提示。以下是添加底部提示的代码示例recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int visibleItemCount = gridLayoutManager.getChildCount(); int totalItemCount = gridLayoutManager.getItemCount(); int firstVisibleItemPos = gridLayoutManager.findFirstVisibleItemPosition(); if ((visibleItemCount + firstVisibleItemPos) >= totalItemCount && firstVisibleItemPos >= 0) { // 已滑动到底部 // 添加提示到底部 } } }); 希望这可以帮助你实现你的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值