RecyclerView使用心得 加载单一View控件与多种View控件

原创 2016年08月31日 14:41:16

由于最近需要在网格布局中加载不同的控件所以开始研究这个。一开始我使用的是GridLayout,但在使用过程中遇到许多不可知且很难搜到解决方法的BUG而且能找到关于GridLayout的文档和说明实在是少之又少。所以建议想使用网格布局的盆友不使用GridLayout。然后就转向使用RecyclerView。接下来进入正题:由于这次我使用的是网格布局所以以网格布局为例。想使用RecyclerView代替ListView可以私聊我,或者在下面评论。(如转载请注明出处)

接下来进入正题:

     使用RecyclerView个人觉得至少应该编写三个部分:
  1.RecyclerView的布局文件和需要加载进RecyclerView的控件布局文件 
     2.使用RecyclerView的Activity或者Fragment
     3.需要加载控件所对应的Adapter
由于1不是这次我想说明的重点,所以只列出这部分的代码,不做过多解释,有疑问的盆友再私聊我。
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1.0">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/dataRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:scrollbarStyle="outsideOverlay">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>
data_item.xml(需加载控件的Item 布局)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <ImageView
        android:id="@+id/IitemView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"/>

    <TextView
        android:id="@+id/ItemText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/IitemView"
        android:layout_centerHorizontal="true"
        android:textColor="@color/black"
        android:textSize="15sp"
        android:gravity="center"/>

