RecyclerView基础使用

前言

本文介绍RecyclerView的基础使用!
1、将RecyclerView展示成ListView样式
2、将RecyclerView展示成GridView样式
3、给RecyclerView添加点击事件
4、给RecyclerView添加滑动监听
5、设置RecyclerView为横向滑动

1、将RecyclerView展示成ListView样式

导入依赖

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

如何使用
第一步:

    
    
//在这里,高度宽度也可以是固定宽高

第二步:代码中配置

myRecyclerView = (RecyclerView) findViewById(R.id.myRecyclerView); //找到RecyclerView
//找到控件
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
 //表示展示成为listview的形式
myRecyclerView.setLayoutManager(layoutManager);
//关键代码,告诉RecyclerView它自己要展示成为什么样子

第三步:准备适配器

public class LikeListViewAdapter extends RecyclerView.Adapter {

    private List list ;  //表示数据源
    private Context context;  //表示上下文,用来创建视图

    public LikeListViewAdapter(Context context) {
            this.context = context;
           list = new ArrayList<>();
    }

    /**此方法是必要的方法,在这里面完成构建视图,相当于ListView中getView()方法中第一步
        参数是ViewGroup 与 viewType(用于RecyclerView的多套布局),返回值是MyViewHolder对象*/
    @Override
    public MyViewHodler onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item1,parent,false);
        MyViewHodler m  = new MyViewHodler(view);
        return m;//这三步之间是通过MyViewHolder对象进行传递的
    }
    /**在这里面完成配置数据源给相应的视图,相当于ListView中getView()方法中第三步
       */
    @Override
    public void onBindViewHolder(MyViewHodler holder, int position) {
            holder.name.setText(list.get(position).getName());
            holder.time.setText(list.get(position).getTime());
    }
  //告诉RecyclerView有多少条目
    @Override
    public int getItemCount() {
        return list.size();
    }
    //前面提到的MyViewHolder对象,相当于ListView中getView()第二步
    public class MyViewHodler extends RecyclerView.ViewHolder
       {
           TextView name,time;
            //必须要重写其构造方法,发现参数是View,可以认为是每一个条目的View(视图)
        public MyViewHodler(View itemView) {
             super(itemView);
            name = (TextView) itemView.findViewById(R.id.textview_name);
            time = (TextView) itemView.findViewById(R.id.textview_time);
            //完成findViewById的过程
        }
    };

    //还需要给外界暴露,使其可以改变里面list的内容
    public void setList(List list){
        this.list = list;
//      notifyDataSetChanged(); //没有什么效果
        notifyItemRangeChanged(0,20); //也没有什么动画效果
    }
}

我认为这里面的数据使用过MyViewHolder对象来进行传递,将这三个步骤串联起来。

第四步:将适配器交给RecyclerView

liAdater = new LikeListViewAdapter(MainActivity.this);  //得到适配器对象
 myRecyclerView.setAdapter(liAdater);  //交给RecyclerView,此时是没有数据的

第五步 :配置展示的数据

for (int i = 0; i < 20; i++) {
            beans1 b = new beans1();
            b.setName("项"+i);
            b.setTime(""+i);
            list.add(b);
        }
        liAdater.setList(list); //通知更新界面

如图所示:

RecyclerView基础使用_第1张图片
device-2017-03-09-102511_看图王.png

解释说明

(1)如图所示,里面是没有红线的,那个是在布局的时候画上的,不和ListView一样自带分割线,这样给了很大的自主性。

 (2)你在每一个条目的布局中展示成什么样子,那么他就会是什么样子,你给他多高,那么在屏幕上展示就有多高,比如我设置
    RecyclerView的高度是200dp,每一条目都是match_parent,那么刚好在RecyclerView可见区域展示,但只能是一条item.
    如果我设置每一item的高度是300dp,RecyclerView依旧是200dp那么高,但是里面内容会展示不全,因为其不会压缩item,
    所以呢,在RecyclerView可见视图上,只能展示一部分。那么可以模仿成为淘宝一样翻转的广告页面。

 (3)对于宽度,如果每一个item 宽度小于RecyclerView的宽度,那么都会展示出来见下图一:
       如果每一个item的宽度大于RecyclerView的宽度,那么就会展示不全,如图二:

 (4)其实,如果你的Item 设计成宽度和高度都是match_parent,表示,宽高和RecyclerView一样,那么只能展示一条item.
RecyclerView基础使用_第2张图片
![Uploading 图一_380282.png . . .]
RecyclerView基础使用_第3张图片
图一.png

2、将RecyclerView展示成GridView样式

