Android的RecyclerView简单使用的实例(附Demo)

本文介绍了RecyclerView的多种使用示例,包括线性、水平线性、网格视图、瀑布流布局等,还展示了添加图片、分割线、设置点击事件监听等操作,以及根据不同ViewHolder实现不同Item的方法,体现了RecyclerView在大数据展示和视图复用管理上的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


 目录

 

1.例子1:线性RecycleView的简单使用(类似ListVIew)

附加1:增加图片 

附加2:增加分割线

2.例子2:为RecyclerView设置点击事件监听

3.例子3:线性水平RecycleView的简单使用

4.例子4:网格视图的RecyclerView的简单使用(类似GridView)

附加1:为网格视图增加监听器

5.例子5:RecyclerView实现瀑布流布局

6.RecyclerView根据不同的ViewHolder实现不同的Item


Demo地址:https://github.com/zGuangYuan/Androidstudio_example 

前言:RecycleView能够灵活实现大数据的展示,视图的复用管理比ListView更好,能够显示列表、网格、瀑布流等形式、且不同的ViewHolder能够实现item多元化的功能。

 


1.例子1:线性RecycleView的简单使用(类似ListVIew)

先演示效果,如下:

注意:使用RecyceView需要添加一个RecycleView的依赖包:

compile 'com.android.support:recyclerview-v7:25.3.1'

导入哪个版本的依赖包,主要是看你是哪一个版本的RecycleView

在:你的SDK安装位置\extras\android\m2repository\com\android\support 文件夹下,就是依赖包

 

可以选择一个版本的依赖包,但是最好和你的 targetSdkVersion 是同版本的,否则会有警告

我在这里导入了一个 25.3.1版本的,因为我的targetSdkVersion 是28所以会警告,但是不影响使用

点击如下图标,导入依赖包,如果没有报错就是导入成功了:

 新建应用程序后,新建一个包RecycleView:

在这个包中新建一个Activity,命名为:RecycleViewActivity

在布局文件新建一个Button控件:

然后再RecycleViewActivity,绑定按钮的监听器(LinearRecycleViewActivity下面创建):

注意new Intent之后,还需要去启动这个Intent对象。startActivity(intent);

 

新建一个列表视图的Empty Activity,命名为:LinearRecycleViewActivity:

接下俩修改Manifest.xml文件,把默认的Activity设为 RecycleViewActivity

现在视图就是这样子:

点击上面的列表视图,进入 LinearRecycleViewActivity这个Activity:

 


 

 新建一个Adapter,继承自RecycleView的Adapter:

复写父类的方法:

看一下Adapter的原型函数:

可以看到Adapter有一个指定的泛型,这个泛型是继承自ViewHolder的,那我们就需要去创建这个泛型,然后传进去: 

在里面新建一个LInearVIewHolder继承ViewHolder:然后创建它的构造方法:

生成一个构造函数: 

然后把这个泛型,传进去给Adapter,然后修改复写函数的返回值,和传入参数类型:

 


接下来新建一个布局文件,用于在RecycleView显示的图片和文字之类的控件,命名为:layout_linearrv_item,根布局为:Linearlayout

然后画一个简单的TextView控件就可以了:


 现在主要是LinearAdapter.java这个类(继承自RecycleView的Adapter):

声明引用,创建一个构造函数引入Contex类型的变量,目的是引入加载需要用到的布局文件

在ViewHolder的子类的构造函数中,获取布局文件的控件对象: 

 复写onCreateViewHolder,在此方法中,调用LinearViewHolder,其构造函数传进去一个View类型的参数,把传进来的布局文件作为参数传进去,这样onCreateViewHolder函数就复写完成了:

 可以在onBindViewHolder方法中,去修改传进来布局文件的属性,修改为:Hello Yuan!

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

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

import com.example.yuan.e05_listview.R;