</LinearLayout>
2.Activity或者Fragment使用RecyclerView所需代码
<span style="font-size:14px;">// 声明使用布局为 RecyclerView
private RecyclerView recyclerView;
// 绑定布局
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
// 声明网格布局管理器
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);
// 设置布局管理器为垂直,这里也可以设置为水平,使用网格布局时就要水平滑动,但我个人开发中没有使用过水平布局,所以没有办法对这个布局进行更详细的说明
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// 设置recyclerView 布局管理器为先前声明的网格布局
recyclerView.setLayoutManager(layoutManager);
// 这是设置分割线,这里分割线所使用的类来自于 http://blog.csdn.net/lmj623565791/article/details/45059587 ; 【张鸿洋的博客】 ,想详细研究的盆友可以去看看
recyclerView.addItemDecoration(new DividerGridItemDecoration(getContext()));
// 下面两个是我自己编写的 Adapter ,及绑定到 这里的设置的 Adapter 在后面会详细将这个
HomeAdapter homeAdapter = new DataAdapter (mInfo,getContext() );
recyclerView.setAdapter(homeAdapter);</span><span style="font-style: italic; font-weight: bold; font-size: 16px;">
</span>
以上就是设置布局的所需的基本步骤,需要其他个性化定制可以查阅相关文档。
接下来就是这次的重点就是adapter
3.需要加载控件所对应的Adapter
所有Adapter必须重写以下三个方法
<span style="font-size:14px;">onCreateViewHolder// 创建控件所在 View
onBindViewHolder // 这个是绑定控件
getItemCount// 这个是获取所有控件总数</span>
3.1 整个RecyclerView采用同一个View的控件
只用重写以上三个方法即可。以下是示例代码
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataHolder> { // 这里要继承你自己所需要的 Holder
    private List<Info> infoList = new ArrayList< Info>();
    private Context context;

    public DataAdapter(List< Info > mInfo, Context mContext) {
        this. infoList = mInfo;
        this.context = mContext;
    }

    @Override
    public DataHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(parent.getContext(), R.layout.data_item, null);// 控件所在的布局
        return new DataHolder(view);
    }

    @Override
    public void onBindViewHolder(DataHolder holder, int position) {
        Info info = infoList.get(position);
        holder.textView.setText(info.getInfoName());
        holder.imageView.setImageResource(R.mipmap.show_data_blue_0_smoth);
        holder.itemOnclickListener.setInfo(info.getInfo);// 监听器地址给出
    }

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

    // 自己定义需要的 Holder
    public class DataHolder extends RecyclerView.ViewHolder {
        ImageView imageView;
        TextView textView;<pre name="code" class="java">onCreateViewHolder// 创建控件所在 View
onBindViewHolder // 这个是绑定控件
getItemCount// 这个是获取所有控件总数
getItemViewType// 这是根据position 的不同来加载不同的控件

ItemOnclickListener itemOnclickListener = new ItemOnclickListener(); public DataHolder(View itemView) { super(itemView); // 绑定布局文件中的控件 imageView = (ImageView) itemView.findViewById(R.id.IitemView); textView = (TextView) itemView.findViewById(R.id.ItemText); itemView.setOnClickListener(itemOnclickListener); } } // 点击监听器 public class ItemOnclickListener implements View.OnClickListener { private String info; public void setInfo(String info) { this. info = info; } @Override public void onClick(View v) { Toast.makeText(context, info, Toast.LENGTH_SHORT).show(); } }}

3.2 整个 RecyclerView采用不同View的控件
不仅要重写必须的三个方法还必须重写getItemViewType 这个方法
所以一共要重写四个方法
<span style="font-size:14px;">onCreateViewHolder// 创建控件所在 View
onBindViewHolder // 这个是绑定控件
getItemCount// 这个是获取所有控件总数
getItemViewType// 这是根据position 的不同来加载不同的控件</span>
这里为了方便说明便只使用了两个不同布局的控件来说明,要是需要更多控件可以以此类推以下是示例代码
public class DataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {//这里由于要使用多种 Holder 所以继承所有 Holder的父类
    //Button 数组
    private List<Button> buttons;               /**
    //ImageView 数组                                   这里的 button和 ImageView 是在两个不同的布局文件中的
    private List<ImageView> images;               **/

    private Context context;
    private static final int TYPE_BUTT = 0;
    private static final int TYPE_IMG = 1;

    public DataAdapter (List<ImageView> images,List<Button> buttons,Context context) {
        this.buttons = buttons;
        this.images= images;
        this.context = context;
    }

    /**
     * 根据不同的 View 创建不同的holder
     * @param viewGroup
     * @param viewType
     * @return
     *
     *  需要新的 View视图来显示列表时,会调用此函数
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        RecyclerView.ViewHolder holder = null;
        switch (viewType) {
            case TYPE_BUTT:
                View buttonView= View.inflate(viewGroup.getContext(), R.layout.item_button, null);
                holder = new ButtonHolder(buttonView);
                break;
            case TYPE_IMG:
                View lineView = View.inflate(viewGroup.getContext(), R.layout.item_img,null);
                holder = new ImageHolder(lineView);
                break;
        }
        return holder;
    }

    @Override// 绑定 ViewHolder的 View 视图和模型层数据
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int buttonSize = buttons.size();//ButtonList 大小
        switch (getItemViewType(position)) {
            case TYPE_BUTT:
                Button buttonV = buttons.get((position));
                ((ButtonHolder) holder).hButton.setButton(buttonV);
               //如果要使用监听器就在这里绑定
                break;
            case TYPE_IMG:
                ImageView imageV= images.get((position - pieSize));
                ((ImageViewHolder) holder).hImageView.setImageView(imageV);
                break;
        }
    }

    @Override
    public int getItemCount() {
        return (buttons.size() + images.size());
    }

    @Override
    public int getItemViewType(int position) {
        int itemType = position;
          // 这里 postion是控件位置,所以 postion 最大值是所有控件个数的总和
        /**
         * 结束位置 =之前图标数组长度总和 + 结束图标数组长度
         */
       
        //Button 结束位置
        int buttonEnd = buttons.size();

        //ImageView 结束位置
        int imageEnd = buttons.size() + images.size();

          /* 这里的 buttonEnd一定要与下面的返回类型匹配。
           *比如要先创建 Button 的View 那么结束标志就是 Button List 的长度
          **/

        if (position < buttonEnd ) {

            itemType = TYPE_BUTT;
        }
        if (position >= buttonEnd && position < imageEnd ) {
            itemType = TYPE_IMG;
        }
        return itemType;
    }

    //Button  Holder
    public class ButtonHolder extends RecyclerView.ViewHolder {
        Button hButton;
        public PieChartViewHolder(View itemView) {
            super(itemView);
            hButton = (Button) itemView.findViewById(R.id.button);
        }
    }

    //Image holder
    public class ImageViewHolder extends RecyclerView.ViewHolder {
        ImageView hImageView;
        public LineChartViewHolder(View itemView) {
            super(itemView);
            hImageView = (ImageView) itemView.findViewById(R.id.imageView);
        }
    }
}


后面多种控件的布局和前面类似, 需加载多少种类型的控件,就要编写多少不同的控件布局(及Item布局)
代码中省略了按键监听器的代码,由于是为了方便说明编写精简了许多代码,力求能够简明的说明我自己在使用RecyclerView 的一些心得,如有错误的地方希望大家能够批评指正。


Android开发笔记之RecycleView加载不同item布局的实现

RecycleView是安卓5.0版本以后推出的新控件优点 想要控制其显示的方式,请通过布局管理器LayoutManager 想要控制Item间的间隔(可绘制),请通过ItemDecoration 想...
  • u012416955
  • u012416955
  • 2016年07月31日 15:51
  • 4092

列表控件RecyclerView的使用

[TOC] 列表控件也算是很常见的控件了,现在基本都切换到RecycleView了,这边记录下列表控件的基本的使用以及几种情况的处理:Demo链接RecycleView官网介绍 使用上基本步骤如下...
  • zxz_tsgx
  • zxz_tsgx
  • 2016年05月30日 10:59
  • 2273

控制ListView(RecyclerView)中Adapter中的控件的显示和隐藏

在实际开发中,我们通常会遇到,通过外面的控件去控制Adapter里面的删除按钮的显示或隐藏: 先看效果图:大致情况是这样的:正常情况,出现管理字体时,Adapter中的删除图标是隐藏的;当点击管理的...
  • willba
  • willba
  • 2017年05月21日 17:32
  • 1198

Android5.0新控件——RecyclerView的使用全解

介绍RecyclerView与ListView原理是类似的:都是仅仅维护少量的View并且可以展示大量的数据集。RecyclerView用以下两种方式简化了数据的展示和处理:使用LayoutManag...
  • qq_37293612
  • qq_37293612
  • 2017年02月07日 20:08
  • 1077

关于在外部拿到RecyclerView的viewholder的几种方式

在实际开发中,我们常常碰到这样的需求,需要在外部拿到RecyclerView 中的viewHoler,从而动态的修改UI,在RecyclerView中,我们需要自己封装点击事件,一般的做法是在recy...
  • qq_21949639
  • qq_21949639
  • 2016年07月31日 01:18
  • 5254

RecyclerView的加载显示多种布局

RecyclerView是对ListView的封装,所以ListView上能用的方法对RecyclerView同样适用,并且会更简单在实际开发中,我们可能需要一个列表,显示多种布局,getItemVi...
  • a516972602
  • a516972602
  • 2016年03月04日 15:13
  • 24786

Android开发笔记之RecycleView加载不同item布局的实现

RecycleView是安卓5.0版本以后推出的新控件优点 想要控制其显示的方式,请通过布局管理器LayoutManager 想要控制Item间的间隔(可绘制),请通过ItemDecoration 想...
  • u012416955
  • u012416955
  • 2016年07月31日 15:51
  • 4092

Glide使用探索(四)——自定义显示控件

Glide自定义显示控件
  • dcsff
  • dcsff
  • 2017年03月06日 15:47
  • 758

自定义view动态加载控件实现动态换行

自定义view动态加载控件先来讲下需求吧,可能我们开发中会遇到这样的场景,需要在一个父容器里加载多个子view,但是,子view的排版又有特殊要求,比如自适应屏幕宽度或者高度等,这样以来原本的控件无法...
  • u013179982
  • u013179982
  • 2016年12月14日 12:55
  • 485

Android View体系(十)自定义组合控件

上一篇我们讲到了自定义View,接着我们来讲讲常用的自定义组合控件,自定义组合控件就是多个控件组合起来成为一个新的控件,主要用来解决多次重复的使用同一类型的布局。比如我们应用的顶部的标题栏,还有弹出的...
  • itachi85
  • itachi85
  • 2016年05月19日 17:10
  • 9903
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RecyclerView使用心得 加载单一View控件与多种View控件
举报原因:
原因补充:

(最多只允许输入30个字)