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详解(一)》


《Android RecyclerView详解(一)》
二.与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<DataBean> 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<RecyclerViewAdapter.ListViewHolder> {
    private Context mContext;
    //泛型是RecyclerView所需的bean类  private List<DataBean> mDataBeen;

    //构造方法,一般需要接收两个参数,上下文及集合对象.  public RecyclerViewAdapter(Context context,List<DataBean> 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"/>
    <!--textStyle:设置字体样式,这里为粗体字-->  <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>
    原文作者:Android开发-CXY
    原文地址: https://blog.csdn.net/CodeFarmerCXY/article/details/62043614
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