Android更强大的滚动控件RecyclerView(详解)
一.RecyclerView的基本用法
1.简介
RecyclerView是Android5.0后谷歌推出的一个用于在有限的窗口中展示 大量数据集的控件,它可以称为增强版的listview。不仅可以轻松实现和 listview一样的效果,同时又优化了listview的不足之处。
2.特点
1、支持局部刷新。
2、可以自定义item增删时的动画。
3、能够实现item拖拽和侧滑删除等功能。
4、默认已实现View的复用,而且回收机制更加完善。
3.基本用法
1、首先要在app/build.gradle文件中添加依赖库:
Comple/Implementation ‘com.android.support:recyclerview-v7:24.2.1’
2.自定义适配器
使用时需要新建FruitAdapter类,该类继承于RecyclerView.Adapter, 其中VH是我们创建的一个继承于RecyclerView.ViewHolder的静态内部类 该适配器类主要有3个方法和1个自定义ViewHolder组成:
(1)onCreateViewHolder: 创建ViewHolder并返回,后续item布局里控件都是从 ViewHolder中取出。 (2)onBindViewHolder:通过方法提供的ViewHolder,将数据绑定到ViewHolder中。 (3)getItemCount:获取数据源总长度。
使用方法:recycleview.setAdapter(adapter)
3.LayoutManager(布局管理器)
通过不同的布局管理器来控制item的排列顺序,负责item元素 的布局和复用。RecyclerView提供了三种布局管理器:
• LinearLayoutManager:线性布局,以垂直戒水平滚动列表方式 显示项目。
• GridLayoutManager:网格布局,在网格中显示项目。
• StaggeredGridLayoutManager:瀑布流布局,在分散对齐网格 中显示项目
4.代码部分
1 、案例效果
2 、类文件 MainActivity.java 代码:
package com.example.recyclerview1;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {//第一步:定义对象RecyclerView recyclerView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//第二步:绑定控件recyclerView=findViewById(R.id.recyclerview);//第三步:准备数据List<Fruit> fruitlist=new ArrayList<>();for (int i = 0; i <2 ; i++) {Fruit pineapple = new Fruit(R.drawable.pineapple, "菠萝", "¥16.9元/kg");fruitlist.add(pineapple);Fruit mango = new Fruit(R.drawable.mango, "芒果","¥29.9 元/kg");fruitlist.add(mango);Fruit pomegranate = new Fruit(R.drawable.pomegranate, "石榴","¥15元/kg");fruitlist.add(pomegranate);Fruit grape = new Fruit(R.drawable.grape, "葡萄","¥19.9 元/kg");fruitlist.add(grape);Fruit apple = new Fruit(R.drawable.apple, "苹果","¥20 元/kg");fruitlist.add(apple);Fruit orange = new Fruit(R.drawable.orange, "橙子","¥18.8 元/kg");fruitlist.add(orange);Fruit watermelon = new Fruit(R.drawable.watermelon, "西瓜","¥28.8元/kg");fruitlist.add(watermelon);}//第四步:设计每一行的子布局//第五步:创建适配器FruitAdapter adapter=new FruitAdapter(fruitlist);//第六步:将数据以垂直线性布局的方式显示出来LinearLayoutManager layoutManager=new LinearLayoutManager(this);recyclerView.setLayoutManager(layoutManager);recyclerView.setAdapter(adapter);}
}
3 、类文件 Fruit.java 代码参考:
package com.example.recyclerview1;
public class Fruit {private int imageID;private String name;private String price;public int getImageID() {return imageID;}public String getName() {return name;}public String getPrice() {return price;}public Fruit(int imageID, String name, String price) {this.imageID = imageID;this.name = name;this.price = price;}
}
4 、布局界面 fruit_item.xml 代码参考:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="horizontal"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/fruit_image"android:src="@drawable/apple"android:layout_width="100dp"android:layout_height="80dp"/><TextViewandroid:id="@+id/fruit_name"android:layout_gravity="center_vertical"android:textSize="30sp"android:textColor="#000000"android:text="name"android:layout_marginLeft="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/fruit_price"android:layout_gravity="center_vertical"android:textColor="#ff0000"android:text="price"android:textSize="30sp"android:layout_marginLeft="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
</LinearLayout>
5 、类文件 FruitAdapter.java 代码参考:
package com.example.recyclerview1;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
//1、将泛型指定为 FruitAdapter.ViewHolder
//2、按下 alt+enter 重写三种方法
//3、鼠标放在 ViewHolder 上,按下 alt+enter 创建 ViewHolder 类
//4、ViewHolder 类继承自 RecyclerView.ViewHolder,按下 alt+enter 创建构造方法
//5、鼠标放在 FruitAdapter 类中,按下 alt+insert 添加构造方法
public class FruitAdapter extends
RecyclerView.Adapter<FruitAdapter.ViewHolder> {private List<Fruit> mFruitlist;public FruitAdapter(List<Fruit> fruitList) {mFruitlist=fruitList;}//方法 1:创建 ViewHolder 实例,将加载出来的布局传入到构造函数中,最后将ViewHolder 实例返回@NonNull@Overridepublic FruitAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);ViewHolder holder=new ViewHolder(view);return holder;}//方法 2:每个子项滚动到屏幕内执行,通过 positon 得到当前项的实例,然后显示图片和文字@Overridepublic void onBindViewHolder(@NonNull FruitAdapter.ViewHolder holder, int
position) {Fruit fruit = mFruitlist.get(position);holder.fruitImage.setImageResource(fruit.getImageID());holder.fruitName.setText(fruit.getName());holder.fruitPrice.setText(fruit.getPrice());}//方法 3:返回数据源的长度@Overridepublic int getItemCount() {return mFruitlist.size();}public class ViewHolder extends RecyclerView.ViewHolder {ImageView fruitImage;TextView fruitName;TextView fruitPrice;public ViewHolder(@NonNull View view) {super(view);fruitImage=view.findViewById(R.id.fruit_image);fruitName=view.findViewById(R.id.fruit_name);fruitPrice=view.findViewById(R.id.fruit_price);}}
}
二.实现横向滚动和瀑布流布
1.横向滚动
1.横向滚动案例运行效果
2.代码
1.2.1 布局界面 fruit_item.xml 参考代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="120dp" android:orientation="vertical" android:layout_height="wrap_content"><ImageViewandroid:id="@+id/fruit_image"android:src="@drawable/apple"android:layout_gravity="left" android:layout_width="100dp"android:layout_height="80dp"/><TextViewandroid:id="@+id/fruit_name"android:layout_marginLeft="20dp"android:textSize="30sp"android:textColor="#000000"android:gravity="center_horizontal" android:text="name"android:layout_marginTop="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/fruit_price"android:layout_gravity="center_horizontal" android:textColor="#ff0000"android:text="price"android:textSize="20sp" android:layout_marginTop="10dp" android:layout_width="wrap_content"android:layout_height="wrap_content"/>
</LinearLayout>
1.2.2 类文件 MainActivity.java 代码:
//6、让数据显示在 recycleView 控件上LinearLayoutManager layoutManager=new LinearLayoutManager(this);// 添加此行内容 //让布局横向排列layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);recyclerView.setLayoutManager(layoutManager);recyclerView.setAdapter(adapter);
2.瀑布流布
1.瀑布流布局案例运行效果
2.代码
2.2.1 布局界面 fruit_item.xml 参考代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent" android:layout_margin="5dp" android:orientation="vertical"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/fruit_image"android:src="@drawable/apple"android:layout_gravity="left"android:layout_width="100dp"android:layout_height="80dp"/><TextViewandroid:id="@+id/fruit_name"android:layout_marginLeft="15dp"android:textSize="30sp"android:textColor="#000000"android:gravity="center_horizontal"android:text="name"android:layout_marginTop="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/fruit_price"android:layout_gravity="center_vertical"android:textColor="#ff0000"android:text="price"android:textSize="20sp"android:layout_marginTop="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
</LinearLayout>
2.2.2 类文件 MainActivity.java 参考代码:
//第六步:让数据显示在 recycleview 控件中
StaggeredGridLayoutManager layoutManager=new
StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
三.RecyclerView 的点击事件
与ListView不同, RecyclerView并没有提供类似于 setOnItemClickListener( )这样的注册监听器方法,而是需要我们 自己给子项具体的View去注册点击事件;
摒弃了ListView子项点击事件的监听器,所有的点击事件都有具体 的View去注册。
1.点击事件案例运行效果
2.代码部分
2.1、类文件 FruitAdapter.java 参考代码:
package com.example.recyclerview3;
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 java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class FruitAdapter extends
RecyclerView.Adapter<FruitAdapter.ViewHolder> {private List<Fruit> mFruitlist;public FruitAdapter(List<Fruit> fruitList) {mFruitlist=fruitList;}//方法 1:创建 ViewHolder 实例,将加载出来的布局传入到构造函数中,最后将ViewHolder 实例返回@NonNull@Overridepublic FruitAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);final ViewHolder holder=new ViewHolder(view);//布局的点击事件holder.fruitView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position=holder.getAdapterPosition(); Fruit fruit=mFruitlist.get(position); Toast.makeText(view.getContext(),"您点击的布局为:"+fruit.getName(),Toast.LENGTH_LONG).show(); } }); //图片的点击事件holder.fruitImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position=holder.getAdapterPosition(); Fruit fruit=mFruitlist.get(position); Toast.makeText(view.getContext(),"您点击的图片为:"+fruit.getName(),Toast.LENGTH_SHORT).show(); } });return holder;}//方法 2:每个子项滚动到屏幕内执行,通过 positon 得到当前项的实例,然后显示图片和文字@Overridepublic void onBindViewHolder(@NonNull FruitAdapter.ViewHolder holder, int position) {Fruit fruit = mFruitlist.get(position);holder.fruitImage.setImageResource(fruit.getImageID());holder.fruitName.setText(fruit.getName());holder.fruitPrice.setText(fruit.getPrice());}//方法 3:返回数据源的长度@Overridepublic int getItemCount() {return mFruitlist.size();}public class ViewHolder extends RecyclerView.ViewHolder {
//添加了 fruitView 变量来保存子项最外层布局的实例View fruitView; ImageView fruitImage;TextView fruitName;TextView fruitPrice;public ViewHolder(@NonNull View view) {super(view);fruitView=view;fruitImage=view.findViewById(R.id.fruit_image);fruitName=view.findViewById(R.id.fruit_name);fruitPrice=view.findViewById(R.id.fruit_price);}}
}
四.总结
五.参考文献
点击免费下载