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 RecyclerView 使用完全解析 体验艺术般的控件

Android RecyclerView 使用完全解析 概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。 据官方的介绍...

RecyclerView实现底部加载更多功能

这两天在公司没有什么任务分配,就研究了下咱们Google在Android5.0 推出的一个用来代替ListView的列表控件----RecyclerView。发现功能上确实比ListView强大了不少...

RecyclerView 获取指定位置item的view并获取view的子控件

@Override protected void onResume() { super.onResume(); new Handler().postDelayed(new Runnab...

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

在实际开发中,我们常常碰到这样的需求,需要在外部拿到RecyclerView 中的viewHoler,从而动态的修改UI,在RecyclerView中,我们需要自己封装点击事件,一般的做法是在recy...

【android】RecyclerView中动态添加子控件和改变ViewHolder高度

想要跨平台,就要对平台有了解,最近在看android开发。在为RecyclerView中动态添加子控件和改变ViewHolder高度时遇到了几个坑,费了不少时间填坑,所以记录一下。 这个是效果图:本文...

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

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

AndroidStudio GradView在RecyclerView中设置条目(Item)点击事件

GridView在RecyclerView中设置条目点击事件,Item点击事件,获取Item的位置

Android Selector与Shape用法

首先android的selector是在drawable/xxx.xml中配置的。 先看一下listview中的状态: 把下面的XML文件保存成你自己命名的.xml文件(比如list_item_b...

Android CheckBox自定义

Android自带的CheckBox看着比较丑,大部分开发者可能都会使用自定义的CheckBox,网上大部分方法是利用事先做好的两张选中和未选中的图片来实现自定义的切换效果。其实CheckBox本身提...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RecyclerView使用心得 加载单一View控件与多种View控件
举报原因:
原因补充:

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