Android RecyclerView详解(一)

Android RecyclerView详解(一)

Android RecyclerView之ListView显示(二)
Android RecyclerView之GridView显示(三)
Android RecyclerView之瀑布流显示(四)

RecyclerView
Android 5.0之后,谷歌公司推出了RecyclerView控件
一.什么是RecyclerView?
RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与ListView相比,同样拥有item回收复用的功能,并且从它的名字recylerview即回收view也可以看出。其他 可以自己去设置。可以看出其高度的解耦,给予你充分的定制自由。 替代ListView,GridView,可以实现垂直/水平显示的列表/瀑布流的效果,功能强大。在API的14无法使用RecycleView,所以要在项目管理页面,把RecyclerView添加到布局文件并关联兼容包(注意:低版本的安卓系统,要进行兼容包的关联)
步骤:按住control+alt+shift+s出现Project Structure按
Android RecyclerView详解(一)_第1张图片
二.与ListView相比RecyclerView有什么优点?
1.RecylerView封装了viewholder的回收复用,就是说RecylerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
2.提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还有StaggeredGridLayoutManager等),也就是说RecylerView不再拘泥于ListView的线性展示方式,可以实现GridView,瀑布流等多种效果。控制Item的分隔线,可以通过继承RecylerView的ItemDecoration这个类,然后针对自己的业务需求去抒写代码。
3.可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

三.RecyclerView用法
了解了RecylerView的优势,首先我们需要明白RecylerView必须导入support-v7包,因为RecylerView高度的解耦,异常的灵活。
谷歌给我们提供了多个类来控制Item的显示
1. 控制显示的方式,可以通过布局管理器LayoutManager(以LinearLayout为例)
2.控制布局方向,可以通过setOrientation
3.控制适配器,可以通过setAdapter
4.控制Item间的间隔(可绘制),可以通过ItemDecoration
5.控制Item增删的动画,可以通过ItemAnimator
LinearLayoutManager layoutManager = new LinearLayoutManager(this );
//设置布局管理器  
recyclerView.setLayoutManager(layoutManager);
//设置为垂直布局,这也是默认的  
layoutManager.setOrientation(OrientationHelper. VERTICAL);
//设置Adapter  
recyclerView.setAdapter( recycleAdapter);
//设置分隔线  
recyclerView.addItemDecoration( new DividerGridItemDecoration(this ));
//设置增加或删除条目的动画  
recyclerView.setItemAnimator( new DefaultItemAnimator());  
RecyclerView还需要一个menu菜单栏
在这里只给出代码,menu菜单栏详解请点击:Munu菜单栏详解
xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_ListView"
        android:orderInCategory="100"
        android:title="ListView显示"
        app:showAsAction="never">
        <menu>
            <item
                android:id="@+id/action_ListView_noraml"
                android:orderInCategory="100"
                android:title="标准"
                app:showAsAction="never"/>
            <item
                android:id="@+id/action_ListView_vertical_reverse"
                android:orderInCategory="100"
                android:title="垂直反向"
                app:showAsAction="never"/>
            <item
                android:id="@+id/action_ListView_horizontal"
                android:orderInCategory="100"
                android:title="水平"
                app:showAsAction="never"/>
            <item
                android:id="@+id/action_ListView_horizontal_reverse"
                android:orderInCategory="100"
                android:title="水平反向"
                app:showAsAction="never"/>
        menu>
    item>
menu>
还需要新建一个DateBean类用于存储图片和信息
package com.example.recyclerview1.menu;

/**
 * Date:2017/3/14
 * author:陈箫阳ChenXiaoYang
 * furction:
 */

