MaterialDesign-RecyleView探究及使用【一】-基本用法

概述

RecylerView控件從Android 5.0開始谷歌公司推出的新控件用于替代ListView、GridView的控件。不是已經(jīng)有ListView了嗎,為什么還要RecyclerView呢?下面我們看下recyleview都有哪些特點。

recyleview主要特點:

1、RecyclerView提供了一種插拔式的體驗,高度的解耦,異常的靈活;

2、自帶了性能優(yōu)化(ViewHolder復(fù)用機制);

3、低耦合高內(nèi)聚。(通過設(shè)置它提供的不同LayoutManager,ItemDecoration , ItemAnimator實現(xiàn)不同視圖效果。)

recyleview缺點:(同listveiw對比)

1、RecyclerView沒有條目點擊、長按事件,需要自己封裝。

2、RecyclerView沒有默認(rèn)的分割線,需要自己繪制。

3、RecyclerView 沒有添加頭部和底部視圖的功能

recyleview主要功能:

我們會從如下幾個功能方面實現(xiàn)recyleview主要功能

1、通過布局管理器LayoutManager控制你想要其顯示視圖樣式的方式;

2、通過ItemDecoration控制Item間的間隔線的展示(需要自定義繪制);

3、通過ItemAnimator控制Item增刪的動畫

4、通過自己封裝RecyclerView條目點擊、長按事件;

5、RecyclerView 添加頭部和底部(需要自己實現(xiàn),recyleview自身沒有此功能)

6、RecyclerView 功能延展

基本用法

RecyclerView 使用時的基本代碼塊:

相對于ListView的代碼,ListView可能只需要去設(shè)置一個adapter就能正常使用了。而RecyclerView基本需要下面好多的步驟,那么為什么會添加這么多的步驟呢?其高度的解耦,給予你充分的定制自由(所以你才可以輕松的通過這個控件實現(xiàn)ListView,GirdView,瀑布流等效果)。

recyleview = this.findViewById(R.id.recyleview);

//設(shè)置布局管理器

recyleview.setLayoutManager(linearLayoutManager);

//添加分割線

recyleview.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.HORIZONTAL, R.drawable.line_diver_gray));

// //設(shè)置Item增加、移除動畫

recyleview.setItemAnimator(new DefaultItemAnimator());

//設(shè)置adapter

adapter = new RVElementaryAdapter(data);

recyleview.setAdapter(adapter);

//設(shè)置條目的點擊事件

adapter.setOnItemClickListener(this);

//設(shè)置條目的長按事件

adapter.setOnItemLongClickListener(this);

RecyclerView的Adapter的寫法:

在了解了RecyclerView的一些控制之后,緊接著來看看它的Adapter的寫法,RecyclerView的Adapter與ListView的Adapter還是有點區(qū)別的,RecyclerView.Adapter,需要實現(xiàn)3個方法:?

1、 onCreateViewHolder()?

這個方法主要生成為每個Item inflater出一個View,但是該方法返回的是一個ViewHolder。該方法把View直接封裝在ViewHolder中,然后我們面向的是ViewHolder這個實例,當(dāng)然這個ViewHolder需要我們自己去編寫。直接省去了當(dāng)初的convertView.setTag(holder)和convertView.getTag()這些繁瑣的步驟。

2、 onBindViewHolder()?

這個方法主要用于適配渲染數(shù)據(jù)到View中。方法提供給你了一viewHolder而不是原來的convertView。

3、 getItemCount()?

這個方法就類似于BaseAdapter的getCount方法了,即總共有多少個條目。

如下是recyleview的adapter基本代碼塊:

public class RVElementaryAdapter extends RecyclerView.Adapter {

? ? @Override

? ? public ElementaryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

? ? ? ? // 創(chuàng)建ViewHolder

? ? ? ? View itemView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent,false);

? ? ? ? ElementaryViewHolder elementaryViewHolder = new ElementaryViewHolder(itemView);

? ? ? ? return elementaryViewHolder;

? ? }

? ? @Override

? ? public void onBindViewHolder(@NonNull RVElementaryAdapter.ElementaryViewHolder holder, int position) {

? ? ? ? //綁定數(shù)據(jù)

? ? ? ? holder.tv.setText(data.get(position));

? ? }

? ? @Override

? ? public int getItemCount() {

? ? ? ? return data == null? 0 :data.size();

? ? }

}

實現(xiàn)的列表效果圖如下:


RecyclerView 控制布局樣式LayoutManager:

上面實現(xiàn)了類似ListView樣子的Demo,通過使用其默認(rèn)的LinearLayoutManager。RecyclerView.LayoutManage這是一個抽象類,系統(tǒng)提供了如下3個實現(xiàn)類:

1、LinearLayoutManager 現(xiàn)行管理器,支持橫向、縱向。

2、GridLayoutManager 網(wǎng)格布局管理器

3、StaggeredGridLayoutManager 瀑布就式布局管理器

下面實現(xiàn)以下各種視圖間的轉(zhuǎn)化效果:

代碼主要是通過recyleview.setLayoutManager(linearLayoutManager);設(shè)置不同的layoutManager來展示不同的視圖樣式,如下關(guān)鍵的代碼快:

/**

*切換布局效果

*/

private void changeView(){

? ? adapter.setViewType(currentViewType);

? ? recyleview.removeItemDecoration(dividerItemDecoration);

? ? recyleview.removeItemDecoration(dividerGridViewItemDecoration);

? ? switch (currentViewType){

? ? ? ? case Constnats.VIEW_TYPE_LISTVIEW:

? ? ? ? ? ? recyleview.addItemDecoration(dividerItemDecoration);

? ? ? ? ? ? recyleview.setLayoutManager(linearLayoutManager);

? ? ? ? ? ? break;

? ? ? ? case Constnats.VIEW_TYPE_GRIDVIEW:

? ? ? ? ? ? recyleview.addItemDecoration(dividerGridViewItemDecoration);

? ? ? ? ? ? recyleview.setLayoutManager(gridLayoutManager);

? ? ? ? ? ? break;

? ? ? ? case Constnats.VIEW_TYPE_HORIZONTALGRIDVEW:

? ? ? ? ? ? recyleview.addItemDecoration(dividerGridViewItemDecoration);

? ? ? ? ? ? recyleview.setLayoutManager(horizontalGridLayoutManager);

? ? ? ? ? ? break;

? ? ? ? case Constnats.VIEW_TYPE_STAGGEREDGRIDVIEW:

? ? ? ? ? ? recyleview.addItemDecoration(dividerGridViewItemDecoration);

? ? ? ? ? ? recyleview.setLayoutManager(staggeredGridLayoutManager);

? ? ? ? ? ? break;

? ? }

}

效果圖如下:


RecyclerView添加條目、刪除條目功能,并添加條目動畫:

注意的點:

1、RecyclerView.Adapter中添加刪除條目需要刷新視圖,平時我們刷新的方法調(diào)用notifyDataSetChanged();

--notifyDataSetChanged();列表全局刷新,給recyleview添加增刪條目的動畫時,調(diào)用這種刷新方法時無法生效的

2、RecyclerView.Adapter中為我們提供了很多自帶酷炫的增加刪除動畫,包括局部刷新的方法。

--notifyItemInserted(int position):?列表position位置添加一條數(shù)據(jù)時可以調(diào)用,伴有動畫效果

--notifyItemRemoved(int position)?:列表position位置移除一條數(shù)據(jù)時調(diào)用,伴有動畫效果

--notifyItemMoved(int fromPosition, int toPosition) 列表fromPosition位置的數(shù)據(jù)移到toPosition位置時調(diào)用,伴有動畫效果

--notifyItemRangeChanged(int positionStart, int itemCount) 列表從positionStart位置到itemCount數(shù)量的列表項進(jìn)行數(shù)據(jù)刷新

--notifyItemRangeInserted(int positionStart, int itemCount) 列表從positionStart位置到itemCount數(shù)量的列表項批量添加數(shù)據(jù)時調(diào)用,伴有動畫效果

·notifyItemRangeRemoved(int positionStart, int itemCount) 列表從positionStart位置到itemCount數(shù)量的列表項批量刪除數(shù)據(jù)時調(diào)用,伴有動畫效果

3、實際增刪操作過程中position不會自動增加,導(dǎo)致數(shù)據(jù)錯位的問題,所以,當(dāng)我們需要使用這些特效方法的時候,必須要重新刷新一遍數(shù)據(jù),糾正position。

4、設(shè)置Item增加、移除動畫recyleview.setItemAnimator(new DefaultItemAnimator());

