android開(kāi)發(fā)之recycleView的使用

一、recycleView的使用場(chǎng)景

1、多種樣式的列表
2撩嚼、宮格和列表同時(shí)存在
3、分類列表比如通訊錄城市列表等

二挖帘、基本使用

在布局文件中聲明
在Activity中使用
Adapter的創(chuàng)建
添加單擊事件
Item動(dòng)畫(huà)
更新數(shù)據(jù)

1完丽、在布局文件中聲明

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
 

2、在Activity中使用

復(fù)制代碼
// 1,找到這個(gè)View
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
// 2,設(shè)置布局管理LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// 3拇舀,(可選)如果可以確定每個(gè)item的高度是固定的逻族,設(shè)置這個(gè)選項(xiàng)可以提高性能
mRecyclerView.setHasFixedSize(true);
// 4,設(shè)置Adapter
mRecyclerView.setAdapter(new MyAdapter());
復(fù)制代碼
 

目前SDK中提供了三種自帶的LayoutManager:

LinearLayoutManager

GridLayoutManager

StaggeredGridLayoutManager

LinearLayoutManager

mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
GridLayoutManager

mLayoutManager = new GridLayoutManager(context,columNum);
mRecyclerView.setLayoutManager(mLayoutManager);
注:在Grid布局中也可以設(shè)置列表的Orientation屬性骄崩,來(lái)實(shí)現(xiàn)橫向和縱向的Grid布局聘鳞。

StaggeredGridLayoutManager

瀑布流就使用StaggeredGridLayoutManager吧薄辅,具體使用方法見(jiàn)http://blog.csdn.net/duanymin/article/details/44979355

 

3、Adapter的創(chuàng)建

復(fù)制代碼
 1 public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
 2     public String[] datas = null;
 3     public MyAdapter(String[] datas) {
 4         this.datas = datas;
 5     }
 6     //創(chuàng)建新View搁痛,被LayoutManager所調(diào)用
 7     @Override
 8     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
 9         View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);
10         ViewHolder vh = new ViewHolder(view);
11         return vh;
12     }
13     //將數(shù)據(jù)與界面進(jìn)行綁定的操作
14     @Override
15     public void onBindViewHolder(ViewHolder viewHolder, int position) {
16         viewHolder.mTextView.setText(datas[position]);
17     }
18     //獲取數(shù)據(jù)的數(shù)量
19     @Override
20     public int getItemCount() {
21         return datas.length;
22     }
23     //自定義的ViewHolder长搀,持有每個(gè)Item的的所有界面元素
24     public static class ViewHolder extends RecyclerView.ViewHolder {
25         public TextView mTextView;
26         public ViewHolder(View view){
27         super(view);
28             mTextView = (TextView) view.findViewById(R.id.text);
29         }
30     }
31 }
復(fù)制代碼
 

4、添加單擊事件

復(fù)制代碼
// 1 定義接口
public static interface OnRecyclerViewItemClickListener {
    void onItemClick(View view , DataModel data);
}

// 2 添加接口和設(shè)置接口的方法
private OnRecyclerViewItemClickListener mOnItemClickListener = null;
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
    this.mOnItemClickListener = listener;
}

// 3 在Adapter實(shí)現(xiàn)OnClickListener方法
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        ViewHolder vh = new ViewHolder(view);
        //將創(chuàng)建的View注冊(cè)點(diǎn)擊事件
        view.setOnClickListener(this);
        return vh;
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int i) {
        viewHolder.mTextView.setText(datas.get(i).title);
        //將數(shù)據(jù)保存在itemView的Tag中鸡典,以便點(diǎn)擊時(shí)進(jìn)行獲取
        viewHolder.itemView.setTag(datas.get(i));
    }
    ...
    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            //注意這里使用getTag方法獲取數(shù)據(jù)

        }
    ...
}
復(fù)制代碼
在Activity中

復(fù)制代碼
mAdapter = new MyAdapter(getDummyDatas());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new MyAdapter.OnRecyclerViewItemClickListener() {
    @Override
    public void onItemClick(View view, DataModel data) {
        //DO your fucking bussiness here!
    }
});
復(fù)制代碼
 

5源请、Item動(dòng)畫(huà)

// 設(shè)置item動(dòng)畫(huà)
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
如果要自定義動(dòng)畫(huà)效果需要繼承ItemAnimator

GitHub上的動(dòng)畫(huà)效果:RecyclerViewItemAnimators

 

6、更新數(shù)據(jù)

這里更新數(shù)據(jù)集不是用adapter.notifyDataSetChanged()而是 notifyItemInserted(position)與notifyItemRemoved(position) 否則沒(méi)有動(dòng)畫(huà)效果彻况。 

為adapter中添加兩個(gè)方法:

復(fù)制代碼
public void addData(int position) {
    mDatas.add(position, "Insert One");
    notifyItemInserted(position);
}

public void removeData(int position) {
    mDatas.remove(position);
    notifyItemRemoved(position);
}

三谁尸、復(fù)雜布局的實(shí)現(xiàn)邏輯

1、RecycleView的關(guān)鍵成員

  A纽甘、Type:類型 通過(guò)getItemViewType(position)獲取
  B良蛮、Holder(熟悉ListView的都知道)
        1、holder在recycleView中保存view的單位
        2悍赢、記錄recycleview中的基本信息
  C决瞳、RecycleView.Recycler(保存了一些緩存機(jī)制)
         1、Recycleview中被緩存的holder
         2左权、多個(gè)RecycleView共用一個(gè)RecycleredPool(緩存池)
         3皮胡、配置緩存size

2、getItemViewType

 a赏迟、ItemType保存在Holder中
 B屡贺、Holder根據(jù)position被緩存在cache中
 RecycleView之所以流暢,就是當(dāng)我們需要復(fù)用的時(shí)候系統(tǒng)會(huì)在cache中拿holder锌杀,進(jìn)而實(shí)現(xiàn)使用流暢甩栈。
 C、遍歷緩存中的holder糕再,如果Type一致就返回量没。  

3、多布局的實(shí)現(xiàn)

 A突想、復(fù)寫(xiě)getItemViewType方法
 B殴蹄、需要處理getItemCount方法
 C、按照獲取的Type處理onCreateViewHolder和OnBinderViewHolder蒿柳。

4饶套、數(shù)據(jù)的處理

 A漩蟆、把多個(gè)數(shù)據(jù)類型都包裝進(jìn)一個(gè)Object(不利于查找)
 B垒探、封裝RecycleView.Adapter,把一些不同的item當(dāng)做header添加進(jìn)來(lái)

5怠李、多布局類型運(yùn)行流程

滾動(dòng)布局——》通過(guò)getItemViewType獲取Type類型——》根據(jù)類型尋找holder——》如果holder為null執(zhí)行adapter.createrHolder圾叼,否則執(zhí)行adapter.bindViewHolder.

四蛤克、通過(guò)LinearLayoutManager實(shí)現(xiàn)多布局代碼:

 recyclerView = (RecyclerView) findViewById(R.id.recycleview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this,
                LinearLayoutManager.VERTICAL,false));
        adapter = new MyRecyclerViewAdapter(this);
        recyclerView.setAdapter(adapter);
        initData();

