RecyclerView點(diǎn)滴

一、開(kāi)發(fā)Android的程序員都知道LIstView,2014年Google Android L 版發(fā)布,新的控件RecyclerView取代之前ListView,為什么Google要取代它,通過(guò)自己實(shí)踐使用,發(fā)現(xiàn)它比ListView有以下幾大有點(diǎn):

1.提供了一種插拔式的體驗(yàn),高度的解耦,異常的靈活使用

2.顯示的樣式更豐富包括水平,豎直,Grid,瀑布顯示方式

3.可以通過(guò)ItemDecoration自定義Item間的間隔

4.可以通過(guò)ItemAnimator自定義Item增、刪動(dòng)畫(huà)(也可設(shè)置默認(rèn)動(dòng)畫(huà))

5.代碼內(nèi)聚不需要手動(dòng)創(chuàng)建ViewHolder

二 、使用RecyclerView先了解他們的用處

1.RecyclerView.LayoutManager--------負(fù)責(zé)item顯示方式

2.RecyclerView.Adapter---------------處理數(shù)據(jù)集合并負(fù)責(zé)綁定視圖

3.ViewHolder------------------------持有item所有的用于綁定數(shù)據(jù)的View

4.ItemDecoration---------------------負(fù)責(zé)繪制Item附近的分割線

5.ItemAnimator-----------------------為Item的一般操作添加動(dòng)畫(huà)效果

LayoutManager主要作用是,測(cè)量和擺放RecyclerView中itemView,以及當(dāng)itemView對(duì)用戶不可見(jiàn)時(shí)循環(huán)復(fù)用處理。 通過(guò)設(shè)置Layout Manager的屬性,可以實(shí)現(xiàn)水平滾動(dòng)、垂直滾動(dòng)、Gird,瀑布顯示

mRecyclerView.setLayoutManager(new LinearLayoutManager(this));設(shè)置橫向布局

當(dāng)然還可以設(shè)置Gird布局GridLayoutManager,瀑布布局StaggeredGridLayoutManager

還有一些其他的API:

findFirstVisibleItemPosition()返回當(dāng)前第一個(gè)可見(jiàn)Item的position

findFirstCompletelyVisibleItemPosition()返回當(dāng)前第一個(gè)完全可見(jiàn)Item的position

findLastVisibleItemPosition()返回當(dāng)前最后一個(gè)可見(jiàn)Item的position

findLastCompletelyVisibleItemPosition()返回當(dāng)前最后一個(gè)完全可見(jiàn)Item的position

RecyclerView.Adapter扮演著兩個(gè)角色。一、根據(jù)不同ViewType創(chuàng)建與之相應(yīng)的的Item-Layout,二、訪問(wèn)數(shù)據(jù)集合并將數(shù)據(jù)綁定到正確的View上。這就需要我們重寫(xiě)以下函數(shù):

public VH onCreateViewHolder(ViewGroup parent, int viewType)創(chuàng)建Item視圖,并返回相應(yīng)的ViewHolder

public void onBindViewHolder(VH holder, int position)綁定數(shù)據(jù)到正確的Item視圖上。

public int getItemCount() 返回該Adapter所持有的Itme數(shù)量

public class MyAdapter extends RecyclerView.Adapter {

public String[] datas = null;

public MyAdapter(String[] datas) {

this.datas = datas;

}

//創(chuàng)建新View,被LayoutManager所調(diào)用

@Override

public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);

ViewHolder vh = new ViewHolder(view);

return vh;

}

//將數(shù)據(jù)與界面進(jìn)行綁定的操作

@Override

public void onBindViewHolder(ViewHolder viewHolder, int position) {

viewHolder.mTextView.setText(datas[position]);

}

//獲取數(shù)據(jù)的數(shù)量

@Override

public int getItemCount() {

return datas.length;

}

//自定義的ViewHolder,持有每個(gè)Item的的所有界面元素

public static class ViewHolder extends RecyclerView.ViewHolder {

public TextView mTextView;

public ViewHolder(View view){

super(view);

mTextView = (TextView) view.findViewById(R.id.text);

}

}

}

RecyclerView.ItemDecoration通過(guò)設(shè)置recyclerView.addItemDecoration(new DividerDecoration(this));來(lái)改變Item之間的偏移量或者對(duì)Item進(jìn)行裝飾。當(dāng)然,你也可以對(duì)RecyclerView設(shè)置多個(gè)ItemDecoration,列表展示的時(shí)候會(huì)遍歷所有的ItemDecoration并調(diào)用里面的繪制方法,對(duì)Item進(jìn)行裝飾。RecyclerView.ItemDecoration是一個(gè)抽象類,可以通過(guò)重寫(xiě)以下三個(gè)方法,來(lái)實(shí)現(xiàn)Item之間的偏移量或者裝飾效果:

public void onDraw(Canvas c, RecyclerView parent) 裝飾的繪制在Item條目繪制之前調(diào)用,所以這有可能被Item的內(nèi)容所遮擋

