RecyclerView 基本使用

原文首發(fā) http://blog.lll0.net/post/recyclerview.html

強(qiáng)大而高效的 RecyclerView

ListView作為一個(gè)強(qiáng)大而有使用頻繁的控件槐沼,但是隨著我們業(yè)務(wù)的發(fā)展慢慢的就感覺 ListView 在某些業(yè)務(wù)場(chǎng)景中已經(jīng)不能滿足我們的業(yè)務(wù)需求曙蒸。舉個(gè)栗子:如果我們?cè)谝粋€(gè)頁面上需要加載不同的布局,在列表中間某一行加載一個(gè)廣告試圖岗钩,而這個(gè)廣告的布局和整個(gè)個(gè)列表的布局樣式是完全不一樣的纽窟。如果放在ListView 中,這種布局是不太好實(shí)現(xiàn)的兼吓。但是放在Google 提出的新控件 ReyclerView 中 實(shí)現(xiàn)這種布局是非常簡(jiǎn)單的臂港。

RecyclerView 是Android L版本中新添加的一個(gè)用來取代ListView的SDK,它的靈活性與可替代性比listview更好。

基本介紹

在使用RecyclerView中引入了幾個(gè)相關(guān)的類

  1. LayoutManager 用來確定每一個(gè)item如何進(jìn)行排列擺放趋艘,何時(shí)展示和隱藏疲恢。回收或重用一個(gè)View的時(shí)候瓷胧,LayoutManager會(huì)向適配器請(qǐng)求新的數(shù)據(jù)來替換舊的數(shù)據(jù)显拳,這種機(jī)制避免了創(chuàng)建過多的View和頻繁的調(diào)用findViewById方法(與ListView原理類似)。Google 為我們提供了 幾個(gè)基礎(chǔ)的布局
    1. LinearLayoutManager 線性布局布局樣式和ListView一樣 呈現(xiàn)的是線性
    2. GridLayoutManager 表格布局與GridView 一樣
    3. StaggeredGridLayoutManager 瀑布流布局 這是新的布局 簡(jiǎn)單描述就是加載的每個(gè)item在頁面上占有的空間都是不一樣的布局
  2. RecyclerView.Adapter RecyclerView 的適配器 數(shù)據(jù)的加載和item 的綁定都是通過這個(gè)類來實(shí)現(xiàn)搓萧。在使用的時(shí)候需要繼承該類來進(jìn)行相應(yīng)的處理
  3. RecyclerView.ViewHolder 同樣是使用中需要繼承該類杂数,然后進(jìn)行把數(shù)據(jù)和item里面的布局進(jìn)行綁定

在使用的時(shí)候 其實(shí)不用考慮復(fù)用的問題。

簡(jiǎn)單使用

1.添加依賴在build.gradle 中添加依賴 瘸洛,然后同步一下 引入依賴需要的包

dependencies {
     compile 'com.android.support:recyclerview-v7:25.1.1' 
}

2.布局中使用RecylerView

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.lll0.bus.ui.test_activity.RecyclerViewTestActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="368dp"
        android:layout_height="551dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp" />
</android.support.constraint.ConstraintLayout>

3.創(chuàng)建布局之后需要在Activity中獲得這個(gè)控件揍移,并聲明LayoutManagerAdapter,代碼如下

 mRecycler = (RecyclerView) findViewById(R.id.recycler);
 mRecycler.setLayoutManager(new LinearLayoutManager(mActitivity));
 recyclerViewAdapter = new RecyclerViewAdapter(beans,mActitivity);
 mRecycler.setAdapter(recyclerViewAdapter);

4.Adapter的創(chuàng)建

package net.lll0.bus.adapter.test;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import net.lll0.bus.suzhoubus.R;
import net.lll0.bus.adapter.RecyclerViewHolder;

import java.util.List;

/**
 * Created by liang on 2017/8/24.
 */

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {

    private String typeView01 = "item1";
    private String typeView02 = "item2";
    /**
     * 加載不同的兩種方式
     * 1. 傳入不同的數(shù)據(jù)源反肋,對(duì)應(yīng)的位置加載不同的布局
     * 2. 傳入一個(gè)數(shù)據(jù)源那伐,但是通過數(shù)據(jù)源里面特殊的字段判斷加載什么布局
     */
    private List<Bean> bean;
    private Context mContext;
    public RecyclerViewAdapter(List<Bean> bean, Context mContext) {
        this.bean = bean;
        this.mContext = mContext;
    }
    @Override
    public int getItemViewType(int position) {
        //通過這個(gè)區(qū)分加載不同 view
        //通過判斷特殊的字段加載不同的布局

        return bean.get(position).type;
    }
    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //通過 getTtemViewType 返回的 內(nèi)容加載不同 的布局

        //假設(shè)加載 三中布局分別對(duì)應(yīng) 1 2 3

        if (1 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.item, parent, false), viewType);
        } else if (2 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.item_lineinfo, parent, false), viewType);
        } else if (3 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.nav_header_home, parent, false), viewType);
        }
        return null;
    }
    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        //onCreateViewHolder 為不同的布局綁定對(duì)應(yīng)的數(shù)據(jù)
        Bean bean = this.bean.get(position);
        int type = bean.type;
        if (1 == type) {
            holder.setText(R.id.textView2,"textView2");
            holder.setText(R.id.textView3,"textView3");
        } else if (2 == type) {
            holder.setText(R.id.lineinfo_index,position+"");
        } else if (3 == type) {
        }
    }
    @Override
    public int getItemCount() {
        //主要是計(jì)算 加載數(shù)據(jù)的總數(shù)
        return bean.size();
    }
}