/**
* 模擬數(shù)據(jù)
/
private void initData(){
List<DataBean> dataBeanList = new ArrayList<>();
for(int i=0;i<20;i++){
int type = (int) ((Math.random()
3)+1);
DataBean dataBean = new DataBean();
dataBean.titelColor = typeColors[type-1];
dataBean.type = type;
dataBean.contentColor = typeColors[(type+1)%3];
dataBean.content = "content"+i;
dataBean.name = "name"+i;
dataBeanList.add(dataBean);
}
adapter.addData(dataBeanList);
}

}

多布局就是不同的Viewholder加載渲染不同的布局,通過(guò)Type進(jìn)行區(qū)分夷蚊。
布局一和所對(duì)應(yīng)的viewHolder构挤、

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:gravity="center_vertical"
    android:layout_height="60dp">
    <ImageView
        android:layout_marginLeft="20dp"
        tools:src="@mipmap/ic_launcher"
        android:id="@+id/title_image"
        android:layout_width="45dp"
        android:layout_height="45dp" />

    <TextView
        android:id="@+id/name_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="測(cè)試名字"
        android:layout_marginLeft="10dp"
        />
</LinearLayout>


/**
 * 布局一viewholder
 * Created by zzj on 2017/2/16.
 */

public class TypeOneHolder extends TypeAbstractHolder {
    private ImageView titel_image;
    private TextView name_tv;
    public TypeOneHolder(View itemView) {
        super(itemView);
        titel_image = (ImageView) itemView.findViewById(R.id.title_image);
        name_tv = (TextView) itemView.findViewById(R.id.name_tv);
    }

    @Override
    public void onBindData(DataBean dataBean) {
        titel_image.setImageResource(dataBean.titelColor);
        name_tv.setText(dataBean.name);
    }
}

布局二、

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:gravity="center_vertical"
    android:layout_height="60dp">
    <ImageView
        android:layout_marginLeft="20dp"
        tools:src="@mipmap/ic_launcher"
        android:id="@+id/title_image"
        android:layout_width="45dp"
        android:layout_height="45dp" />


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >
        <TextView
            android:id="@+id/name_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="測(cè)試名字"
            android:layout_marginLeft="10dp"
            />
        <TextView
            android:id="@+id/content_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="測(cè)試內(nèi)容"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="10dp"
            />
    </LinearLayout>
</LinearLayout>


/**布局二viewholder
 * Created by zzj on 2017/2/16.
 */

public class TypeTwoHolder extends TypeAbstractHolder {
    private ImageView titel_image;
    private TextView name_tv,content_tv;
    public TypeTwoHolder(View itemView) {
        super(itemView);
        titel_image = (ImageView) itemView.findViewById(R.id.title_image);
        name_tv = (TextView) itemView.findViewById(R.id.name_tv);
        content_tv = (TextView) itemView.findViewById(R.id.content_tv);

    }

    @Override
    public void onBindData(DataBean dataBean) {
        titel_image.setImageResource(dataBean.titelColor);
        name_tv.setText(dataBean.name);
        content_tv.setText(dataBean.content);
    }
}

布局三惕鼓、

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:gravity="center_vertical"
    android:layout_height="60dp">
    <ImageView
        android:layout_marginLeft="20dp"
        tools:src="@mipmap/ic_launcher"
        android:id="@+id/title_image"
        android:layout_width="45dp"
        android:layout_height="45dp" />


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >
        <TextView
            android:id="@+id/name_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="測(cè)試名字"
            android:layout_marginLeft="10dp"
            />
        <TextView
            android:id="@+id/content_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="測(cè)試內(nèi)容"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="10dp"
            />
    </LinearLayout>

    <ImageView
        android:id="@+id/content_image"
        tools:src="@mipmap/ic_launcher"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:layout_marginLeft="60dp"
        />
</LinearLayout>


/**布局三viewholder
 * Created by zzj on 2017/2/16.
 */

public class TypeThreeHolder extends TypeAbstractHolder {
    private ImageView titel_image,content_image;
    private TextView name_tv,content_tv;
    public TypeThreeHolder(View itemView) {
        super(itemView);
        titel_image = (ImageView) itemView.findViewById(R.id.title_image);
        name_tv = (TextView) itemView.findViewById(R.id.name_tv);
        content_tv = (TextView) itemView.findViewById(R.id.content_tv);
        content_image = (ImageView) itemView.findViewById(R.id.content_image);
    }