public void onDrawOver(Canvas c, RecyclerView parent) 裝飾的繪制在Item條目繪制之后調(diào)用,因此裝飾將浮于Item之上

public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) 與padding或margin類似,LayoutManager在測(cè)量階段會(huì)調(diào)用該方法,計(jì)算出每一個(gè)Item的正確尺寸并設(shè)置偏移量。

RecyclerView.ItemAnimator,ItemAnimator能夠幫助Item實(shí)現(xiàn)獨(dú)立的動(dòng)畫(huà)。ItemAnimator作觸發(fā)于以下三種事件:

1.某條數(shù)據(jù)被插入到數(shù)據(jù)集合中

2.從數(shù)據(jù)集合中移除某條數(shù)據(jù)

3.更改數(shù)據(jù)集合中的某條數(shù)據(jù)

幸運(yùn)的是,在Android中默認(rèn)實(shí)現(xiàn)了一個(gè)DefaultItemAnimator,我們可以通過(guò)以下代碼為Item增加動(dòng)畫(huà)效果:

recyclerView.setItemAnimator(new DefaultItemAnimator());

在之前的版本中,當(dāng)時(shí)據(jù)集合發(fā)生改變時(shí),我們通過(guò)調(diào)用.notifyDataSetChanged(),來(lái)刷新列表,因?yàn)檫@樣做會(huì)觸發(fā)列表的重繪,所以并不會(huì)出現(xiàn)任何動(dòng)畫(huà)效果,因此需要調(diào)用一些以notifyItem*()作為前綴的特殊方法,比如:

public final void notifyItemInserted(int position) 向指定位置插入Item

public final void notifyItemRemoved(int position) 移除指定位置Item

public final void notifyItemChanged(int position) 更新指定位置Item

三、Recycler設(shè)置監(jiān)聽(tīng)Listeners

當(dāng)使用了一段時(shí)間的RecyclerView,發(fā)現(xiàn)為其每一項(xiàng)添加點(diǎn)擊事件并沒(méi)有ListView那么輕松,像ListView直接加個(gè)OnItemClickListener就行了。實(shí)際上我們不要把RecyclerView當(dāng)做ListView的一個(gè)升級(jí)版,希望大家把他看做一個(gè)容器,同時(shí)里面包含了很多不同的Item,它們可以以不同方式排列組合,非常靈活,點(diǎn)擊方式你可以按照你自己的意愿進(jìn)行實(shí)現(xiàn)。

本節(jié)主要講解如何為RecyclerView添加點(diǎn)擊事件, 并簡(jiǎn)單介紹如何進(jìn)行Item增加刪除。

添加點(diǎn)擊事件

上面講了如何使用RecyclerView的Adpater,其實(shí)我們會(huì)發(fā)現(xiàn),Adapter是添加點(diǎn)擊事件一個(gè)很好的地方,里面是構(gòu)造布局等View的主要場(chǎng)所,也是數(shù)據(jù)和布局進(jìn)行綁定的地方。首先我們?cè)贏dapter中創(chuàng)建一個(gè)實(shí)現(xiàn)點(diǎn)擊接口,其中view是點(diǎn)擊的Item,data是我們的數(shù)據(jù),因?yàn)槲覀兿胫牢尹c(diǎn)擊的區(qū)域部分的數(shù)據(jù)是什么,以便我下一步進(jìn)行操作:

public static interface OnRecyclerViewItemClickListener {

void onItemClick(View view , DataModel data);

}

定義完接口,添加接口和設(shè)置Adapter接口的方法:

private OnRecyclerViewItemClickListener mOnItemClickListener = null;

public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {

this.mOnItemClickListener = listener;

}

那么這個(gè)接口用在什么地方呢?如下代碼所示,我們?yōu)锳dapter實(shí)現(xiàn)OnClickListener方法:

public class MyAdapter extends RecyclerView.Adapter 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ù)

mOnItemClickListener.onItemClick(v,(DataModel)v.getTag());

}

}

...

}

做完這些事情,我們就可以在Activity或其他地方為RecyclerView添加項(xiàng)目點(diǎn)擊事件了,如在MainActivity中:

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!

}

});

完成了以上代碼就可以為RecyclerView添加項(xiàng)目點(diǎn)擊事件了,下面我們來(lái)看看RecyclerView如何添加和刪除數(shù)據(jù)并在界面上顯示。

添加刪除數(shù)據(jù)

以前在ListView當(dāng)中,我們只要修改后數(shù)據(jù)用Adapter的notifyDatasetChange一下就可以更新界面。然而在RecyclerView中還有一些更高級(jí)的用法:

添加數(shù)據(jù):

public void addItem(DataModel content, int position) {

datas.add(position, content);

notifyItemInserted(position); //Attention!

}

刪除數(shù)據(jù):

public void removeItem(DataModel model) {

int position = datas.indexOf(model);

datas.remove(position);

notifyItemRemoved(position);//Attention!

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容