Android——RecyclerView入門學(xué)習(xí)之RecyclerView.Adapter(三)

學(xué)習(xí)資料:

之前使用RecyclerView.Adapter鸟蜡,基本就類似套用公式,死步驟,對Adapter感到既熟悉又陌生后室。從去年我開始接觸學(xué)習(xí)Android之時,RecyclerView已經(jīng)開始大量被運用举庶,逐步取代ListView琳水。遂借嗽,正好琳轿,那就先直接學(xué)習(xí)RecyclerView.Adapter相關(guān)知識


1. RecyclerView.Adapter適配器

RecyclerView.Adapter判沟,一個抽象類,并支持泛型

public static abstract class Adapter<VH extends ViewHolder> {
   ...
}

定義一個MyRecyclerViewAdapter繼承RecyclerView.Adapter后利赋,Android Stuido提醒需要重寫3個方法,在重寫3個方法前猩系,一般會先定義一個Holder繼承RecycelrView.ViewHolder媚送,之后直接在MyRecyclerViewAdapter上,指定泛型就是RecyclerHolder

3個需要必須重寫的方法:

方法1:public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)

方法2:public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)

方法3:public int getItemCount()

在指定了泛型為RecyclerHoler后寇甸,方法2也會根據(jù)泛型改變onBindViewHolder(RecyclerHolder holder, int position)


1.1 onCreateViewHolder(ViewGroup parent, int viewType)創(chuàng)建Holder

源碼:

/**
 * Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent an item.
 * 
 * @param parent The ViewGroup into which the new View will be added after it is bound to an adapter position.
 * @param viewType The view type of the new View.
 *
 * @return A new ViewHolder that holds a View of the given view type.
 */
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
  • ViewGroup parent:可以簡單理解為item的根ViewGroup塘偎,item的子控件加載在其中
  • int viewTypeitem的類型,可以根據(jù)viewType來創(chuàng)建不同的ViewHolder拿霉,來加載不同的類型的item

這個方法就是用來創(chuàng)建出一個新的ViewHolder吟秩,可以根據(jù)需求的itemType,創(chuàng)建出多個ViewHolder绽淘。創(chuàng)建多個itemType時涵防,需要getItemViewType(int position)方法配合


1.2 onBindViewHolder(RecyclerHolder holder, int position)綁定ViewHolder

源碼:

**
*Called by RecyclerView to display the data at the specified position.
*This method should update the contents of the {@link ViewHolder#itemView} to reflect the item at the given position.
* 
*@param holder The ViewHolder which should be updated to represent the contents of the item at the given position in the data set.
*@param position The position of the item within the adapter's data set.
*/

public abstract void onBindViewHolder(VH holder, int position);
  • VH holder:就是在onCreateViewHolder()方法中,創(chuàng)建的ViewHolder
  • int positionitem對應(yīng)的DataList數(shù)據(jù)源集合的postion

postion就是adapter position沪铭,RecycelrViewitem的數(shù)量壮池,就是根據(jù)DataList數(shù)據(jù)源集合的數(shù)量來創(chuàng)建的


1.3 getItemCount()獲取Item的數(shù)目

源碼:

/**
 * Returns the total number of items in the data set held by the adapter.
 *
 * @return The total number of items in this adapter.
 */
public abstract int getItemCount();

這個方法的返回值,便是RecyclerView中實際item的數(shù)量杀怠。有些情況下椰憋,當(dāng)增加了HeaderView或者FooterView后,需要注意考慮這個返回值


1.4 簡單shi yong

一個最簡單的RecyclerViewAdapter

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.RecyclerHolder> {
    private Context mContext;
    private List<String> dataList = new ArrayList<>();

    public MyRecyclerViewAdapter(RecyclerView recyclerView) {
        this.mContext = recyclerView.getContext();
    }

    public void setData(List<String> dataList) {
        if (null != dataList) {
            this.dataList.clear();
            this.dataList.addAll(dataList);
            notifyDataSetChanged();
        }
    }

    @Override
    public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout, parent, false);
        return new RecyclerHolder(view);
    }

    @Override
    public void onBindViewHolder(RecyclerHolder holder, int position) {
        holder.textView.setText(dataList.get(position));
    }

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

    class RecyclerHolder extends RecyclerView.ViewHolder {
        TextView textView;

        private RecyclerHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.tv__id_item_layout);
        }
    }
}