public class DataBean {
    public int icon;
    public String name;
}
主类MainActivity代码
package com.example.recyclerview1;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.recyclerview1.menu.DataBean;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //A.初始化控件对象
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    }

    //A.RecyclerView填充数据
    private void loadListData() {
        //集合对象
        ArrayList datas = new ArrayList<>();
        //给bean类放数据,最后把装好数据的bean类放入到集合里
        for (int i = 0; i < 20; i++) {
            //创建集合对象
            DataBean dataBean = new DataBean();
            dataBean.icon=R.mipmap.ic_launcher;
            dataBean.name="RecyclerView"+i;
            datas.add(dataBean);
        }
        //创建适配器所需参,创建Adapter类及对象(一般最低需要两个,上下文及加载数据集合)
        RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(this, datas);
        //1.设置适配器
        mRecyclerView.setAdapter(recyclerViewAdapter);
        //布局管理器所需参数,其参数上下文this.
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        //2.设置布局管理器,参数  LinearLayoutManager
        mRecyclerView.setLayoutManager(linearLayoutManager);
    }

    //加载一个菜单的布局
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //加载布局,使用菜单特有方法getMenuInflater,获取inflate对象,参数:  1.菜单显示的布局       2.固定menu
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;

    }

    //菜单按钮点击事件的处理
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.action_ListView_noraml) {
            //标准展示
            loadListData();
            Toast.makeText(MainActivity.this, "标准显示", Toast.LENGTH_SHORT).show();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
四.RecyclerView.Adapter用法
RecylerView的设置过程,比ListView要复杂,这也是RecylerView高度解耦的表现,虽然代码上有点复杂,但它的扩展性是极高的。
了解RecyclerView的一些控制之后,紧接着是Adapter的写法,RecyclerView的Adapter与ListView的Adapter还是有点区别的,RecyclerView.Adapter,需要实现3个方法:
1.onCreateViewHolder()这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
2.onBindViewHolder():这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。
3.getItemCount()这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。
package com.example.recyclerview1;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.recyclerview1.menu.DataBean;
import java.util.List;

/**
 * Date:2017/3/14
 * author:陈箫阳ChenXiaoYang
 * furction:
 */

public class RecyclerViewAdapter extends RecyclerView.Adapter {
    private Context mContext;
    //泛型是RecyclerView所需的bean类
    private List mDataBeen;

    //构造方法,一般需要接收两个参数,上下文及集合对象.
    public RecyclerViewAdapter(Context context,List dataBean) {
        mContext=context;
        mDataBeen=dataBean;
    }

    //创建ViewHolder,并把VIewHolder(也可以理解为一个item)返回出去
    @Override
    public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //转换一个View布局对象,决定了Item的样子.参数:1.上下文    2.XML布局资源     3.一般为null
        View itemView = View.inflate(mContext, R.layout.item_list, null);
        //创建一个VIewHolder对象
        ListViewHolder listViewHolder = new ListViewHolder(itemView);
        //把ViewHolder对象传出去
        return listViewHolder;
    }

    //当VIewHolder和数据绑定时回调
    @Override
    public void onBindViewHolder(ListViewHolder holder, int position) {
        //从集合里拿对应item的数据对象
        DataBean dataBean = mDataBeen.get(position);
        //给holder里面的控件对象设置数据
        holder.setData(dataBean);
    }

    //决定RecyclerView多少条item
    @Override
    public int getItemCount() {
        //数据不为null,有几条数据就显示几条数据
        if(mDataBeen !=null && mDataBeen.size()>0){
            return mDataBeen.size();
        }
        return 0;
    }

    //自动帮我写的ViewHolder,参数:View布局对象
    public class ListViewHolder extends RecyclerView.ViewHolder {

        private final ImageView ivIcon;
        private final TextView tvName;

        public ListViewHolder(View itemView) {
            super(itemView);
            ivIcon = (ImageView) itemView.findViewById(R.id.item_list_iv_icon);
            tvName = (TextView) itemView.findViewById(R.id.item_list_tv_name);
        }

        public void setData(DataBean data) {
            //给imageView设置图片数据
            ivIcon.setImageResource(data.icon);
            //给TextView设置文本数据
            tvName.setText(data.name);
        }
    }
}
RecyclerView标准化了ViewHolder,编写 Adapter面向的是ViewHoder而不在是View了,复用的逻辑被封装了,写起来更加简单。其实它的写法与BaseAdapter的写法是差不多的,大家可以对比下它与getView方法写法的区别,在onCreateViewHolder方法中初始化了一个View,然后返回一个ViewHolder,这个返回的ViewHolder类似于之前在getView中的convertView.getTag(),然后在onBindViewHolder方法中去给这个ViewHolder中的控件填充值。其实它的原理跟getView是差不多的,只是做了封装,写起来比较简洁。
5.主类布局文件activity_main和行布局item_list代码
xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.recyclerview1.MainActivity">

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

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

    <ImageView
        android:id="@+id/item_list_iv_icon"
        android:layout_width="75dp"
        android:layout_height="75dp"
        android:src="@mipmap/ic_launcher"/>
    
    <TextView
        android:id="@+id/item_list_tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textStyle="bold"
        android:text="图片描述"
        android:layout_toRightOf="@id/item_list_iv_icon"
        android:layout_centerVertical="true"/>

RelativeLayout>

你可能感兴趣的:(RecyclerView)