zoukankan      html  css  js  c++  java
  • RecycleView 实现多布局

    最近的一个新需求,简单描述下吧:

    需求:

      

    目标样式如图所示,我们需要根据需求动态添加网关和设备。

    目标有了下面就是怎么实现了。首先我们选用的是RecycleView

    那么主要目标就成了 在recycleView下如何实现多布局(我们看到网关和设备的布局不同)

    首先写两个布局(一个网关 , 一个设备)

    网关布局样式:

    设备布局样式:

    这些都比较简单,在这里就不赘述。

    RecycleView的基本用法:

      1)引入包

      2)在布局中使用控件

      3)在activity中绑定并使用recycleView

      4)自定义recycleView的适配器

    这些在我之前的博客有介绍,本篇主要说明多布局应当如何来写

    适配器:

    先上代码:

    package com.wbnq.ryadie.utils;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.RecyclerView.ViewHolder;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Toast;
    
    import com.wbnq.ryadie.R;
    import com.wbnq.ryadie.utils.SBViewHolder;
    import com.wbnq.ryadie.utils.SBitem;
    import com.wbnq.ryadie.utils.WGViewHolder;
    import com.wbnq.ryadie.utils.WGitem;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by guwei on 16-10-22.
     */
    public class RecAdapter extends RecyclerView.Adapter<ViewHolder> {
    
        //设置类型标志
        private static final int TYPE_WG = 0x00;
        private static final int TYPE_SB = 0x01;
    
        private LayoutInflater inflater;
        private Context mContext;
        private List<Object> mData;
    
        boolean isopen = false;
    
    
        public RecAdapter(Context context, List<Object> mdata) {
            this.mContext = context;
            this.mData = mdata;
            inflater = LayoutInflater.from(context);
        }
    
    
        //获取数据类型 方便分类
        @Override
        public int getItemViewType(int position) {
            if (mData.get(position) instanceof WGitem) {
                return TYPE_WG;
            } else if (mData.get(position) instanceof SBitem) {
                return TYPE_SB;
            } else {
                return super.getItemViewType(position);
            }
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            View view = null;
            ViewHolder viewHolder = null;
            switch (viewType) {
                case TYPE_WG:
                    view = inflater.inflate(R.layout.wglist_item, parent, false);
                    viewHolder = new WGViewHolder(view);
                    break;
    
                case TYPE_SB:
                    view = inflater.inflate(R.layout.sblist_item, parent, false);
                    viewHolder = new SBViewHolder(view);
                    break;
            }
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
    
            switch (getItemViewType(position)) {
    
                //网关 操作
                case TYPE_WG:
                    final WGViewHolder wgholder = (WGViewHolder) holder;
                    WGitem wgbean = (WGitem) mData.get(position);
                    wgholder.title.setText(wgbean.mTitle);
                    wgholder.date.setText(wgbean.mDate);
    
                    //定义可重载 监听方法
                    wgholder.history.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Toast.makeText(mContext, "历史记录", Toast.LENGTH_SHORT).show();
                        }
                    });
    
                    //开关监听
                    wgholder.image_zykg.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if (isopen) {
                                wgholder.image_zykg.setImageResource(R.mipmap.ryicon_guan);
                                isopen = !isopen;
                            } else {
                                wgholder.image_zykg.setImageResource(R.mipmap.ryicon_kai);
                                isopen = !isopen;
                            }
    
                        }
                    });
    
    
                    break;
    
                // 设备 操作
                case TYPE_SB:
                    final SBViewHolder sbholder = (SBViewHolder) holder;
                    SBitem sbitem = (SBitem) mData.get(position);
    
                    sbholder.rongyang.setText(sbitem.mRongyang);
                    sbholder.wendu.setText(sbitem.mWendu);
                    sbholder.dianya.setText(sbitem.mDianya);
    
                    sbholder.pb_rongyang.setProgress(Integer.valueOf(sbitem.mRongyang));
                    sbholder.pb_wendu.setProgress(Integer.valueOf(sbitem.mWendu));
                    sbholder.pb_dianya.setProgress(Integer.valueOf(sbitem.mDianya));
    
                    break;
            }
    
            if (onItemClieckLinster != null) {
    
                //onitemlongclicklistener
                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View view) {
                        onItemClieckLinster.onItemLongClickListener(holder.itemView, position);
                        return false;
                    }
                });
            }
    
        }
    
        //新增item
        public void addData(int pos , int type) {
           switch (type){
               case TYPE_WG:
                   mData.add(new WGitem("date" , "新增item"));
                   notifyItemInserted(pos);
                   break;
    
               case TYPE_SB:
                   mData.add(pos , new SBitem("0","0","0"));
                   notifyDataSetChanged();
                   break;
           }
    
        }
    
        //移除item
        public void deleateData(int pos) {
            mData.remove(pos);
            notifyItemRemoved(pos);
        }
        //item 点击/长按 监听
        public interface OnItemClieckLinster {
    //        void onItemClickListener(View view, int pos);
    
            void onItemLongClickListener(View view, int pos);
        }
    
        private OnItemClieckLinster onItemClieckLinster;
    
        public void setOnItemClieckLinster(OnItemClieckLinster listener) {
    
            this.onItemClieckLinster = listener;
        }
    
        @Override
        public int getItemCount() {
            return mData.size();
        }
    }
    View Code

    该代码参考listview的多布局实现 

    首先我们自定义的适配器需要继承 RecyclerView.Adapter<ViewHolder>

    主要的重载方法为:

    //获取数据类型 方便分类
        @Override
        public int getItemViewType(int position) {
            if (mData.get(position) instanceof WGitem) {
                return TYPE_WG;
            } else if (mData.get(position) instanceof SBitem) {
                return TYPE_SB;
            } else {
                return super.getItemViewType(position);
            }
        }

    这个方法为后面的 onCreateViewHolder和onBindViewHolder 提供item类型

    来方便加载不同的布局。

    该方法中的WGitem 和 SBitem为我们自定义的bean包含对应item布局的相关参数

    比如:

    SBitem:

    public class SBitem {
    
        public String mRongyang;
        public String mWendu;
        public String mDianya;
    
        public SBitem(String rongyang, String wendu, String dianya) {
            this.mRongyang = rongyang;
            this.mWendu = wendu;
            this.mDianya = dianya;
        }
    }

    这个bean中包含的就是设备布局中所有的参数(请忽略参数类型...)

    接下来就是 onCreateViewHolder和onBindViewHolder 这两个方法

    根据获取的类型来进行不同的绑定和操作

    在onBindViewHolder中在确定类型后的第一个操作是:

    //网关 操作
                case TYPE_WG:
                    final WGViewHolder wgholder = (WGViewHolder) holder;
                    WGitem wgbean = (WGitem) mData.get(position);
                    wgholder.title.setText(wgbean.mTitle);
                    wgholder.date.setText(wgbean.mDate);
    
     // 设备 操作
                case TYPE_SB:
                    final SBViewHolder sbholder = (SBViewHolder) holder;
                    SBitem sbitem = (SBitem) mData.get(position);
    
                    sbholder.rongyang.setText(sbitem.mRongyang);
                    sbholder.wendu.setText(sbitem.mWendu);
                    sbholder.dianya.setText(sbitem.mDianya);

    因为 onBindViewHolder获取到的holder 并不针对网关类型 或者设备类型所以要对该holder进行一个类型转换

    @Override
        public void onBindViewHolder(final ViewHolder holder, final int position)

    当然啦你要先写好这两个ViewHolder:

    例如 SBViewHolder:

    package com.wbnq.ryadie.utils;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import com.wbnq.ryadie.R;
    import com.wbnq.ryadie.utils.SBitem;
    import com.wbnq.ryadie.utils.WGitem;
    
    import java.util.List;
    
    /**
     * Created by guwei on 16-10-21.
     */
    public class SBViewHolder extends RecyclerView.ViewHolder {
    
        public TextView rongyang, wendu, dianya;
        public ProgressBar pb_rongyang, pb_wendu, pb_dianya;
    
        public SBViewHolder(View itemView) {
            super(itemView);
    
            rongyang = (TextView) itemView.findViewById(R.id.sblist_text_ry);
            wendu = (TextView) itemView.findViewById(R.id.sblist_text_wd);
            dianya = (TextView) itemView.findViewById(R.id.sblist_text_dy);
    
            pb_rongyang = (ProgressBar) itemView.findViewById(R.id.progressBar_rongyang);
            pb_wendu = (ProgressBar) itemView.findViewById(R.id.progressBar_wendu);
            pb_dianya = (ProgressBar) itemView.findViewById(R.id.progressBar_dianchi);
    
        }
    }

    viewholder的作用我之前的博客也有介绍有兴趣可以去看下。只不过我现在把它单独取出来写在一个文件中而已:

    需要用到的其他文件就是这些了。

    还有一个比较重要的方法就是添加删除设备的问题了

    这里就体现RecycleView的好用了,新增和删除非常简单,不过还是要根据类型来。

     //新增item
        public void addData(int pos , int type) {
           switch (type){
               case TYPE_WG:
                   mData.add(new WGitem("date" , "新增item"));
                   notifyItemInserted(pos);
                   break;
    
               case TYPE_SB:
                   mData.add(pos , new SBitem("0","0","0"));
                   notifyDataSetChanged();
                   break;
           }
    
        }
    
        //移除item
        public void deleateData(int pos) {
            mData.remove(pos);
            notifyItemRemoved(pos);
        }

    用法很简单:

    两个参数:

      第一个 需要放置的位置

      第二个 添加的类型(网关/设备)

    移除同理,不过不需要类型只传位置就好~

    下面大家自己去研究下代码吧。

  • 相关阅读:
    美化WebApi,使其统一返回Json格式
    JavaScript函数封装调用
    Visual Studio 编辑器调试在IIS发布的Web程序出现错误的解决
    C#解析多层Json数据
    Python3解析库lxml
    学习使用Django一 安装虚拟环境
    一:(1.1)了解MVC之路由重写
    Python使用selenium模拟点击,进入下一页(三)
    云服务器安装证书
    Python使用selenium模拟点击(二)
  • 原文地址:https://www.cnblogs.com/wobeinianqing/p/5994173.html
Copyright © 2011-2022 走看看