我的個人習(xí)慣是單獨使用一個setData()方法將DataList傳遞進Adapter赔退,看到網(wǎng)上有一些博客中會通過構(gòu)造方法傳遞橙依。我一般會在網(wǎng)絡(luò)請求前就初始化Adapter,當(dāng)異步網(wǎng)絡(luò)請求拿到解析過的JSON數(shù)據(jù)后硕旗,調(diào)用這個方法將數(shù)據(jù)加載進Adapter窗骑,即使做了分頁,也可以比較方漆枚。但感覺這種方法終究會浪費一點性能

注意慧域,在 onCreateViewHolder()方法中:

View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout, parent, false);

inflate()方法使用的是3個參數(shù)的方法。


1.4.1 問題

以前使用2個參數(shù)的方法inflate(@LayoutRes int resource, @Nullable ViewGroup root)浪读,下面的形式

View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout,null);

遇到的一個問題

2個參數(shù)方法遇到的問題

兩種方法昔榴,使用的是同一套布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv__id_item_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:textAllCaps="false"
        android:textColor="@android:color/white"
        android:textSize="20sp" />

</LinearLayout>

item內(nèi)的TextView的寬是match_parent辛藻,但使用兩個參數(shù)的方法時,看起來卻是wrap_content的效果


1.4.2嘗試從源碼中找問題

兩個參數(shù)的方法源碼

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
        return inflate(resource, root, root != null);
}

兩個參數(shù)的方法內(nèi)部調(diào)用了3個參數(shù)的方法互订,此時inflate(resourceId, null, false)吱肌,rootnullattachToRootfalse

最終來到了這里仰禽,只保留了部分代碼:

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
    ...
    
    View result = root;
    
    ...
    
    // Temp is the root view that was found in the xml
    final View temp = createViewFromTag(root, name, inflaterContext, attrs);

    ViewGroup.LayoutParams params = null;
    ...
    
    if (root != null) {
    
        ...
        
        params = root.generateLayoutParams(attrs);
        
        ...               
    }
    
    ...
    
    rInflateChildren(parser, temp, attrs, true);
    
    ...
    
    if (root == null || !attachToRoot) {
        result = temp;
    }
 }

使用兩個參數(shù)的inflate()方法氮墨,ViewGroup.LayoutParams params最終為null;而如果使用3個參數(shù)的方法吐葵,最終params = params = root.generateLayoutParams(attrs)

這里為了減少出現(xiàn)問題的出現(xiàn)规揪,就使用3個參數(shù)的方法inflate(R.layout.id_rv_item_layout, parent, false)

這里看源碼也就看了這小段一段,inflate()方法的完整過程還是比較復(fù)雜的温峭,比較淺顯的知道問題出在哪里后猛铅,沒有深挖


1.4 點擊事件

完整代碼:

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.RecyclerHolder> {
    private Context mContext;
    private List<String> dataList = new ArrayList<>();
    private onRecyclerItemClickerListener mListener;

    public MyRecyclerViewAdapter(RecyclerView recyclerView) {
        this.mContext = recyclerView.getContext();
    }


    /**
     * 增加點擊監(jiān)聽
     */
    public void setItemListener(onRecyclerItemClickerListener mListener) {
        this.mListener = mListener;
    }

    /**
     * 設(shè)置數(shù)據(jù)源
     */
    public void setData(List<String> dataList) {
        if (null != dataList) {
            this.dataList.clear();
            this.dataList.addAll(dataList);
            notifyDataSetChanged();
        }
    }

    public List<String> getDataList() {
        return dataList;
    }

    @Override
    public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout, parent, false);
        // View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout,null);
        return new RecyclerHolder(view);
    }

    @Override
    public void onBindViewHolder(RecyclerHolder holder, int position) {
        holder.textView.setText(dataList.get(position));
        holder.textView.setOnClickListener(getOnClickListener(position));
    }

    private View.OnClickListener getOnClickListener(final int position) {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != mListener && null != v) {
                    mListener.onRecyclerItemClick(v, dataList.get(position), position);
                }
            }
        };
    }


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

    class RecyclerHolder extends RecyclerView.ViewHolder {
        TextView textView;

        private RecyclerHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.tv__id_item_layout);
        }
    }

    /**
     * 點擊監(jiān)聽回調(diào)接口
     */
    public interface onRecyclerItemClickerListener {
        void onRecyclerItemClick(View view, Object data, int position);
    }
}