public class LinearAdapter extends RecyclerView.Adapter <LinearAdapter.LinearViewHolder>{
    //声明引用
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    //创建一个构造函数
    public LinearAdapter(Context context){
        this.mContext=context;
        //利用LayoutInflater把控件所在的布局文件加载到当前类当中
        mLayoutInflater = LayoutInflater.from(context);
    }
    //此方法要返回一个ViewHolder
    @Override
    public LinearAdapter.LinearViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        return new LinearViewHolder(mLayoutInflater.inflate(R.layout.layout_linearrv_item,parent,false));
    }
    //通过holder设置TextView的内容
    @Override
    public void onBindViewHolder(LinearAdapter.LinearViewHolder holder, int position) {
        holder.textView.setText("Hello Yuan!");
    }
    @Override
    public int getItemCount() {
        return 25;
    }
    class LinearViewHolder extends RecyclerView.ViewHolder{
        //声明layout_linearrv_item布局控件的变量
        private TextView textView;

        public LinearViewHolder(View itemView) {
            super(itemView);
            textView =(TextView) itemView.findViewById(R.id.TV_RVLinear_title_Id);
        }
    }
}

 已上编写完成之后基本完成,现在返回到LinearRecycleViewActivity.java中去生成这个RecycleView的Adapter的对象,然后把RecycleView所在的Activity传进去就OK了。


回到LinearRecycleViewActivity,修改如下:


运行应用程序:

点击按钮后如下显示,总共是25个条目,且背景为橙色,可以上下滑动看完全部条目:

附加1:增加图片 

可以让这些条目显示的多元化一点吗,当然可以,只需要在这基础上做一些简单的修改即可,比如,再让这个线性的RecycleView再加载一张网络图片,如何做?

首先修改下面layout_linearrv_item.xml这个布局文件,增加一个ImageView控件:

然后只需回到,LinearAdapter.java中作出一些简单的修改,去获取ImageView控件对象,然后修改控件的性就行了: 

 

第三方图片来源于网络,地址从下图赋值出来: 

提示:如何加载第三方网络图片:点我查看

 运行应用程序,如下图所示,总共有25个条目,可以向下滑动:

 附加2:增加分割线

可以看见两个条目之间是没有分割线的,但是我们可以去自定义分割线,然后应用到这个线性的RecyclerView上:

 使用addItemDecoration()方法可以用来设置分割线,传进去的参数是ItemDecotation类型的对象:

ItemDecotation是个抽象类 

 

里面有三个有效的方法:

方法一:

方法2:

方法三:

那我们使用方法三,因为他是抽象类,抽象类不能生成对象,所以我们去继承它,然后复写它的抽象方法:

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import com.example.yuan.e05_listview.R;

public class LinearRecycleViewActivity extends AppCompatActivity {

    private RecyclerView mRVMain;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_linear_recycle_view);

        mRVMain=(RecyclerView) findViewById(R.id.RV_main_Id);
        //设置线性布局管理器
        mRVMain.setLayoutManager(new LinearLayoutManager(LinearRecycleViewActivity.this));
        //Item装饰
        mRVMain.addItemDecoration(new MyDecoration());
        //设置Adapter
        mRVMain.setAdapter(new LinearAdapter(LinearRecycleViewActivity.this, new LinearAdapter.OnItemClickListener() {
            @Override
            public void OnClick(int position) {
                Toast.makeText(LinearRecycleViewActivity.this,"点击位置"+position,Toast.LENGTH_SHORT).show();
            }
        }));

        //继承ItemDecoration类

        }
        class MyDecoration extends RecyclerView.ItemDecoration{
        //复写getItemOffsets方法
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            outRect.set(0,0,0,getResources().getDimensionPixelOffset(R.dimen.dividerHeight));
        }
    }
}

 

 

新建一个resource文件命名为:decoration:

设置分割线属性:

注意:因为分割线是RecycleView的背景色(灰色),为了看的更清楚改一下, layout_linearav_ietm.xml布局文件中TextView控件的背景色。如下:

运行应用程序,就可以看到这个分割线了 ,每一个条目下面都有一个3dp的分割线:


2.例子2:为RecyclerView设置点击事件监听

方式一:直接在LinearAdapter的onBindViewHolder()方法中直接实现监听器接口,然后绑定监听器即可:

运行应用程序,点击列表视图:

点击条目,显示点击位置:

方式二:因为RecyclerView没有和ListView和GridView一样在外部有监听器接口,但是可以通过回调函数在外部实现监听的方法(不同类),想在LinearRecycleView.java中实现监听怎么做?

原理:在LinearAdapter这个类里面写一个接口,然后在LinearRecycleView实现这个接口,然后复写里面的Onclick()方法,通过函数的回调实现在LinearRecycleView这个类监听LinearAdapter这个类的事件:

1.在LinearAdapter定义一个接口

 接收来自外部的实现类对象: 

数据回调: 

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Context;
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 android.widget.Toast;

