RecycleView 實現多佈局

最近的一個新需求,簡單描述下吧:html

需求:java

  

目標樣式如圖所示,咱們須要根據需求動態添加網關和設備。android

目標有了下面就是怎麼實現了。首先咱們選用的是RecycleViewapi

那麼主要目標就成了 在recycleView下如何實現多佈局(咱們看到網關和設備的佈局不一樣)ide

首先寫兩個佈局(一個網關 , 一個設備)佈局

網關佈局樣式:this

設備佈局樣式:spa

這些都比較簡單,在這裏就不贅述。code

RecycleView的基本用法:htm

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

用法很簡單:

兩個參數:

  第一個 須要放置的位置

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

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

 

下面你們本身去研究下代碼吧。

相關文章
相關標籤/搜索