定義一個接口onRecyclerItemClickerListener,這樣可以在Actiivty設(shè)置監(jiān)聽對象凤藏,之后為TextView設(shè)置點擊監(jiān)聽事件奸忽,在TextView的點擊事件方法中,使用onRecyclerItemClick()進行回調(diào)


在Activity中使用:

//設(shè)置點擊事件
adapter.setItemListener(new MyRecyclerViewAdapter.onRecyclerItemClickerListener() {
    @Override
    public void onRecyclerItemClick(View view, Object data, int position) {
        String s = (String) data;
        adapter.getDataList().set(position, s + "---->hi");
            adapter.notifyItemChanged(position);
        }
});

在監(jiān)控對象回調(diào)方法中揖庄,使用了notifyItemChanged(position)來進行局部刷新

點擊進行局部刷新

但這種方式會new出一大堆View.OnClickListener栗菜,還有一種思路是利用RecycelrViewonTouchListenerGestureDetector手勢來進行設(shè)置,可以看看三種方式實現(xiàn)RecyclerView的Item點擊事件


1.5 一系列的notifyData方法

一共有10個方法

方法 作用
notifyDataSetChanged() 通知RecycelrView進行全局刷新
notifyItemChanged(int position) 通知RecycelrViewadapter position處局進行部刷新
notifyItemRemoved(int position) 通知RecyclerView移除在adapter position處的item
notifyItemMoved(int fromPosition, int toPosition) 通知RecyclerView移除從fromPositiontoPositionitem
notifyItemRangeRemoved(int positionStart, int itemCount) 通知RecyclerView移除從positionStart開始的itemCountitem
notifyItemChanged(int position, Object payload) 通知RecyclerView改變指定positionitemobject
notifyItemRangeChanged(int positionStart,int itemCount) 通知RecyclerViewpositionStart開始改變itemCountitem
notifyItemRangeChanged(int positionStart,int itemCount,Object payload) 通知RecyclerViewpositionStart開始改變itemCountitem的對象
notifyItemInserted(int position) 通知RecyclerViewposition處插入一個item
notifyItemRangeInserted(int positionStart, int itemCount) 通知RecyclerViewpositionStart開始插入itemCountitem

有些情況下蹄梢,方法需要考慮組合使用疙筹,否則可能出現(xiàn)position錯亂,例如

在Adapter中移除或者插入item

/**
 * 移除指定Position的Item
 */
public void remove(int position) {
    if (dataList.size() == 0) return;
    dataList.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, dataList.size() - position);
}

//在Activity中使用 禁炒,設(shè)置點擊事件
adapter.setItemListener(new MyRecyclerViewAdapter.onRecyclerItemClickerListener() {
    @Override
    public void onRecyclerItemClick(View view, Object data, int position) {
        adapter.remove(position);
        // String s = (String) data;
        // adapter.inserted(position,s+"---->hi");
    }
});

//在指定位置插入一個item
public void inserted(int position, String s) {
    if (dataList.size() == 0) return;
    dataList.add(position, s);
    notifyItemInserted(position);
    notifyItemRangeChanged(position, dataList.size() - position);
}

notifyItemRemoved(position)雖然通知移除了RecycelrViewposition位置上的itemA腌歉,但itemA之后的一系列item也需要進行改變,也需要通知RecyclerView進行改變

但這兩個方法性能上都有問題齐苛,卡頓比較明顯翘盖,應(yīng)該會有更好的動態(tài)改變或者動態(tài)插入item的方法,以后學(xué)到了再補充


1.5 簡易的封裝

通用的ViewHolder:

public class BaseViewHolder extends RecyclerView.ViewHolder {
    private final SparseArray<View> sparseArray;

    public BaseViewHolder(View itemView) {
        super(itemView);
        this.sparseArray = new SparseArray<>(8); //一般一個Item 不會超過8種控件
    }

    public <T extends View> T getView(int viewId) {
        View view = sparseArray.get(viewId);
        if (view == null) {
            view = itemView.findViewById(viewId);
            sparseArray.put(viewId, view);
        }
        return (T) view;
    }

    public BaseViewHolder setText(int viewId, String text) {
        TextView tv = getView(viewId);
        if (tv != null) {
            tv.setText(text);
        }
        return this;
    }
}

主要思路就是使用SparseArray<View>將控件存起來


適配器:

public abstract class CommonBaseAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
    protected List<T> data = new ArrayList<>();
    protected int itemLayoutId;
    protected Context mContext;
    private onRecyclerItemClickerListener mListener;

    public CommonBaseAdapter(RecyclerView rv, @LayoutRes int itemLayoutId) {
        this.itemLayoutId = itemLayoutId;
        this.mContext = rv.getContext();
    }

    public void setData(List<T> data) {
        if (data != null) {
            this.data.clear();
            this.data.addAll(data);
            notifyDataSetChanged();
        }
    }

    /**
     *  增加點擊監(jiān)聽
     */
    public void setItemListener(onRecyclerItemClickerListener mListener) {
        this.mListener = mListener;
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //這里使用3個參數(shù)的方法
        View view = LayoutInflater.from(mContext).inflate(itemLayoutId, parent, false);
        return new BaseViewHolder(view);
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        bindViewData(holder, data.get(position), position);
        holder.itemView.setOnClickListener(getOnClickListener(position));
    }

    private View.OnClickListener getOnClickListener(final int position) {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null && v != null) {
                    mListener.onRecyclerItemClick(v, data.get(position), position);
                }
            }
        };
    }

    @Override
    public int getItemCount() {
        return this.data.size();
    }

    public abstract void bindViewData(BaseViewHolder holder, T item, int position);

    interface onRecyclerItemClickerListener {
        void onRecyclerItemClick(View view, Object data, int position);
    }
}

內(nèi)部提供一個抽象方法bindViewData()凹蜂,子類重寫抽象方法來做一些具體的操作馍驯。

封裝的很簡單,但平常學(xué)習(xí)使用也能減少一些重復(fù)代碼玛痊。網(wǎng)上有很多強大的封裝汰瘫,可以再深入學(xué)習(xí)一下為RecyclerView打造通用Adapter讓RecyclerView更加好用


使用:

public class RecyclerViewAdapter extends CommonBaseAdapter<String> {

    public RecyclerViewAdapter(RecyclerView rv, @LayoutRes int itemLayoutId, @IdRes int resId) {
        super(rv, itemLayoutId);

    }

    @Override
    public void bindViewData(BaseViewHolder holder, String item, int position) {
        holder.setText(R.id.textViewId, item);
    }
}

Activity中就可以進行使用

這個簡易的封裝并沒有對添加加載圖片的方法。加載圖片的方法一開始也我封裝在了這個CommonBaseAdapter中擂煞,但后來發(fā)現(xiàn)直接封裝在這里并不是好的思路

圖片需要做的處理比較多混弥,而且主流的庫有3個,為了易于維護,還是將圖片的操作單獨再封裝在一個工具類中蝗拿,在CommonBaseAdapter中使用操作圖片的工具類比較好


1.6 添加HeaderView和FooterViewiew

學(xué)的鴻洋大神的代碼和思路晾捏,涉及到了裝飾模式。還有一種添加方式是直接通過使用多種item直接在現(xiàn)有的CommonBaseAdapter來修改哀托,但感覺這種思路需要對CommonBaseAdapter改動的代碼太多惦辛,點擊事件的position也需要考慮,不如鴻洋大神的這種思路易于開發(fā)和維護

代碼:

