欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 第十八课 强大的滚动控件 RecyclerView

程序员文章站 2022-05-14 19:31:46
...

步骤:

一、添加依赖库

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

二、在activity_mian.xml中,添加RecyclerView控件,并占据整个页面。

三、把你要在RecyclerView中展示的内容,设置成一个实体类Fruit,接着为RecyclerView的子项(展示的各个内容)制定一个我们自定义的布局fruit_item.xml(用来放在RecyclerView里面)。

四、新建适配器(FruitAdapter)

------------------------------------------------------------------------------------------》

Android 提供了一个更强大的滚动控件--RecyclerView。它是一个增强版的ListView。

新建RecyclerView项目。自动创建好项目,开始。

1、RecyclerView的基本用法

百分比布局类似,RecyclerView也属于新增控件,为了让RecyclerView在所有Android版本上使用,Android团队使用了同样

的方式,将RecyclerView定义在了support库中,因此,要想使用RecyclerView这个控件,首先在项目的build.gradle中添加对应的依赖库才行,代开app/gradle文件,在dependencies中添加如下内容:

dependencies { 

 implementation fileTree(dir: 'libs', include: ['*.jar']) 

 implementation 'com.android.support:appcompat-v7:26.1.0'

     .....

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

}

然后修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="com.example.recyclerviewtestb.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        />
</LinearLayout>

在布局中添加RecyclerView控件也是非常简单的,先为RecyclerView指定一个id。让RecyclerView占据整个布局的空间,由于RecyclerVeiw不是内置在系统SDK当中的,所以需要把完整的报名路径写出来。

我们先准备好一份同样的水果图片。放在drawable目录下,然后创建一个实体类Fruit,作为RecyclerView的适配类型,代码如下:

package com.example.recyclerviewtestb;

/**
 * Created by ZHJ on 2018/3/10.
 */
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类中只有两个字段,name表示水果的名称,imageId表示水果对那个图片的资源id。

然后我们需要为RecyclerView的子项制定一个我们自定义的布局,在layout目录下新建fruit_item.xml。

代码如下:

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

    <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类,让这个适配器继承自RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder。其中,ViewHolder是我们在FruitAdapter中定义的一个内部类,代码如下:

package com.example.recyclerviewtestb;

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

import java.util.List;

/**
 * Created by ZHJ on 2018/3/10.
 */

public class FruitAdpater extends RecyclerView.Adapter<FruitAdpater.ViewHolder> {
    private List<Fruit> mFruitList;
    static class ViewHolder extends  RecyclerView.ViewHolder{//内部类
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(View view){
            super(view);
            fruitImage= (ImageView)view.findViewById(R.id.fruit_image);
            fruitName = (TextView)view.findViewById(R.id.fruit_name);
        }
    }
    //构造函数
    public  FruitAdpater(List<Fruit>fruitList){
        mFruitList = fruitList;
    }

    @Override
       public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruitImage.setImageResource(fruit.getImageId());
        holder.fruitName.setText(fruit.getName());

    }

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

我们先定义了一个内部类ViewHolder,ViewHolder要继承自RecyclerView.ViewHolder。然后,ViewHolder的构造函数中要传入一个View参数,这个参数通常就是RecyclerView子项的最外层布局,那么我们就可以通过findViewById()方法来获取到布局中的ImageView和TextView的实例了。

    接着往下看,FruitApapter中也有一个构造函数,这个方法用于把要展示的数据源传进来,并赋值给一个全局变量mFruitList,我们后续的操作都将在这个数据源的基础上进行。

     继续往下看,由于FruitAdapter是继承自RecyclerView.Adapter的,那么就必须重写onCreateViewHolder(),onBindViewHolder()和getItemCount()这3个方法。

onCreateViewHolder()方法用于创建ViewHolder实例的,我们在这个方法中将fruit_item布局加载进来,然后创建一个ViewHolder实例,并把加载进来,然后创建一个ViewHolder实例,并把加载出来的布局传入到构造函数中,最后将ViewHolder()方法的实例返回。

onBindViewHolder()方法是用于对RecyclerView子项的数据进行赋值,会在每个子项被滚到屏幕内的时候执行,这里我们通过position参数得到当前项的Fruit实例,然后再将数据设置到ViewHolder的ImageView和TextView当中即可。

getItemCount()方法就简单了,它用于告诉RecyclerView一共有多少子项,直接返回数据源的长度九课就可以了。


五、

适配器准备好了之后,我们开始修改MainActivity中的代码,如下:


package com.example.recyclerviewtestb;

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

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);
        initFruit();//初始化水果数据
        RecyclerView recyclerView =(RecyclerView)findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        FruitAdpater adpater = new FruitAdpater(fruitList);
        recyclerView.setAdapter(adpater);
    }
    private  void  initFruit(){

       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);
        }

    }
}

这里使用了一个同样的initFruits()方法,用于初始化所有的水果数据。

接着在onCreate()方法中我们先获取RecyclerView的实例,然后创建一个LinearLayoutManager对象,并将它设置到RecyclerView中。LayoutManager用于指定RecyclerView的布局方式,这里使用的LinearLayoutManager是线性布局的意思。

接下来,我们创建了FruitAdaptper的实例,并将水果数据传入FruitAdapter的构造函数中,最后调用RecyclerView的setAdaper()方法来完成适配器设置,这样RecyclerView和数据之间的关联就建立完成了。


可以运行一下:

Android 第十八课 强大的滚动控件 RecyclerView


----------------------------------------------------------------》

实现横向滚动和瀑布流布局:

接下来,我们开始尝试实现横向滚动的效果,

首先,要对fruit_item.xml布局进行修改,因为这个布局里面的元素是水平排列的,适用于纵向滚动

如果我们要实现横向滚动,应该把fruit_item里的元素该成垂直排列。

修改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="match_parent">

    <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>

我们将Linearlayout改成垂直排列,并把宽度设为100dp。这里将宽度指定为固定值是因为每种水果的文字长度不一致。

修改MainActivity中的代码,如下所示:

package com.example.recyclerviewtestb;

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

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);
        initFruit();//初始化水果数据
        RecyclerView recyclerView =(RecyclerView)findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);
        FruitAdpater adpater = new FruitAdpater(fruitList);
        recyclerView.setAdapter(adpater);
    }
    ......
}

我们只是调用了LinearLayoutManager的setOrientation()方法来设置布局的排列方向,默认是纵向排列的,我们传入LinearLayoutManager.HORIZONTAL表示让布局横行排列,这样RecyclerView就可以横向滚动了。

运行一下:

Android 第十八课 强大的滚动控件 RecyclerView

RecyclerView的布局排列是由LayoutManager去管理,LayoutManager中指定了一套可扩展的布局排列接口,子类只要按照接口的规范来实现,就可以指定出各种不同排列方式的布局。


除了LinearLayoutManager之外,RecyclerView还给我们提供了GridLayoutManager和StaggeredGridLayoutManager这两种内置的布局排列方式。

GridLayoutManager可以用来实现网格布局。

StaggeredGridLayoutManager可以用来实现瀑布流布局。

《待续。。。。》