import com.bumptech.glide.Glide;
import com.example.yuan.e05_listview.R;

public class LinearAdapter extends RecyclerView.Adapter <LinearAdapter.LinearViewHolder>{
    //声明引用
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private OnItemClickListener mlistener;
    //创建一个构造函数
    public LinearAdapter(Context context,OnItemClickListener listener){
        this.mContext=context;
        //利用LayoutInflater把控件所在的布局文件加载到当前类当中
        mLayoutInflater = LayoutInflater.from(context);
        //从外部传进来一个OnItemClickListener子类的变量
        this.mlistener=listener;
    }
    //此方法要返回一个ViewHolder
    @Override
    public LinearAdapter.LinearViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        return new LinearViewHolder(mLayoutInflater.inflate(R.layout.layout_linearrv_item,parent,false));
    }
    //通过holder设置TextView的内容
    @Override
    public void onBindViewHolder(LinearAdapter.LinearViewHolder holder, final int position) {
        holder.textView.setText("模特");
        Glide.with(mContext).load("http://img.zcool.cn/community/01c8b4557aca590000002d5c60d85e.jpg@1280w_1l_2o_100sh.jpg").into(holder.imageView);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mlistener.OnClick(position);
                //点击后弹窗,显示点击位置
                //Toast.makeText(mContext,"点击位置"+position,Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    public int getItemCount() {
        return 25;
    }
    class LinearViewHolder extends RecyclerView.ViewHolder{
        //声明layout_linearrv_item布局控件的变量
        private TextView textView;
       private ImageView imageView;

        public LinearViewHolder(View itemView) {
            super(itemView);
            textView =(TextView) itemView.findViewById(R.id.TV_RVLinear_title_Id);
            imageView=(ImageView) itemView.findViewById(R.id.IVLinear_picture_Id);
        }
    }
    //定义一个接口
    public interface OnItemClickListener{
        //接口默认都是抽象的方法,且类型都是public
        void OnClick(int position);
    }
}

 

2.在LinearRecycleView.java中,

运行应用程序,执行的结果和方式一一样,方式二采用了回调的方法:

注意:那么设置长点击事件也是一样的,调用holder.itemView.setOnLongClickListener();复写里面的方法,想要在外部调用就采用回调的方法。


3.例子3:线性水平RecycleView的简单使用

先演示效果,如下:

新建一个Empty Activity,命名为:HorLinearRecyclerViewActivity

在activity_recycle_view.xml这个布局文件,增加一个按钮跳转到HorLinearRecyclerViewActivity这个Activity:

为按钮绑定监听器:

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.example.yuan.e05_listview.R;

public class RecycleViewActivity extends AppCompatActivity {

    //声明引用
    private Button mLinearButton;
    private Button mHorLinearButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycle_view);
        //获取控件对象
        mLinearButton=(Button) findViewById(R.id.button_linearRV_Id);
        mHorLinearButton=(Button) findViewById(R.id.button_linearRV2_Id);
        setlistener();
    }
    public void setlistener(){
        //生成监听器对象
        ButtonListener listener = new ButtonListener();
        //绑定监听器
        mLinearButton.setOnClickListener(listener);
        mHorLinearButton.setOnClickListener(listener);
    }
    class ButtonListener implements OnClickListener{
        @Override
        public void onClick(View v) {
            Intent intent =null;
            switch(v.getId()){
                case R.id.button_linearRV_Id:
                    intent = new Intent(RecycleViewActivity.this,LinearRecycleViewActivity.class);
                    break;
                case R.id.button_linearRV2_Id:
                    intent = new Intent(RecycleViewActivity.this,HorLinearRecyclerViewActivity.class);
            }
            startActivity(intent);
        }
    }
}

 


在水平滚动这个Activity的布局文件增加加一个 RecylcerView控件:

然后再HorLinearRecyclerViewActivity的Activity中新建一个线性布局管理器,把布局改成水平方向,并为RecyclerView对象设置一个适配器:

 还没有为这个RecyclerView对象设置适配器,下面为它设置一个Adapter.

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Button;
import android.widget.Toast;

import com.example.yuan.e05_listview.R;

public class HorLinearRecyclerViewActivity extends AppCompatActivity {

    private RecyclerView mhorRV;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hor_linear_recycler_view);

        mhorRV=(RecyclerView) findViewById(R.id.RV_hor_Id);
        //设置一个线性布局管理器,因为要设置方向,就不采用匿名内部类的方式了
        //生成一个LinearLayoutManager的对象
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(HorLinearRecyclerViewActivity.this);
        //设置这个线性布局管理器的方向,为水平方向
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //设置mHorRV的线性布局管理器
        mhorRV.setLayoutManager(linearLayoutManager);
        //设置适配器:Adapter
        mhorRV.setAdapter(new HorLinearAdapter(HorLinearRecyclerViewActivity.this));

    }
}

设置适配器:

由于和前面的LinearAdapter的内容基本类似,故直接复制一份就行了,只要在那基础上稍作修改就OK了:

操作:

弹出窗口,改个名字:HorLinearAdapter,

然后还需要item的布局文件,同样赋值一份,稍作修改就可以(其实直接用同一份也是可以的),为了规范化,再复制一份:

复制下面这份item布局文件:

复制后重命名:layout_horlinearrv_item.xml

修改下内容,把控件的Id也修改了: 

 

整体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/IVhorLinear_picture_Id"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="#4DB3B3"
        android:scaleType="centerCrop"
        android:layout_marginTop="5dp"/>
    <TextView
        android:id="@+id/TV_RVhorLinear_title_Id"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:text="Hello"
        android:gravity="center"
        android:textSize="20sp"
        android:background="#CBFAC0"
        />

</LinearLayout>

 回到HorLinearAdapter的布局修改成上面的那个布局文件

整体代码如下:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Context;
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 com.bumptech.glide.Glide;
import com.example.yuan.e05_listview.R;

public class HorLinearAdapter extends RecyclerView.Adapter <HorLinearAdapter.LinearViewHolder>{
    //声明引用
    private Context mContext;
    private LayoutInflater mLayoutInflater;

    //创建一个构造函数
    public HorLinearAdapter(Context context){
        this.mContext=context;
        //利用LayoutInflater把控件所在的布局文件加载到当前类当中
        mLayoutInflater = LayoutInflater.from(context);
    }
    //此方法要返回一个ViewHolder
    @Override
    public HorLinearAdapter.LinearViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new LinearViewHolder(mLayoutInflater.inflate(R.layout.layout_horlinearrv_item,parent,false));
    }
    //通过holder设置TextView的内容
    @Override
    public void onBindViewHolder(HorLinearAdapter.LinearViewHolder holder, final int position) {
        holder.textView.setText("模特");
        Glide.with(mContext).load("http://img.zcool.cn/community/01c8b4557aca590000002d5c60d85e.jpg@1280w_1l_2o_100sh.jpg").into(holder.imageView);

    }
    @Override
    public int getItemCount() {
        return 10;
    }
    class LinearViewHolder extends RecyclerView.ViewHolder{
        //声明layout_linearrv_item布局控件的变量
        private TextView textView;
       private ImageView imageView;

        public LinearViewHolder(View itemView) {
            super(itemView);
            textView =(TextView) itemView.findViewById(R.id.TV_RVhorLinear_title_Id);
            imageView=(ImageView) itemView.findViewById(R.id.IVhorLinear_picture_Id);
        }
    }

}

 运行应用程序,如下:

点击水平滚动视图,进入下面这个界面,可以左右滑动: 

水平视图同样可以设置分割线和点击监听事件,和上面一样的方法。不赘述 。


4.例子4:网格视图的RecyclerView的简单使用(类似GridView)

先演示效果,如下:

新建一个Empty Activity,命名为:GridRecyclerViewActivity.

然后在activity_recyle_view.xml,文件添加一个按钮控件:

在RecyclerViewActivity.java中为这个按钮绑定监听器,跳转到网格视图这个Activity(GridRecyclerViewActivity) 

整体代码如下:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.example.yuan.e05_listview.R;
import com.example.yuan.e06_gridview.GridView.GridViewActivity;

public class RecycleViewActivity extends AppCompatActivity {