在adapter中實現(xiàn)添加和刪除條目的功能,避免了數(shù)據(jù)錯位的問題,功能代碼如下:

/**

? ? * 添加條目

? ? * @param position

? ? */

? ? public void addData(int position){

? ? ? ? data.add(position,"additem"+position);

? ? ? ? heights.add(position,(int) Math.max(200,Math.random()*600));

? ? ? ? notifyItemInserted(position);

? ? ? ? // 加入如下代碼保證position的位置正確性

? ? ? ? if (position != data.size() - 1) {

? ? ? ? ? ? //列表從positionStart位置到itemCount數(shù)量的列表項進(jìn)行數(shù)據(jù)刷新

? ? ? ? ? ? notifyItemRangeChanged(position, data.size() - position);

? ? ? ? }

//? ? notifyDataSetChanged();

? ? }

? ? /**

? ? * 移除條目

? ? * @param position

? ? */

? ? public void removeData(int position){

? ? ? ? data.remove(position);

? ? ? ? heights.remove(position);

? ? ? ? notifyItemRemoved(position);

? ? ? ? // 加入如下代碼保證position的位置正確性

? ? ? ? if (position != data.size() - 1) {

? ? ? ? ? ? //列表從positionStart位置到itemCount數(shù)量的列表項進(jìn)行數(shù)據(jù)刷新

? ? ? ? ? ? notifyItemRangeChanged(position, data.size() - position);

? ? ? ? }

//? ? ? ? notifyDataSetChanged();

? ? }

RecyleView添加點擊事件和長按事件Click and LongClick:

上面說到RecyleView的缺點系統(tǒng)沒有提供ClickListener和LongClickListener,我們也可以自己去添加,需要多實現(xiàn)些代碼。?可以通過adapter中自己去提供回調(diào)自己去實現(xiàn)。adapter.setOnItemClickListener(this)設(shè)置條目的點擊事件;adapter.setOnItemLongClickListener(this)設(shè)置條目的長按事件,

注意:解決點擊position可能錯位的問題,通過構(gòu)造點擊事件把position傳給自己實現(xiàn)的點擊事件,以便于記錄點擊確定的position

關(guān)鍵代碼塊如下:

@Override

public void onBindViewHolder(@NonNull RVElementaryAdapter.ElementaryViewHolder holder, int position) {

? ? if(itemClickListener != null) {

? ? ? ? holder.tv.setOnClickListener(new MyClickListener(position));

? ? }

? ? if(itemLongClickListener != null) {

? ? ? ? holder.tv.setOnLongClickListener(new MyLongClickListener(position));

? ? }

}

private ItemClickListener itemClickListener;

private ItemClickListener itemLongClickListener;

/**

* 設(shè)置點擊事件

*/

public void setOnItemClickListener(ItemClickListener itemClickListener){

? ? this.itemClickListener = itemClickListener;

}

/**

* 設(shè)置長按點擊事件

*/

public void setOnItemLongClickListener(ItemClickListener itemLongClickListener){

? ? this.itemLongClickListener = itemLongClickListener;

}

public interface ItemClickListener{

? ? void onItemClick(int position);

? ? void onItemLongClick(int position);

}

/**

* 條目的點擊事件

*/

public class MyClickListener implements View.OnClickListener{

? ? int position;

? ? MyClickListener(int position){

? ? ? ? this.position = position;

? ? }

? ? @Override

? ? public void onClick(View v) {

? ? ? ? itemClickListener.onItemClick(position);

? ? }

}

/**

* 條目的長按事件

*/

public class MyLongClickListener implements View.OnLongClickListener{

? ? int position;

? ? MyLongClickListener(int position){

? ? ? ? this.position = position;

? ? }

? ? @Override

? ? public boolean onLongClick(View v) {

? ? ? ? itemLongClickListener.onItemLongClick(position);

? ? ? ? return true;

? ? }

}

到此基本介紹了RecylerView常見用法,包含了:

1、系統(tǒng)提供了幾種LayoutManager的使用;

2、如何使用ItemAnimator為RecylerView去添加Item移除、添加以及動畫效果。

3、介紹了如何添加ItemClickListener與ItemLongClickListener。

4、recyleview的adapter的用法

接下來會看一下RecyleView添加分割線的功能。

源碼demo鏈接:

https://github.com/heiyl/recyleview

csdn地址:https://blog.csdn.net/hylxnq/article/details/80265880

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

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

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