RecyclerView的案例和解析

本文详细介绍了Android中的RecyclerView,对比ListView阐述其优势,并提供了一个完整的使用案例,包括UI布局、数据填充、布局管理器的使用及点击事件的实现,帮助开发者理解和掌握RecyclerView的使用技巧。

一个RecyclerView的案例和解析


之前介绍了ListView的使用,如果在使用ListView的时候不使用一些技巧,listView的性能是不好的,而且它的扩展性也不好,只能支持纵向滚动效果,如果想实现横向的滚动效果,ListView是无法实现的。因此Android 提供了一个更强大的滚动控件RecyclerView, 它不仅能实现与ListView相同的效果,同时也补充了ListView的不足之处。

开始介绍RecyclerView的使用


RecyclerView是定义在support库中的新增的控件,所以使用的时候需要在项目的build.gradle文件中dependencies闭包中添加依赖
 compile 'com.android.support:recyclerview-v7:26.0.0-alpha1', 添加完后,需要点击Sync now 进行同步。

 

 如下:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
    compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
    testCompile 'junit:junit:4.12'
}


API代码引入后,就可以正常使用,RecyclerView的实现略微复杂,但是代码清晰容易理解。


UI布局


Activity_main.xml 中使用RecyclerView标签的时候要添加完整包名,因为它并不在内置的sdk系统中,然后设定id, 并且配置高度和宽度都是match_parent,这样RecyclerView将充满整个布局空间。




    

Fruit_item.xml 中实现了RecyclerView子项的布局设计,如下代码所示:




    

    


数据填充

1- 首先也是定义数据类, Fruit.xml



public class Fruit {

    private String name;
    private int imageID;

    public Fruit(String name, int imageID){
        this.name=name;
        this.imageID=imageID;
    }

    public int getImageID() {
        return imageID;
    }

    public String getName() {
        return name;
    }
}

2- 其次就是适配器的实现,FruitAdapter.java - RecyclerView的适配器需要继承RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,其中viewHolder是FruitAdapter的一个内部类。
代码详解如下

package com.motorola.recyclerviewtest;

import android.provider.ContactsContract;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;


public class FruitAdapter extends RecyclerView.Adapter {

    private List mFruitList;

    static class ViewHolder extends RecyclerView.ViewHolder {
        private View fruitView;
        private ImageView fruit_image;
        private TextView fruit_name;

        public ViewHolder(View itemView) {
            super(itemView);
            fruitView=itemView;
            fruit_image = (ImageView) itemView.findViewById(R.id.fruit_image);
            fruit_name = (TextView) itemView.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List fruits) {
        this.mFruitList = fruits;
    }

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

        viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int postion = viewHolder.getAdapterPosition();
                Fruit fruit =mFruitList.get(postion);
                Toast.makeText(view.getContext(), "You click "+fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });

        viewHolder.fruit_image.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                int position= viewHolder.getAdapterPosition();
                Fruit fruit=mFruitList.get(position);
                Toast.makeText(view.getContext(), "You click " +fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruit_image.setImageResource(fruit.getImageID());
        holder.fruit_name.setText(fruit.getName());
    }

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

ViewHolder:
ViewHolder 内部类需要继承RecyclerView.ViewHolder,然后ViewHolder的构造函数中需要传入一个View参数,这个参数就是RecyclerView子项的最外层布局,接下来就可以通过findViewById
()方法来获取布局中ImageView和TextView实例。

FruitAdapter
类继承自RecyclerView.Adapter,在该类构造函数中需要传输数据源,接下来的各种操作都是基于数据源操作的。同时需要重写RecyclerView.Adapter的三个方法onCreateViewHolder(), onBindViewHolder(), getItemCount()



  • onCreateViewHolder(): 这个方法是用于创建viewHolder实例的,首先调用LayoutInflater去加载fruit_item子布局到父布局中,然后将创建的布局View实例作为参数传入ViewHolder构造中,创建ViewHolder实例。
如下代码所示:

  View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
  final ViewHolder viewHolder = new ViewHolder(view);

