RecyclerView的案例和解析

来源:互联网 发布:mac照片怎么导入手机 编辑:程序博客网 时间:2024/06/11 03:27

一个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;}


原创粉丝点击