概述
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