public class HeaderAndFooterAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    private CommonBaseAdapter mAdapter;

    private static final int HEADER_VIEW_TYPE = 2 << 6;
    private static final int FOOTER_VIEW_TYPE = 2 << 5;

    private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
    private SparseArrayCompat<View> mFooterViews = new SparseArrayCompat<>();

    public HeaderAndFooterAdapter(CommonBaseAdapter mAdapter) {
        this.mAdapter = mAdapter;
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (null != mHeaderViews.get(viewType)) {
            return new HeaderAndFooterHolder(mHeaderViews.get(viewType));
        } else if (null != mFooterViews.get(viewType)) {
            return new HeaderAndFooterHolder(mFooterViews.get(viewType));
        }
        return mAdapter.onCreateViewHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        if (isHeaderViewPosition(position)) return;
        if (isFooterViewPosition(position)) return;
        mAdapter.onBindViewHolder(holder, position - getHeaderViewCount());
    }

    @Override
    public int getItemViewType(int position) {
        if (isHeaderViewPosition(position)) {
            return mHeaderViews.keyAt(position);
        } else if (isFooterViewPosition(position)) {
            return mFooterViews.keyAt(position-getHeaderViewCount()-getAdapterItemCount());
        }
        return mAdapter.getItemViewType(position - getHeaderViewCount());
    }

    @Override
    public int getItemCount() {
        return getHeaderViewCount() + getFooterViewCount() + getAdapterItemCount();
    }

    /**
     * 加入HeaderView
     */
    public void addHeaderView(View view) {
        mHeaderViews.put(mHeaderViews.size() + HEADER_VIEW_TYPE, view);
    }

    /**
     * 加入FooterView
     */
    public void addFootView(View view) {
        mFooterViews.put(mFooterViews.size() + FOOTER_VIEW_TYPE, view);
    }

    /**
     * HeaderView 的數(shù)目
     */
    public int getHeaderViewCount() {
        return mHeaderViews.size();
    }

    /**
     * FooterView 的數(shù)目
     */
    public int getFooterViewCount() {
        return mFooterViews.size();
    }

    /**
     * 是不是HeaderView的Position
     */
    private boolean isHeaderViewPosition(int position) {
        return position < getHeaderViewCount();
    }


    /**
     * 是不是FooterView的Position
     */
    private boolean isFooterViewPosition(int position) {
        return position >= getHeaderViewCount() + getAdapterItemCount();
    }

    /**
     * 得到Adapter中Item的數(shù)目
     */
    private int getAdapterItemCount() {
        return mAdapter.getItemCount();
    }

    private class HeaderAndFooterHolder extends BaseViewHolder {
        private HeaderAndFooterHolder(View itemView) {
            super(itemView);
        }
    }
}

封裝的思路:
add進來的view進行保存仓手,當(dāng)加載item時胖齐,利用itemTypeview進行類型判斷,如果是HeaderView或者FooterView就創(chuàng)建HeaderAndFooterHolder嗽冒,然后綁定只是用來顯示并沒有對HeaderView或者FooterView做其他更多事件的處理


使用也比較方便:

//數(shù)據(jù)適配器
RecyclerViewAdapter adapter = new RecyclerViewAdapter(rv, R.layout.id_rv_item_layout, R.id.tv__id_item_layout);
//頭View適配器
HeaderAndFooterAdapter headerAndFooterAdapter = new HeaderAndFooterAdapter(adapter);
//HeaderView
TextView headerView = new TextView(this);
headerView.setBackgroundColor(Color.BLACK);
headerView.setTextColor(Color.WHITE);
headerView.setWidth(1080);
headerView.setTextSize(50);
headerView.setText("我是頭");
headerAndFooterAdapter.addHeaderView(headerView);
//設(shè)置適配器
rv.setAdapter(headerAndFooterAdapter);
//添加數(shù)據(jù)
addData(adapter);
添加HeaderView

RecyelrView設(shè)置的適配器是headerAndFooterAdapter呀伙,而添加數(shù)據(jù)使用的是adapterHeaderAndFooterAdapter是支持添加多個HeaderView


1.6.1 GridLayoutManger和StaggeredGridLayoutManager跨列問題

上面添加HeaderView時添坊,使用的LinerLayoutManager剿另,當(dāng)使用GridLayoutManger時,便會有問題

HeaderView不能單獨占據(jù)一行

GridLayoutManager遇到問題

加入針對GridLayoutManager跨列處理的代碼:

/**
 *當(dāng)RecyelrView開始觀察Adapter會被回調(diào)
 */
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    mAdapter.onAttachedToRecyclerView(recyclerView);
    final RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
    if (manager instanceof GridLayoutManager) {
        final GridLayoutManager gridLayoutManager = (GridLayoutManager) manager;
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                int viewType = getItemViewType(position);
                //如果是HeaderView或者是FooterView帅腌,設(shè)置占據(jù)gridLayoutManager.getSpanCount()列
                if (null != mHeaderViews.get(viewType) || null != mFooterViews.get(viewType)) {
                    return gridLayoutManager.getSpanCount();
                }
                return 1;
            }
        });
    }
}