代码
别的做法和前面一样,唯一不同的是,告诉ReyclerView展示成为什么样子时候用下面这句(上面第二步)

 GridLayoutManager gridLayoutamnager = new GridLayoutManager(MainActivity.this,3);//将一行平分成为3份空间
 gridLayoutamnager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup(){
            @Override
            public int getSpanSize(int position) {
                if (position%4==0){
                    return 2;
                    //表示%4==0的position,其可以独占该行按照比例划分空间的2个位置,但是如果要是,一行就划分了3份空间,但是要让其占有比这个
                    //会怎么样,如图,图三:
                    //会显示Item at position 0 requires 5 spans but GridLayoutManager has only 3 spans.
                    //就是如果你将行空间划分为三份,但是你这里return 4那么就会程序就会崩溃
                }
                return 1;//其他的表示就占一份空间就好
            }
        });
        myRecyclerView.setLayoutManager(gridLayoutamnager);
      //如果要是没有上述setSpanSizeLookup()方法,效果如图四:

RecyclerView基础使用_第4张图片
图四.png
RecyclerView基础使用_第5张图片
图三.png

说明

(1)如果你每个条目设计的宽度设计成match_parent,高度也是,那么高度不会压缩,但是,宽度会有变,如前面图四
(2)如果你的宽度是自己定义的,如果宽度大于屏幕的宽度,那么每一部分只会显示item的一部分,如果要是小于屏幕的宽度,
    那么就会出现相互重叠的效果如下图
RecyclerView基础使用_第6张图片
device-2017-03-09-172945_看图王.png

3、给RecyclerView添加点击事件

第一步
采用接口回调的方式来实现,先准备一个接口,放在自定义的Adapter文件里面,不用当做内部类的形式


interface sendListener{
         void send(int positon);
}
这里只用position当做参数,是为了 演示,具体可以根据自己的需求来提供不同的参数

第二步
让适配器持有这个自定义接口的对象,并且对外暴露

    private sendListener sendListener; //持有这个接口的对象

    public void setSendListener(com.yuyi.myrecyclerstudy.sendListener sendListener) {
        this.sendListener = sendListener;
    }//对外暴露规则

第三步
在自定义的ViewHolder里面完成调用

 public class MyViewHodler extends RecyclerView.ViewHolder{
      
             TextView name,time;//定义的两个变量

            //必须要重写其构造方法,发现参数是View,可以认为是每一个条目的View(视图)
           //可以认为是第二步
        public MyViewHodler(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.textview_name);
            time = (TextView) itemView.findViewById(R.id.textview_time);
            //在这里得到了视图,因此在这里对于视图进行加点击事件
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (sendListener != null){
                        sendListener.send(getLayoutPosition());
                      //通过getLayoutPosition得到其位置,这个是关键。这里对于这个条目进行添加点击事件
                    }
                }
            });      //另外这里是对于itemView加的点击事件,如果情况特殊完全可以只对于某个View加上点击事件。
        }
    }

第四步
在外界就可以使用其点击事件了

liAdater.setSendListener(new sendListener() {
            @Override
            public void send(final int positon) {
                Toast.makeText(MainActivity.this,""+positon,Toast.LENGTH_SHORT).show();
               }
}
效果如图:
RecyclerView基础使用_第7张图片
device-2017-03-09-112305.png

总结

原本这样,RecyclerView已经具有点击事件了,可以满足正常的需求了,但是RecyclerView本身提供了
很大的自由性和一些动画,这里就顺便演示某些动画效果

补充一
在自定义的Adapter类中加上,增添一个条目和删除一个条目的对外的方法

    //针对于带有动画的删除一个item
    public void removeItem(int position){
        list.remove(position);
        notifyItemRemoved(position);
    }
    //针对与带有动画的增加一个item
    public void addItem(int position,beans1 b){
        list.add(position,b);//先改变数据源
        notifyItemInserted(position);
    }

补充二
在点击事件处理时候加上AlertDialog 进行处理,完成效果:

liAdater.setSendListener(new sendListener() {
            @Override
            public void send(final int positon) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setIcon(R.mipmap.ic_launcher);
                builder.setTitle("请选择你的操作");

                builder.setNegativeButton("删除", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        liAdater.removeItem(positon);
                    }
                });

                builder.setPositiveButton("增加", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        beans1 b = new beans1();
                        b.setTime("99");
                        b.setName("新");
                        liAdater.addItem(positon,b);
                    }
                });

                builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialogInterface) {
                        Toast.makeText(MainActivity.this,"用户取消了操作",Toast.LENGTH_SHORT).show();
                    }
                });
                builder.show();
            }
        });
效果如图:
RecyclerView基础使用_第8张图片
device-2017-03-09-113239_20170309175536.gif

4、给RecyclerView添加滑动监听

SwipeRefreshLayout
这是谷歌官方推荐的搭配的方法。

需要使用android.support.V4.widget.SwipeRefreshlayout

监听方法

swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //在这里不会直接更新,还需要你手动去调用刷新的方法
            }
        });

可以设置刷新圆圈的颜色

swipeRefreshLayout.setColorSchemeColors(Color.RED,Color.BULE);
//这里面设置颜色最多是四个,可以实现转一个圈显示一个颜色

可以设置刷新圆圈出来的位置

swipeRefreshlayout.setProgressViewOffset(true,200,300);
//实现的功能是,true:会收缩,参数二是开始的位置,参数三是结束的位置
//形成一种收缩移动的动画既视感

可以设置圆圈消失

swipeRefreshlayout.setRefreshing(false);

分页加载

介绍
很多人直接会用系统提供的addOnScrollListener()方法,如下所示:

myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
           public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
               super.onScrollStateChanged(recyclerView, newState);  
              if (newState == RecyclerView.SCROLL_STATE_IDLE){
                  /**new State 一共有三种状态
                 * SCROLL_STATE_IDLE:目前RecyclerView不是滚动,也就是静止
                 * SCROLL_STATE_DRAGGING:RecyclerView目前被外部输入如用户触摸输入。
                 * SCROLL_STATE_SETTLING:RecyclerView目前动画虽然不是在最后一个位置外部控制。
                 //这里进行加载更多数据的操作
               }
            }
        });  

弊端
上述方法类似与ViewPager的滑动监听,只要你一滑动RecyclerView,那么就会调用,
如上述的约束条件,只要动了,就会就会静止,就会调用,哪怕你没有到ReyclerView
数据的底部,所以不可取

解决
需要对这个监听进行约束,首先定义新的类,在Adaper类中,不是当做内部类

class OnlastItem extends RecyclerView.OnScrollListener{
    boolean isButton =false;
}
//关键,一定要继承RecyclerView.OnScrollListener接口

在Adapter类中一定要重写onViewAttachedToWindow()方法

@Override
 public void onViewAttachedToWindow(MyViewHodler holder) {
     super.onViewAttachedToWindow(holder);
     int positon = holder.getLayoutPosition();
     if (positon == list.size()-1){
             onlastItem.isButton =true;
     }
 }

上述方法介绍

Called when a view created by this adapter has been attached to a window.
这个方法会频繁的调用,只要一个屏幕外的item进入当前视野,就会调用,但是有一点需要注意的是,
window指的是当前可见的视图,一个item 哪怕,你只看到一点点,那么也算是进入了屏幕上了,
就是所谓的window 上了。
那么你初始化展示了RecyclerView的内容后,这个方法也会根据在window上可见的数目,调用相应的次数。

继续上述步骤
在Adapter类中:

    //持有滑动的变量
    private OnlastItem onlastItem;
    //对外暴露其方法
    public void setOnlastItem(OnlastItem onlastItem) {
        this.onlastItem = onlastItem;
    }

给RecyclerView设置监听方法

        //滑动监听
        OnlastItem on = new OnlastItem(){
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                /*当RecyclerView滚动。这将是
                 称为滚动后完成。这个回调也被称为后如果可见项目范围改变布局
                 计算。在这种情况下,dx和dy将0。
                 dx表示水平滚动,dy表示垂直滚动*/
            }
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
       
                   要调用的回调方法当RecyclerView滚动状态改变。
                /**new State 一共有三种状态
                 * SCROLL_STATE_IDLE:目前RecyclerView不是滚动。
                 * SCROLL_STATE_DRAGGING:RecyclerView目前被外部输入如用户触摸输入。
                 * SCROLL_STATE_SETTLING:RecyclerView目前动画虽然不是在最后一个位置
                                          外部控制。
                 * */
            
                if (newState == RecyclerView.SCROLL_STATE_IDLE&&isButton==true){
                    //这里用不是滚动状态的实现,并且还有一个判断,是退出屏幕了
                    if (newState == RecyclerView.SCROLL_STATE_IDLE){
                        //进行联网数据操作
                        isButton =false;//这个置反很关键
                    }
                }
            }
        };
        myRecyclerView.addOnScrollListener(on);  //关键方法
        liAdater.setOnlastItem(on);  //关键方法

5、设置RecyclerView为横向滑动

先看效果图

RecyclerView基础使用_第9张图片
device-2017-03-22-150803_20170322150905.gif

关键代码

 LinearLayoutManager laoutManager = new LinearLayoutManager(this);
//上述代码告诉RecyclerView 的layoutmanger,展示成为listview样式
 laoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//告诉它是水平展示,要不然默认是竖直方向
 myRecyclerView.setLayoutManager(laoutManager);
//最后交给layoutManger

总结:上述只是RecyclerView的基础使用,可以参考本系列的其他文章,来丰富别的使用方式

你可能感兴趣的:(RecyclerView基础使用)