目录
前言:RecycleView能够灵活实现大数据的展示,视图的复用管理比ListView更好,能够显示列表、网格、瀑布流等形式、且不同的ViewHolder能够实现item多元化的功能。
1.例子1:RecycleView的简单使用
注意:使用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();复写里面的方法,想要在外部调用就采用回调的方法。