5.RecyclerView.ViewHolder 子類的實(shí)現(xiàn) ,這是一個(gè)通用的ViewHolder

package net.lll0.bus.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
/**
 * Created by liang on 2016/2/15.
 */
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
    private SparseArray<View> mViews;//集合類石蔗,layout里包含的View,以view的id作為key罕邀,value是view對(duì)象
    private Context mContext;//上下文對(duì)象
    private int type;

    public RecyclerViewHolder(Context ctx, View itemView) {
        super(itemView);
        mContext = ctx;
        mViews = new SparseArray<View>();
    }
    public RecyclerViewHolder(Context ctx, View itemView,int type) {
        super(itemView);
        mContext = ctx;
        mViews = new SparseArray<View>();
        this.type = type;
    }
    public View getItemView() {
        return itemView;
    }
    /*
     * 通過空間id在SparseArray集合中找出用戶View
     * @param viewId  控件的id
     * @param <T>  具體的是那個(gè)控件
     * @return  當(dāng)然是返回你要找的控件了
     */
    private <T extends View> T findViewById(int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = itemView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }
    /**
     * 通過findViewById以及控件id的到用戶的空間對(duì)象
     *
     * @param viewId
     * @return
     */
    public View getView(int viewId) {
        return findViewById(viewId);
    }
    public TextView getTextView(int viewId) {
        return (TextView) getView(viewId);
    }
    public Button getButton(int viewId) {
        return (Button) getView(viewId);
    }
    public ImageView getImageView(int viewId) {
        return (ImageView) getView(viewId);
    }
    public ImageButton getImageButton(int viewId) {
        return (ImageButton) getView(viewId);
    }
    public EditText getEditText(int viewId) {
        return (EditText) getView(viewId);
    }
    public RecyclerViewHolder setText(int viewId, String value) {
        TextView view = findViewById(viewId);
        view.setText(value);
        return this;
    }
    public RecyclerViewHolder setBackground(int viewId, int resId) {
        View view = findViewById(viewId);
        view.setBackgroundResource(resId);
        return this;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    /**
     * 通過該方法可以的到對(duì)應(yīng)控件的點(diǎn)擊事件
     *
     * @param viewId   控件的id
     * @param listener 需要實(shí)現(xiàn)的監(jiān)聽器
     * @return
     */
    public RecyclerViewHolder setClickListener(int viewId, View.OnClickListener listener) {
        View view = findViewById(viewId);
        view.setOnClickListener(listener);
        return this;
    }
}

運(yùn)行

只要實(shí)現(xiàn)以上代碼,就能實(shí)現(xiàn)具體的內(nèi)容养距。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诉探,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子棍厌,更是在濱河造成了極大的恐慌肾胯,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耘纱,死亡現(xiàn)場(chǎng)離奇詭異敬肚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)揣炕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門帘皿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人畸陡,你說我怎么就攤上這事∷涮睿” “怎么了丁恭?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)斋日。 經(jīng)常有香客問我牲览,道長(zhǎng),這世上最難降的妖魔是什么恶守? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任第献,我火速辦了婚禮贡必,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庸毫。我一直安慰自己仔拟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布飒赃。 她就那樣靜靜地躺著利花,像睡著了一般。 火紅的嫁衣襯著肌膚如雪载佳。 梳的紋絲不亂的頭發(fā)上炒事,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音蔫慧,去河邊找鬼挠乳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛姑躲,可吹牛的內(nèi)容都是我干的欲侮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼肋联,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼威蕉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起橄仍,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤韧涨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后侮繁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虑粥,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宪哩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娩贷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锁孟,死狀恐怖彬祖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情品抽,我是刑警寧澤储笑,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站圆恤,受9級(jí)特大地震影響突倍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一羽历、第九天 我趴在偏房一處隱蔽的房頂上張望焊虏。 院中可真熱鬧,春花似錦秕磷、人聲如沸诵闭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涂圆。三九已至,卻和暖如春币叹,著一層夾襖步出監(jiān)牢的瞬間润歉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工颈抚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踩衩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓贩汉,卻偏偏與公主長(zhǎng)得像驱富,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匹舞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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