关闭

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

标签: AndroidRecyclerView多种控件加载网格
652人阅读 评论(0) 收藏 举报
分类:

由于最近需要在网格布局中加载不同的控件所以开始研究这个。一开始我使用的是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 的一些心得,如有错误的地方希望大家能够批评指正。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:656次
    • 积分:16
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档