跨列處理

當(dāng)布局管理器為GridLayouManger時驰弄,對當(dāng)前要的添加的item進行判斷麻汰,如果是HeaderView或者是FooterView速客,就進行跨列處理,單獨占據(jù)一行


加入針對StaggeredGridLayoutManager跨列處理的代碼:

/**
 * 一個item通過adapter開始顯示會被回調(diào)
 */
@Override
public void onViewAttachedToWindow(BaseViewHolder holder) {
    super.onViewAttachedToWindow(holder);
    int position = holder.getLayoutPosition();
    if (isHeaderViewPosition(position)||isFooterViewPosition(position)){
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if (null != lp && lp instanceof StaggeredGridLayoutManager.LayoutParams){
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(true);//占滿一行
        }
    }
}

瀑布流跨列

當(dāng)布局管理器為StaggeredGridLayoutManager時五鲫,對當(dāng)前要的添加的item進行判斷溺职,如果是HeaderView或者是FooterView,就設(shè)置setFullSpan(true)位喂,占滿一行


2. 最后

RecyclerView.Adapter暫時大致就學(xué)習(xí)這些

本人很菜浪耘,有錯誤請指出

共勉 :)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市塑崖,隨后出現(xiàn)的幾起案子七冲,更是在濱河造成了極大的恐慌,老刑警劉巖规婆,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澜躺,死亡現(xiàn)場離奇詭異,居然都是意外死亡抒蚜,警方通過查閱死者的電腦和手機掘鄙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗡髓,“玉大人操漠,你說我怎么就攤上這事《稣猓” “怎么了浊伙?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵撞秋,是天一觀的道長。 經(jīng)常有香客問我吧黄,道長部服,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任拗慨,我火速辦了婚禮廓八,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赵抢。我一直安慰自己剧蹂,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布烦却。 她就那樣靜靜地躺著宠叼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪其爵。 梳的紋絲不亂的頭發(fā)上冒冬,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音摩渺,去河邊找鬼简烤。 笑死,一個胖子當(dāng)著我的面吹牛摇幻,可吹牛的內(nèi)容都是我干的横侦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼绰姻,長吁一口氣:“原來是場噩夢啊……” “哼枉侧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狂芋,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤榨馁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后帜矾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翼虫,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年黍特,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛙讥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡灭衷,死狀恐怖次慢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤迫像,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布劈愚,位于F島的核電站,受9級特大地震影響闻妓,放射性物質(zhì)發(fā)生泄漏菌羽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一由缆、第九天 我趴在偏房一處隱蔽的房頂上張望注祖。 院中可真熱鬧,春花似錦均唉、人聲如沸是晨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罩缴。三九已至,卻和暖如春层扶,著一層夾襖步出監(jiān)牢的瞬間箫章,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工镜会, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留檬寂,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓稚叹,卻偏偏與公主長得像焰薄,于是被迫代替她去往敵國和親拿诸。 傳聞我的和親對象是個殘疾皇子扒袖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 過去的這一兩年, RecyclerView越來越引起了我們Android開發(fā)人員的注意亩码,RecyclerView的...
    OlivineVip閱讀 1,251評論 0 14
  • 又到了更新博文的時間了季率,最近在看一本很不錯的心理學(xué)書籍,名字叫做 《拖延心理學(xué)》描沟,封面長下面這樣子 書的內(nèi)容主要是...
    ec95b5891948閱讀 57,434評論 38 472
  • 本文已授權(quán)微信公眾號:鴻洋(hongyangAndroid)在微信公眾號平臺原創(chuàng)首發(fā)飒泻。 轉(zhuǎn)載請標(biāo)明出處: http...
    專屬守護閱讀 1,503評論 0 2
  • 初識Android時,我對ListView吏廉、GradView中的Adapter一直半懂非懂泞遗,每次寫Adapter都...
    blink_dagger閱讀 5,948評論 4 10
  • 本周的周檢視完成情況: 1.專業(yè)閱讀1h 要求一周四天, 實際6天已達到 量變會引起質(zhì)變 2.文學(xué)閱讀1h 要求一...
    KUNGFUBUNNY閱讀 132評論 0 1