    @Override
    public void onBindData(DataBean dataBean) {
        titel_image.setImageResource(dataBean.titelColor);
        name_tv.setText(dataBean.name);
        content_tv.setText(dataBean.content);
        content_image.setImageResource(dataBean.contentColor);
    }
}

ViewHolder的父類

public abstract class TypeAbstractHolder extends RecyclerView.ViewHolder {

    public TypeAbstractHolder(View itemView) {
        super(itemView);
    }

    /**
     * 綁定數(shù)據(jù)
     * @param dataBean
     */
    public abstract void onBindData(DataBean dataBean);
}

在Adapter中創(chuàng)建綁定ViewHolder


      @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case DataBean.TYPE_ONE:
                return new TypeOneHolder(inflater.inflate(R.layout.item_recycleview_linear_type_one,parent,false));
            case DataBean.TYPE_TWO:
                return new TypeTwoHolder(inflater.inflate(R.layout.item_recycleview_linear_type_two,parent,false));
            case DataBean.TYPE_THREE:
                return new TypeThreeHolder(inflater.inflate(R.layout.item_recycleview_linear_type_three,parent,false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ((TypeAbstractHolder)holder).onBindData(dataBeanList.get(position));
    }

由上而下的多布局就基本創(chuàng)建完成筋现。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市箱歧,隨后出現(xiàn)的幾起案子矾飞,更是在濱河造成了極大的恐慌,老刑警劉巖呀邢,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洒沦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡价淌,警方通過(guò)查閱死者的電腦和手機(jī)申眼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蝉衣,“玉大人括尸,你說(shuō)我怎么就攤上這事÷蚰耍” “怎么了姻氨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)剪验。 經(jīng)常有香客問(wèn)我肴焊,道長(zhǎng),這世上最難降的妖魔是什么功戚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任娶眷,我火速辦了婚禮,結(jié)果婚禮上啸臀,老公的妹妹穿的比我還像新娘届宠。我一直安慰自己,他們只是感情好乘粒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布豌注。 她就那樣靜靜地躺著,像睡著了一般灯萍。 火紅的嫁衣襯著肌膚如雪轧铁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,775評(píng)論 1 307
  • 那天旦棉,我揣著相機(jī)與錄音齿风,去河邊找鬼药薯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛救斑,可吹牛的內(nèi)容都是我干的童本。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼脸候,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼穷娱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起运沦,我...
    開(kāi)封第一講書(shū)人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鄙煤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后茶袒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體梯刚,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年薪寓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亡资。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡向叉,死狀恐怖锥腻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情母谎,我是刑警寧澤瘦黑,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站奇唤,受9級(jí)特大地震影響幸斥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咬扇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一甲葬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧懈贺,春花似錦经窖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至堡妒,卻和暖如春配乱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工宪卿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人万栅。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓佑钾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親烦粒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子休溶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

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

  • RecycleView多種布局顯示 1.前言 我們知道ListView多種布局顯示用到兩個(gè)方法一個(gè)getItemV...
    TheTwo閱讀 7,932評(píng)論 15 56
  • Android四大組件: activity: activity的生命周期:activity是context的子類,...
    梧桐樹(shù)biu閱讀 644評(píng)論 0 2
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,192評(píng)論 25 707
  • 3件事: 1. 早上的手忙腳亂及急躁扰她。 2. 環(huán)境帶來(lái)的倦怠兽掰。 3. 處理claim的效率及協(xié)助。 10點(diǎn)開(kāi)會(huì)徒役,超...
    冰羯閱讀 209評(píng)論 0 0
  • 不能再揮霍錢財(cái)了孽尽,你所說(shuō)的把最后的這幾年過(guò)得精彩,是以父母的逐漸衰老為代價(jià)的忧勿。不要只顧著奮斗杉女,只顧著享受而忽略了父...
    奮斗的小柯基閱讀 77評(píng)論 0 0