1. 程式人生 > >打造RecyclerView的通用介面卡

打造RecyclerView的通用介面卡

SDK的5.0版本出來已經N久了,可以說是已經經過許多人的檢驗了,裡面的新控制元件不能說是非常完美,但也是非常好用了,其中最讓我喜愛的就是RecyclerView了,可以完美替代ListView和GridView(除了新增headerview和footview了,網上有許多解決方式。這個下面會以一種簡單的方式順帶解決,肯定為大家省心),而且可以程式碼動態切換這兩種佈局方式以及瀑布流佈局。相關切換方式網上有很多,大家自行搜尋,我就不貼連線了。
相信大家在之前使用listview時肯定一直很厭煩重複編寫無數的adapter,當然有那麼一部分機智如我的人肯定一直使用著萬能介面卡。然而RecyclerView要求我們必須使用ViewHolder來實現adapter。這就讓許多用慣了萬能介面卡的人不爽了。今天我就提供一直基於listview萬能介面卡的實現原理來改良實現的RecyclerView的通用介面卡,由於不是教學,切程式碼比較簡單,就不分段講解了,相信大家看註釋就能看懂。
一共兩個類,一個是繼承了系統的android.support.v7.widget.RecyclerView.ViewHolder所實現的RViewHolder類,通過他實現任意控制元件的快取一個是繼承了android.support.v7.widget.RecyclerView.Adapter所實現的RBaseAdapter類。

不善言辭,直接貼程式碼
RViewHolder
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import
android.widget.TextView; public class RViewHolder extends ViewHolder { private Context mContext; private View mConvertView; private SparseArray<View> mViews; public RViewHolder(View itemView) { super(itemView); mConvertView = itemView; this.mViews = new
SparseArray<View>(); } public static RViewHolder get(Context context, ViewGroup parent, int layoutId, int position) { View view = LayoutInflater.from(context).inflate(layoutId, parent, false); return new RViewHolder(view); } /** * 通過控制元件的Id獲取對於的控制元件,如果沒有則加入views * * @param viewId * @return */ public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (view == null) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } /** * 為TextView設定字元�? * * @param viewId * @param text * @return */ public ViewHolder setText(int viewId, String text) { TextView view = getView(viewId); view.setText(text); return this; } /** * 為ImageView設定圖片 * * @param viewId * @param drawableId * @return */ public ViewHolder setImageResource(int viewId, int drawableId) { ImageView view = getView(viewId); view.setImageResource(drawableId); return this; } /** * 為ImageView設定圖片 * * @param viewId * @param drawableId * @return */ public ViewHolder setImageBitmap(int viewId, Bitmap bm) { ImageView view = getView(viewId); view.setImageBitmap(bm); return this; } public View getConvertView() { return mConvertView; } }

這裡是RBaseAdapter

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import android.content.Context;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public abstract class RBaseAdapter<T> extends Adapter<RViewHolder> {
    private Context mContext;
    private List<T> list;
    protected LayoutInflater mInflater;
    private int mItemLayoutId;

    public RBaseAdapter(Context context) {
        // TODO Auto-generated constructor stub
        this.mContext = context;
        this.mInflater = LayoutInflater.from(mContext);
        this.mItemLayoutId = new LinearLayout(mContext).getId();
        this.list = new ArrayList<T>();

    }

    public RBaseAdapter(Context context, List<T> list) {
        // TODO Auto-generated constructor stub
        this.mContext = context;
        this.mInflater = LayoutInflater.from(mContext);
        this.mItemLayoutId = new LinearLayout(mContext).getId();
        this.list = list;

    }

    public RBaseAdapter(Context context, List<T> list, int itemLayoutId) {
        this.mContext = context;
        this.mInflater = LayoutInflater.from(mContext);
        this.mItemLayoutId = itemLayoutId;
        this.list = list;

    }

    public RBaseAdapter(Context context, int itemLayoutId) {
        this.mContext = context;
        this.mInflater = LayoutInflater.from(mContext);
        this.mItemLayoutId = itemLayoutId;
        this.list = new ArrayList<T>();

    }

    public void setitemLayoutId(int itemLayoutId) {
        this.mItemLayoutId = itemLayoutId;
    }

    public List<T> getList() {
        return this.list;
    }

    public void appendList(List<T> list) {
        // TODO Auto-generated method stub
        this.list = list;
        notifyDataSetChanged();
    }

    public void addList(List<T> list2) {
        // TODO Auto-generated method stub
        this.list.addAll((Collection<? extends T>) list2);
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        return list.size();

    }

    boolean hasHeader = false;
    boolean hasFooter = false;
    View headerView;
    View footerView;

    public void setHeaderView(View headerView) {
        hasHeader=true;
        this.headerView = headerView;
    }

    public void setFooterView(View footerView) {
         hasFooter = true;
        this.footerView = footerView;
    }

    public View getHeaderView() {
        return headerView;
    }

    public View getFooterView() {
        return footerView;
    }

    @Override
    public void onBindViewHolder(RViewHolder holder, int position) {
        if (hasHeader && position == 0) {
            return;
        } else if (hasFooter && position == (list.size() + (hasHeader ? 1 : 0))) {
            return;
        } else
            convert(holder, (T) list.get(position));
    }

    @Override
    public RViewHolder onCreateViewHolder(ViewGroup parent, int position) {
        if (hasHeader && position == 0) {
            return new RViewHolder(headerView);
        } else if (hasFooter && position == (list.size() + (hasHeader ? 1 : 0))) {
            return new RViewHolder(footerView);
        } else
            return RViewHolder.get(mContext, parent, mItemLayoutId, position);

    }
//這裡定義抽象方法,我們在匿名內部類實現的時候實現此方法來呼叫控制元件
    public abstract void convert(RViewHolder holder, T item);
}
    對於RBaseAdapter稍微講解下,首先是泛型,這樣任何物件型別都可以使用,再來就是前面提到的headerview和footerview的解決,可以看到RBaseAdapter裡面定義了幾個方法,通過position的不同來載入不同的佈局的思想來新增headerview和footerview。
    Activity裡面呼叫
recyclerView.setAdapter(new RBaseAdapter<VirtualWinsBean>(mContext, R.layout.virtual_win_users_list_item) {

            @Override
            public void convert(RViewHolder holder, VirtualWinsBean item) {
                if (Util.checkNULL(item.getNick_name())) {
                    holder.setText(R.id.name, Util.HidePhone(item.getPhone() + ""));
                } else {
                    holder.setText(R.id.name, item.getNick_name());
                }
                RoundImageView networkImageView = holder.getView(R.id.photo);
                networkImageView.setLoadingImage(R.drawable.header_def);
                networkImageView.setDefultImage(R.drawable.header_def);
                networkImageView.LoadUrl(U.g(item.getFile_url()));
            }
        });
    初寫部落格,語言整理的不是很好,有什麼建議指導或者不懂得可以留言or私信我,祝大家升職加薪,贏娶白富美,走向人生巔峰。

我建了一個QQ群(群號:121606151),用於大家討論交流Android技術問題,有興趣的可以加下,大家一起進步。