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);
    }

用法很簡單:

兩個參數:

  第一個 需要放置的位置

  第二個 添加的類型(網關/設備)

移除同理,不過不需要類型只傳位置就好~

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM