与ListView对比优势:
1.运行效率更高。
2.能实现横向滚动与瀑布流布局。
官方更加推荐Recycler控件,但因为后期加入又要使所有版本的Android都能使用,所以把它放入了support库当中,所以使用的第一步,是在项目的build.gradle中添加相应的依赖库。
打开app/build.gradle文件,在dependencies中添加
implementation 'com.android.support:recyclerview-v7:28.0.0'
不同项目不同版本的依赖库版本号不同,截图给大家参考下我现在的,不必模仿:
点击Sync Now同步。
那么如何使用这个控件呢?点击activity_main.xml,修改代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
中间的这段代码,就是调用RecyclerView控件。因为它并不是内置在SDK中的控件,所以使用时要写出完整的路径名。
接下来我们以水果列表显示为例分别实现四个功能,每个功能讲解结束都会附上Demo,请自行下载:
1:实现纵向滚动
2:实现横向滚动
3:实现瀑布流布局
4:实现recyclerView点击事件
功能一:实现纵向滚动
先创建一个Fruit类Fruit.java,代码如下:
package com.example.recyclerviewtest;
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
再创建对于一个水果,它的单个布局文件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_height="wrap_content">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
</LinearLayout>
接下来为RecyclerView准备一个适配器,新建FruitAdapter类文件FruitAdapter.java,让这个个适配器继承自RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder。其中ViewHolder是我们在FruitAdapter中定义的一个内部类,代码如下:
package com.example.recyclerviewtest;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
//传入view参数,这个参数就是RecyclerView的子项布局,这样就能找到里面各个控件的id
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
}
}
//将要展示的数据源传入
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
//下面三个函数必须要重写
//载入fruit_item布局,创建ViewHolder实例
@NonNull
@Override
public 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;
}
//为每个RecylerView对象赋值
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
holder.fruitImage.setImageResource(fruit.getImageId());
}
//计算一共多少个子项
@Override
public int getItemCount() {
return mFruitList.size();
}
}
适配器已经准备好了,我们现在可以使用RecyclerView了,修改MainActivity.java:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
//获取recyclerView实例
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
//创建LinerLayoutManager对象,其中LayoutManager用于指定RecyclerView的布局方式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//设置布局
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//关联RecyclerView与数据
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for(int i = 0; i < 2; i++) {
Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
fruitList.add(mango);
}
}
}
接下来就可以运行了,以后如果需要不同的内容,结构,更改部分代码即可,代码结构不会改变。下面是运行效果:
功能一Demo文件下载:https://download.csdn.net/download/qq_38367681/12167275
功能二:实现横向滚动
要实现横向拉动其实很简单,因为ListView的布局是由自身去管理的,而RecyclerView把这个工作交给了LayoutManager,LayoutManager中制定了一套可扩展的布局排列接口,子类只要按照接口的规范来实现,就能定制出各种不同排列的布局了。
第一步,肯定要先改写子项的布局,使它横向排列看起来更舒服,所以修改fruit_item.xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"/>
</LinearLayout>
第二部,只需要调整layoutManager的排列方向。默认是垂直方向,所以纵向排列的代码并没有加入方向调整,实现功能二,我们只需要加入一行代码,设置排列方向为水平:
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
所以MainActivity.java代码变成如下:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
//获取recyclerView实例
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
//创建LinerLayoutManager对象,其中LayoutManager用于指定RecyclerView的布局方式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//设置线性布局为水平线性布局,默认为垂直,所以不设置效果会跟listview一样
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//设置布局
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//关联RecyclerView与数据
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for(int i = 0; i < 2; i++) {
Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
fruitList.add(mango);
}
}
}
运行结果如下:
功能二Demo文件下载:https://download.csdn.net/download/qq_38367681/12168921
功能三:实现瀑布流布局
同功能二,为了瀑布流布局更美观,肯定是先修改fruit_item.xml文件,然后再修改MainActivity.java中的LayoutManager,使其变成瀑布流布局。当然也只是一行代码:
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
共接收两个参数,第一个参数是列数,第二个参数是布局的排列方向。
fruit_item.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dp"/>
</LinearLayout>
MainActivity.java代码如下:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
//获取recyclerView实例
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
//创建一个StaggeredGridLayoutManager实例,共接收两个参数,第一个参数是列数,第二个参数是布局的排列方向
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
//设置布局
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//关联RecyclerView与数据
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for(int i = 0; i < 2; i++) {
Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
fruitList.add(apple);
Fruit banana = new Fruit("BananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBananaBanana", R.drawable.banana_pic);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("GrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrapeGrape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
fruitList.add(mango);
}
}
}
运行结果如下:
功能三Demo文件下载:https://download.csdn.net/download/qq_38367681/12169036
功能四:RecyclerView的点击事件。
RecyclerView所有的点击事件都需要具体的View控件去注册,其实这样反而会更舒服,我们可以为任何我们想要触发点击事件的控件,布局,甚至是RecyclerView列表子项添加点击事件。为RecyclerView子项添加点击监听时,我们在ViewHolder中添加fruitView变量用来保存子项最外层的布局实例,然后在onCreateViewHolder()方法中注册点击事件即可。为子项的控件添加点击监听时,直接用viewholder里的布局控件注册点击即可。代码如下:
FruitAdapter.java
package com.example.recyclerviewtest;
import android.media.Image;
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 androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
//传入view参数,这个参数就是RecyclerView的子项布局,这样就能找到里面各个控件的id
static class ViewHolder extends RecyclerView.ViewHolder {
//整个子项布局
View fruitView;
ImageView fruitImage;
TextView fruitName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
fruitView = itemView;
fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
}
}
//将要展示的数据源传入
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
//下面三个函数必须要重写
//载入fruit_item布局,创建ViewHolder实例
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull 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 v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "you clicked view" + fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
//为每个子项的图片添加点击监听
holder.fruitImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "you clicked image" + fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
return holder;
}
//为每个RecylerView对象赋值
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitName.setText(fruit.getName());
holder.fruitImage.setImageResource(fruit.getImageId());
}
//计算一共多少个子项
@Override
public int getItemCount() {
return mFruitList.size();
}
}
运行结果如下:
点击图片时
当点击文字(其实代表的是图片文字整个子项被点击,因为给图片注册了点击监听,所以只能点文字表明点击了整个子项)
功能四Demo文件下载:https://download.csdn.net/download/qq_38367681/12169120
直接复制使用吧,祝愉快