    //声明引用
    private Button mLinearButton;
    private Button mHorLinearButton;
    private Button mGridButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycle_view);
        //获取控件对象
        mLinearButton=(Button) findViewById(R.id.button_linearRV_Id);
        mHorLinearButton=(Button) findViewById(R.id.button_linearRV2_Id);
        mGridButton=(Button) findViewById(R.id.button_gridRV3_Id);
        setlistener();
    }
    public void setlistener(){
        //生成监听器对象
        ButtonListener listener = new ButtonListener();
        //绑定监听器
        mLinearButton.setOnClickListener(listener);
        mHorLinearButton.setOnClickListener(listener);
        mGridButton.setOnClickListener(listener);
    }
    class ButtonListener implements OnClickListener{
        @Override
        public void onClick(View v) {
            Intent intent =null;
            switch(v.getId()){
                case R.id.button_linearRV_Id:
                    intent = new Intent(RecycleViewActivity.this,LinearRecycleViewActivity.class);
                    break;
                case R.id.button_linearRV2_Id:
                    intent = new Intent(RecycleViewActivity.this,HorLinearRecyclerViewActivity.class);
                case R.id.button_gridRV3_Id:
                    intent = new Intent(RecycleViewActivity.this, GridRecyclerViewActivity.class);
            }
            startActivity(intent);
        }
    }
}

回到activity_grid_recycler_view.xml这个布局文件,增加一个RecyclerView控件(设置了橙色背景):

回到对应的Activity(GridRecyclerView.java)声明一下上面的RecyclerView控件,设置布局管理器,设置适配器:


接下来就设置一个新建一个类,继承自RecyclerView的Adapter,然后复写它的方法,去写一个适配器,具体过程在第一个例子

已经详细展示,故不做多解释:

1.新建一个类,命名为:GridRecyclerViewAdapter,继承自RecyclerView的Adapter

2.复写Adapter的抽象方法:

3.查看Adapter的函数原型,有指定一个泛型,参数是ViewHolder的子类:

4.创建一个类继承ViewHolder,命名为MyViewHolder,并创建一个构造函数:

 

 5.然后把指定泛型修改一下,总共三处:

6. 新增加一个item的布局文件,为这个网格的RecyclerView提供空间的来源:

6.1新建一个布局文件,命名为:layout_grid_recyclerview_item.xml,根布局为线性布局:

6.2在这个Gird上,显示一张图片和一行文字,需要ImageView控件和TextView控件:

7.在GridRecyclerView.java的类中,新建一个构造函数,接受来自调用的Context,有两个作用,第一:用于第三方网络图片加加载,第二:用于把 layout_grid_recyclerview_item布局文件引入到当前类当中:

 8.复写第一个方法,把layout_grid_recyclerview_item布局文件加载到当前类当中:

这样的话MyViewHolder类就可以使用 layout_grid_recyclerview_item布局文件的控件了:

9.写MyViewHolder构造函数的东西:

10.为网格视图设置文字和图片属性:

现在这个Adapter的内容都编写完了:整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Context;
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 com.bumptech.glide.Glide;
import com.example.yuan.e05_listview.R;

public class GridRecyclerViewAdapter extends RecyclerView.Adapter<GridRecyclerViewAdapter.MyViewHolder> {
    //声明引用
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    //创建一个构造函数:
    public GridRecyclerViewAdapter(Context context){
        this.mContext=context;
        //利用LayoutInflater把控件所在的布局文件加载到当前类当中
        mLayoutInflater = LayoutInflater.from(context);
    }
    @Override
    public GridRecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //返回一个ViewHolder类型的数据,返回ViewHolder子类的对象,把布局文件加载到当前类返回
        return new MyViewHolder(mLayoutInflater.inflate(R.layout.layout_grid_recyclerview_item,parent,false));
    }

    @Override
    public void onBindViewHolder(GridRecyclerViewAdapter.MyViewHolder holder, int position) {
        holder.textView.setText("跑车");
        Glide.with(mContext).load("http://image.bitautoimg.com/appimage/media/20170317/w1600_h900_f6a5cad43dda443184bc2a6d5ecf44b4.jpeg").into(holder.imageView);
    }

    @Override
    public int getItemCount() {
        return 10;
    }
    public class MyViewHolder extends RecyclerView.ViewHolder{
        //声明引用
        private ImageView imageView;
        private TextView textView;
        public MyViewHolder(View itemView) {
            super(itemView);
            //获取控件对象
            imageView=(ImageView) itemView.findViewById(R.id.IV_GridRV_Id);
            textView=(TextView) itemView.findViewById(R.id.TV_GridRV_Id);
        }
    }
}

11.回到GridRecyclerView.java,生成适配器对象,调用适配器:

已上一个网格视图的基本设置已经完成。 


 运行这个应用程序,点击网格视图:

总共十个条目,且RecyclerView的背景色为橙色,图片宽度150*150dp。

附加1:为网格视图增加监听器