  • onBindViewHolder(): 这个方法主要用于对RecyclerView的子项进行数据赋值。如下代码所示
  @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruit_image.setImageResource(fruit.getImageID());
        holder.fruit_name.setText(fruit.getName());
    }
  
    
  • getItemCount(): 这个方法很简单,用于告诉RecyclerView总共有多少个子项,直接获取数据源的长度就可以得到了。如下代码所示
 @Override
    public int getItemCount() {
        return mFruitList.size();
    }
    
到这里适配器类就实现好了,整体代码如下所示:



RecyclerView的运用

MainActivity.java

package com.motorola.recyclerviewtest;

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

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    private List mFruitList = new ArrayList();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruit();
        RecyclerView recyclerView=(RecyclerView)findViewById(R.id.Recyclerview1);
//        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
//        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        StaggeredGridLayoutManager layoutManager=new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(new FruitAdapter(mFruitList));
    }

    public void initFruit(){
        for(int i=0; i<5; i++){
            Fruit apple = new Fruit(getRandomLengthName("apple"), R.drawable.picture1);
            mFruitList.add(apple);
            Fruit pear = new Fruit(getRandomLengthName("pear"), R.drawable.picture2);
            mFruitList.add(pear);
            Fruit watermelon = new Fruit(getRandomLengthName("watermelon"), R.drawable.picture3);
            mFruitList.add(watermelon);
            Fruit peach = new Fruit(getRandomLengthName("peach"), R.drawable.picture4);
            mFruitList.add(peach);
            Fruit strawberry = new Fruit(getRandomLengthName("strawberry"), R.drawable.picture5);
            mFruitList.add(strawberry);
            Fruit mango = new Fruit(getRandomLengthName("mango"), R.drawable.picture6);
            mFruitList.add(mango);
            Fruit cherry = new Fruit(getRandomLengthName("cherry"), R.drawable.picture7);
            mFruitList.add(cherry);
            Fruit grape = new Fruit(getRandomLengthName("grape"), R.drawable.picture8);
            mFruitList.add(grape);
        }

    }

    private String getRandomLengthName(String name){
        Random random = new Random();
        int length =random.nextInt(20)+1;
       StringBuilder stringBuilder= new StringBuilder();
        for(int i=0;i

在mainActivity.java类中,Oncreate() 方法下,首先创建RecyclerView的对象,然后创建一个LinearlayoutManager 布局管理器对象,并把它设置到RecyclerView的对象当中,然后再通过setAdapter()
方法将fruitadapter对象设置到Recyclerview对象中,LinearlayoutManager 是用于设置RecyclerView的布局管理器,可以设置LinearLayoutManager 对象的setOrientation()
方法参数为LinearLayoutManager.HORIZONTAL, 这样RecyclerView的排列方式就转化成了横向排列。
除了LinearLayoutManager 布局之外,RecyclerView还提供了GridLayoutManager, StaggeredGridLayoutManager. GridLayoutManager实现的是网格布局,StaggeredGrid
LayoutManager实现的瀑布流布局.


点击事件

RecyclerView 的点击事件的实现要比ListView的复杂得多,但是却更灵活的提供了针对不同控件的点击要求。

在ListView中,控件直接提供了方法setOnItemClickListener(), 而RecyclerView的实现是在适配器的方法onCreateViewHolder()中,当获取到ViewHolder对象后,针对每一个控件对象都可以实现点击事件,这里实现了最外层布局和ImageView的点击事件。

如下代码所示:

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
    final ViewHolder viewHolder = new ViewHolder(view);

    viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int postion = viewHolder.getAdapterPosition();
            Fruit fruit =mFruitList.get(postion);
            Toast.makeText(view.getContext(), "You click "+fruit.getName(), Toast.LENGTH_SHORT).show();
        }
    });

    viewHolder.fruit_image.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View view) {
            int position= viewHolder.getAdapterPosition();
            Fruit fruit=mFruitList.get(position);
            Toast.makeText(view.getContext(), "You click " +fruit.getName(), Toast.LENGTH_SHORT).show();
        }
    });
    return viewHolder;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值