只需在onBindViewHolde()方法中设置,监听器即可,以弹窗的方式显示出来:

 运行应用程序,这样就可以监听啦,然后根据需要自己扩展:

这个同样可以设置按压效果,分割线等等的功能,在上面的例子已经展示的很清楚了。 


5.例子5:RecyclerView实现瀑布流布局

先演示效果,如下:

老样子,还是用实例来演示如何使用:

1.新建一个Empty Activity,命名为:WaterfallRecyclerViewActivity

2,然后在activity_recyle_view.xml,文件添加一个按钮控件,并绑定监听器:

绑定监听器,代码如下:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.example.yuan.e05_listview.R;
import com.example.yuan.e06_gridview.GridView.GridViewActivity;

public class RecycleViewActivity extends AppCompatActivity {

    //声明引用
    private Button mLinearButton;
    private Button mHorLinearButton;
    private Button mGridButton;
    private Button mWaterfallButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycle_view);
        //获取控件对象
        mLinearButton=(Button) findViewById(R.id.button_linearRV_Id);
        mHorLinearButton=(Button) findViewById(R.id.button_linearRV2_Id);
        mGridButton=(Button) findViewById(R.id.button_gridRV3_Id);
        mWaterfallButton=(Button) findViewById(R.id.button_waterfallRV4_Id);
        
        setlistener();
    }
    public void setlistener(){
        //生成监听器对象
        ButtonListener listener = new ButtonListener();
        //绑定监听器
        mLinearButton.setOnClickListener(listener);
        mHorLinearButton.setOnClickListener(listener);
        mGridButton.setOnClickListener(listener);
        mWaterfallButton.setOnClickListener(listener);
    }
    class ButtonListener implements OnClickListener{
        @Override
        public void onClick(View v) {
            Intent intent =null;
            switch(v.getId()){
                case R.id.button_linearRV_Id:
                    intent = new Intent(RecycleViewActivity.this,LinearRecycleViewActivity.class);
                    break;
                case R.id.button_linearRV2_Id:
                    intent = new Intent(RecycleViewActivity.this,HorLinearRecyclerViewActivity.class);
                    break;
                case R.id.button_gridRV3_Id:
                    intent = new Intent(RecycleViewActivity.this, GridRecyclerViewActivity.class);
                    break;
                case R.id.button_waterfallRV4_Id:
                    intent=new Intent(RecycleViewActivity.this,WaterfallRecyclerViewActivity.class);
            }
            startActivity(intent);
        }
    }
}

 


回到activity_waterfall_recycler_view.xml这个布局文件,增加一个RecyclerView控件(设置了橙色背景):

回到对应的Activity(WaterfallRecyclerView.java)声明一下上面的RecyclerView控件,设置布局管理器,设置适配器:


接下来就设置一个新建一个类,继承自RecyclerView的Adapter,然后复写它的方法,去写一个适配器:

新建一个类,命名为:WaterfallRecyclerViewAdapter

 前面的例子步骤已经很详细了,故这部分直接给代码,不做解释:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Context;
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 android.widget.Toast;

import com.bumptech.glide.Glide;
import com.example.yuan.e05_listview.R;

public class WaterfallRecyclerViewAdapter extends RecyclerView.Adapter<WaterfallRecyclerViewAdapter.MyViewHolder> {
    //声明引用
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    //创建一个构造函数:
    public WaterfallRecyclerViewAdapter(Context context){
        this.mContext=context;
        //利用LayoutInflater把控件所在的布局文件加载到当前类当中
        mLayoutInflater = LayoutInflater.from(context);
    }
    @Override
    public WaterfallRecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //返回一个ViewHolder类型的数据,返回ViewHolder子类的对象,把布局文件加载到当前类返回
        return new MyViewHolder(mLayoutInflater.inflate(R.layout.layout_waterfall_recyclerview_item,parent,false));
    }

    @Override
    public void onBindViewHolder(WaterfallRecyclerViewAdapter.MyViewHolder holder, final int position) {
        if(position % 2 ==0){
            holder.imageView.setImageResource(R.drawable.flower);
        }else{
            holder.imageView.setImageResource(R.drawable.girls);
        }

        //设置监听器,短点击
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext,"短点击位置"+position,Toast.LENGTH_SHORT).show();
            }
        });
        //长点击
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Toast.makeText(mContext,"长点击位置"+position,Toast.LENGTH_SHORT).show();
                return false;
            }
        });
    }

    @Override
    public int getItemCount() {
        return 30;
    }
    public class MyViewHolder extends RecyclerView.ViewHolder{
        //声明引用
        private ImageView imageView;
        public MyViewHolder(View itemView) {
            super(itemView);
            //获取控件对象
            imageView=(ImageView) itemView.findViewById(R.id.IV_waterfallRV_Id);

        }
    }
}

 新增加一个item的布局文件,为这个网格的RecyclerView提供空间的来源:

1.新建一个布局文件,命名为:layout_waterfall_recyclerview_item.xml 

因为是显示瀑布流形式,所以只放两张大小不一样的图片,所以需要两个ImageView控件:

需要两张大小不一样的图片,直接从网上下本地,然后放到drawable文件夹下,待会引用就行了:

 

 


在最后一步设置一个Adapter就行了:

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;

import com.example.yuan.e05_listview.R;

public class WaterfallRecyclerViewActivity extends AppCompatActivity {
    //声明引用
    private RecyclerView mWaterfallRV;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_waterfall_recycler_view);
        //获取控件对象
        mWaterfallRV=findViewById(R.id.RV_waterfall_Id);
        //设置布局管理器,两个参数,如果后面参数是垂直就代表第一个是几列,如果是水平,第一个就代表行数
        mWaterfallRV.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
        //设置Adapter
        mWaterfallRV.setAdapter(new WaterfallRecyclerViewAdapter(WaterfallRecyclerViewActivity.this));

    }
}

 

运行应用程序:

 点击按钮:

可以看到话和人交替显示,根据图片的大小,不规则的显示,这就是所谓的瀑布流形式:

这样看起来好像有点不舒服:我们可以使用addItemDecoration()方法给他加一个分割线,看起来好看一点:

在values文件下,修改decoration.xml,增加一个2dp的间距

  

修改WaterfallRecyclerViewActivity.java,如下,如何使用设置分割线在上面也有说过:

注意:分割线是RecyclerView的分割线,所以分割线应该是橙色的。 

整体代码如下:

package com.example.yuan.e06_gridview.RecycleView;

import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;

import com.example.yuan.e05_listview.R;

public class WaterfallRecyclerViewActivity extends AppCompatActivity {
    //声明引用
    private RecyclerView mWaterfallRV;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_waterfall_recycler_view);
        //获取控件对象
        mWaterfallRV=findViewById(R.id.RV_waterfall_Id);
        //设置布局管理器,两个参数,如果后面参数是垂直就代表第一个是几列,如果是水平,第一个就代表行数
        mWaterfallRV.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
        //设置Adapter
        mWaterfallRV.setAdapter(new WaterfallRecyclerViewAdapter(WaterfallRecyclerViewActivity.this));
        //设置分割线
        mWaterfallRV.addItemDecoration(new MyDecoration());

    }
    class MyDecoration extends RecyclerView.ItemDecoration {
        //复写getItemOffsets方法
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            //设置距离为2dp
            int distance = getResources().getDimensionPixelOffset(R.dimen.pirtureDistance);
            //设置上下左右全部有2dp的分割线
            outRect.set(distance, distance, distance,distance);
        }
    }
}

运行应用程序,可以看到上下左右全部都有1dp的分割线,现在看起来就层次分明了,还可以上下滑动:总共有30张图片

在上面的程序已经设置了点击事件了,所以点击会提示,点击的位置:

 本例子完。


 6.RecyclerView根据不同的ViewHolder实现不同的Item

效果展示,如下:

是什么意思呢,大概解释一下,我们在RecyclerView本来只是引用一个布局文件来显示,比如里面有图片和文字结合,我们如果使用引用布局文件,就全部是显示这个布局文件有的内容,但是我们现在是向让他显示多个布局文件的东西,我们在一个RecyclerView,先引用布局A(只有文字),再引用布局B(只有图片),其实就像我们微信聊天页面一样,一会是文字,一会是图片,或语音或视频,使用RecyclerView就可以根据不同的ViewHolder在一个页面把不同类型的item显示出来。

 

我们使用RecyclerView,通过前面的例子知道,RecyclerView有很多种布局方式,有线性水平线性垂直,网格布局,瀑布流布局,我们使用它就得选择一个适合我们需要展示东西的性质,选一个简单的:

采用线性垂直的方式,然后引用两个ViewHolder.

直接在第一个例子的基础之上修改:

1.现在需要两个布局文件,第一个布局文件不修改。如下:

第二个布局文件,命名为:layout_linearrv_item2.xml,只有一个imageView控件


 回到LinearAdapter.java文件中,去修改代码:

1.首先复写public int getItemViewType(int position)方法,此方法可以知道当前的item的位置,可以根据不同的位置设置不同的ViewHolder;

2.新增一个ViewHolder它对应的布局文件是:layout_linearrv_item2

3.修改onCreateViewHolder(ViewGroup parent, int viewType)方法

注意下面这几个地方都是需要修改的:

4.修改onBindViewHolder()方法,根据不同的ViewHolder显示不同的item.

加载的图片来自网络:

整体代码:

package com.example.yuan.e06_gridview.RecycleView;

import android.content.Context;
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 android.widget.Toast;

import com.bumptech.glide.Glide;
import com.example.yuan.e05_listview.R;

public class LinearAdapter extends RecyclerView.Adapter <RecyclerView.ViewHolder>{
    //声明引用
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private OnItemClickListener mlistener;
    //创建一个构造函数
    public LinearAdapter(Context context,OnItemClickListener listener){
        this.mContext=context;
        //利用LayoutInflater把控件所在的布局文件加载到当前类当中
        mLayoutInflater = LayoutInflater.from(context);
        //从外部传进来一个OnItemClickListener子类的变量
        this.mlistener=listener;
    }
    //此方法要返回一个ViewHolder
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        if (viewType ==0){
            return new LinearViewHolder(mLayoutInflater.inflate(R.layout.layout_linearrv_item,parent,false));
        }else{
            return new LinearViewHolder1(mLayoutInflater.inflate(R.layout.layout_linearrv_item2,parent,false));
        }

    }
    //通过holder设置TextView的内容
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
       if (getItemViewType(position) ==0){
           ((LinearViewHolder)holder).textView.setText("Hello Yuan");
           Glide.with(mContext).load("http://img.daimg.com/uploads/allimg/140729/3-140H9215513.jpg").into(((LinearViewHolder) holder).imageView);
       }else{
           Glide.with(mContext).load("http://img.article.pchome.net/01/57/12/92/pic_lib/wm/Jaguar-XFR-S-2014-widescreen-15.jpg").into(((LinearViewHolder1) holder).imageView);
       }
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mlistener.OnClick(position);
                //点击后弹窗,显示点击位置
                //Toast.makeText(mContext,"点击位置"+position,Toast.LENGTH_SHORT).show();
            }
        });

    }

    //获取位置
    @Override
    public int getItemViewType(int position) {
        if(position % 2==0){  //位置是偶数
            return 0;
        }else { //位置是奇数
            return 1;
        }
    }

    @Override
    public int getItemCount() {
        return 25;
    }
    class LinearViewHolder extends RecyclerView.ViewHolder{
        //声明layout_linearrv_item布局控件的变量
        private TextView textView;
        private ImageView imageView;

        public LinearViewHolder(View itemView) {
            super(itemView);
            textView =(TextView) itemView.findViewById(R.id.TV_RVLinear_title1_Id);
            imageView=(ImageView) itemView.findViewById(R.id.IV_Linear_picture1_Id);
        }

    }
    class LinearViewHolder1 extends RecyclerView.ViewHolder{
        //声明layout_linearrv_item布局控件的变量
        private ImageView imageView;

        public LinearViewHolder1(View itemView) {
            super(itemView);
            imageView=(ImageView) itemView.findViewById(R.id.IVLinear_picture_Id2);

        }
    }
    //定义一个接口
    public interface OnItemClickListener{
        //接口默认都是抽象的方法,且类型都是public
        void OnClick(int position);
    }
}

已上代码部分完成,下面运行程序看一看 


 运行应用程序:

点击列表视图,可以看到两个布局切换,且偶数位是一张图片和文字结合的ViewHolder,奇数位只有一张图片:

设置了监听事件:

小结:在这基础上我们可以添加很多种ViewHolder显示,奇偶数位置,只是为了调试方便设置,在实际应用中,可能根据传进来的参数,或者不同类型指定不同的ViewHolder来显示,都是可可以的,多个ViewHolder同样可以是网格布局,瀑布流的形式。

所以说RecyclerView是灵活的,他可以做到ListView和GridView能做到的东西,也能做到他们做不到的东西,使用起来相对于前面两种稍微复杂一点点,但是灵活性还是很好的。


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值