Android?RecycleView的item用法示例詳解
RecyclerView 是 Android 提供的一個(gè)強(qiáng)大的列表控件,用來(lái)顯示大量數(shù)據(jù)。
RecyclerView 的主要特點(diǎn)
1. 高性能的視圖復(fù)用機(jī)制
Recycle就是循環(huán)的意思,那么recycleview的特點(diǎn)也很鮮明了,它只會(huì)創(chuàng)建出在屏幕內(nèi)和一定緩存的itemview,當(dāng)view滑出屏幕時(shí),不會(huì)銷毀重建,而是復(fù)用舊的view,可以極高的提高性能;
2. 高度可定制
可以添加分割線、動(dòng)畫、拖拽、滑動(dòng)刪除;
3. 支持多種布局
支持線性、網(wǎng)格、瀑布流等布局實(shí)現(xiàn);
子項(xiàng)的點(diǎn)擊事件和長(zhǎng)按點(diǎn)擊事件
總體思路:因?yàn)槲覀冊(cè)谶m配器的viewholder中可以拿到每個(gè)子項(xiàng)的view的,此時(shí)可以設(shè)置監(jiān)聽(tīng)調(diào)用Onclick方法或者OnLongClick方法,然后通過(guò)接口回調(diào)的方式在RecycleView中設(shè)置回調(diào)的邏輯處理;
那么為什么要通過(guò)接口回調(diào)的方式呢?是因?yàn)檫m配器的任務(wù)就是綁定數(shù)據(jù)后顯示UI,它不應(yīng)該決定點(diǎn)擊事件后的邏輯處理,所以在適配器中實(shí)現(xiàn)子項(xiàng)的監(jiān)聽(tīng),但是真正的實(shí)現(xiàn)我們放到Activity或者Fragment中,這樣有利于解耦;
接下來(lái)看看具體的實(shí)現(xiàn):
在適配器中:
private OnItemClickListener onItemClickListener;
public interface OnItemClickListener{
void onItemClick(cityadapt cityadapt,int position);
void onItemLongClick(cityadapt cityadapt,int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
//實(shí)現(xiàn)接口,使得調(diào)用適配器中的Onclick的方法,然后再進(jìn)行接口回調(diào)
public class cityviewholder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public cityviewholder(@NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if(onItemClickListener!= null){
onItemClickListener.onItemClick(cityadapt.this,getAdapterPosition());
}
}
@Override
public boolean onLongClick(View view) {
return true;
}
}在實(shí)現(xiàn)類中
cityadapt1.setOnItemClickListener(new cityadapt.OnItemClickListener() {
@Override
public void onItemClick(cityadapt cityadapt, int position) {
viewPager2.setCurrentItem(position,true);
}
@Override
public void onItemLongClick(cityadapt cityadapt, int position) {
}
});在進(jìn)行子項(xiàng)的刪除和拖動(dòng)的學(xué)習(xí)之前,得先了解一個(gè)類:ItemTouchHelper
ItemTouchHelper
ItemTouchHelper是 Android 官方提供的一個(gè) RecyclerView 輔助類。- 它通過(guò) 監(jiān)聽(tīng)手勢(shì)事件,幫助我們輕松實(shí)現(xiàn):
- Item 拖動(dòng)(上下或左右移動(dòng))
- Item 滑動(dòng)(左滑/右滑刪除,或執(zhí)行其他操作)
- 不需要自己去寫復(fù)雜的手勢(shì)檢測(cè)邏輯。
我理解的本質(zhì)也是接口回調(diào),我們只定義接口的實(shí)現(xiàn),然后作為構(gòu)造方法的參數(shù)傳入ItemTouchHelper的實(shí)例中,最后與RecycleView綁定;
在這里我們定義回調(diào)后的實(shí)現(xiàn),比如允許滑動(dòng)的方向等等;
ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
}然后通過(guò)ItemTouchHelper的實(shí)例傳入,使得后續(xù)做出自定義的邏輯判斷和反應(yīng)等;
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
最后通過(guò)attachToRecyclerView與recycleview綁定,binding.recyCity是recycleview的實(shí)例;
itemTouchHelper.attachToRecyclerView(binding.recyCity);
在ItemTouchHelper.Callback中有必須實(shí)現(xiàn)的三個(gè)抽象方法:
getMovementFlags():用來(lái)指定支持的拖拽和滑動(dòng)方向onMove():拖拽時(shí)回調(diào)(交換兩個(gè) item 的位置)onSwiped():側(cè)滑時(shí)回調(diào)(比如刪除 item)
在本模塊中介紹一下`getMovementFlags()
//規(guī)定可以滑動(dòng)的方向
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int position = viewHolder.getAdapterPosition();
if(position == 0){
return 0;
}
int ver = 0;
int hor = ItemTouchHelper.LEFT;
return makeMovementFlags(ver,hor);
}- 最后返回一個(gè)方法
makeMovementFlags(ver,hor),參數(shù)有兩個(gè),第一個(gè)是關(guān)于允許上下滑動(dòng)或拖拽的,第二個(gè)是關(guān)于上下的;
int position = viewHolder.getAdapterPosition();
if(position == 0){
return 0;
}這里這么寫得到當(dāng)前滑動(dòng)或者拖動(dòng)的位置,如果這個(gè)是recycleview中第一個(gè)的話,就返回0,意味著不允許滑動(dòng)或者拖拽;
ItemTouchHelper.LEFT:ItemTouchHelper.LEFT是ItemTouchHelper里定義的一個(gè)常量,代表滑動(dòng)(swipe)時(shí)允許的方向之一;
剩余的其他:
ItemTouchHelper.UP // 向上拖動(dòng)
ItemTouchHelper.DOWN // 向下拖動(dòng)
ItemTouchHelper.LEFT // 向左滑動(dòng)
ItemTouchHelper.RIGHT // 向右滑動(dòng)
子項(xiàng)的刪除事件
在ItemTouchHelper的基礎(chǔ)上,我們還需重寫一個(gè)方法:
//是否允許滑動(dòng)移除
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}然后在ItemTouchHelper中的onSwiped方法內(nèi)規(guī)定邏輯;
//規(guī)定左滑后的邏輯
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int i = viewHolder.getAdapterPosition();
if(i != 0){
cityadapt1.getData().remove(i);
cityadapt1.notifyItemRemoved(i);
// MainActivity.deleteFragment(i);
addtomainweather.deleteFragment(i);
}
}里面有三個(gè)方法:
cityadapt1.getData().remove(i): 把適配器中持有的數(shù)據(jù)源里對(duì)應(yīng)的 item 移除;cityadapt1.notifyItemRemoved(i):觸發(fā)刪除的動(dòng)畫;addtomainweather.deleteFragment(i):通過(guò)接口回調(diào)的方式,自定義實(shí)現(xiàn)刪除的邏輯;
當(dāng)然我們也可以定義刪除的動(dòng)畫
子項(xiàng)刪除事件的動(dòng)畫效果
代碼如下:
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
View view = viewHolder.itemView;
Paint paint = new Paint();
paint.setColor(Color.WHITE);
if(dX < 0){
c.drawRect((float) view.getRight()+dX,(float) view.getTop(),(float) view.getRight(),(float) view.getBottom(),paint);
Bitmap icon = BitmapFactory.decodeResource(recyclerView.getContext().getResources(),R.drawable.deletecity);
int iconmargin =( view.getHeight() - icon.getHeight())/2;
int top = view.getTop()+iconmargin;
int bottom = top + icon.getHeight();
int left = view.getRight() - iconmargin - icon.getWidth();
int right = view.getRight() - iconmargin;
c.drawBitmap(icon,null,new Rect(left,top,right,bottom),null);
}
}
}這個(gè)方法是 ItemTouchHelper.Callback 提供的 onChildDraw,用來(lái)在 拖動(dòng)/滑動(dòng)時(shí)繪制額外的 UI 效果(比如背景、按鈕、圖標(biāo);
先看看這個(gè)方法對(duì)應(yīng)的參數(shù):
@NonNull Canvas c, // 畫布
@NonNull RecyclerView recyclerView, // 當(dāng)前的 RecyclerView
@NonNull RecyclerView.ViewHolder viewHolder, // 當(dāng)前正在交互的 item
float dX, // X 方向的位移
float dY, // Y 方向的位移
int actionState, // 當(dāng)前手勢(shì)狀態(tài)(滑動(dòng)/拖動(dòng))
boolean isCurrentlyActive // 手指是否還在按住 item
代碼中的部分說(shuō)明:
actionState == ItemTouchHelper.ACTION_STATE_SWIPE是如果手勢(shì)是滑動(dòng)的話;
其他的滑動(dòng):
ItemTouchHelper.ACTION_STATE_IDLE→ 沒(méi)有操作ItemTouchHelper.ACTION_STATE_DRAG→ 拖動(dòng)中
View view = viewHolder.itemView;獲得當(dāng)前的item;
c.drawRect((float) view.getRight()+dX,(float) view.getTop(),(float) view.getRight(),(float) view.getBottom(),paint); :里面有五個(gè)參數(shù),分別是規(guī)定滑動(dòng)后矩形的左邊界,矩形的上邊界,矩形的右邊界,矩形的下邊界,以及繪制的顏色/樣式;
Bitmap icon = BitmapFactory.decodeResource(recyclerView.getContext().getResources(),R.drawable.deletecity);``recyclerView.getContext().getResources(),得到文件資源管理器,得到對(duì)應(yīng)的圖片等;BitmapFactory.decodeResource(Resources res, int id),BitmapFactory是一個(gè)解碼工具類,這個(gè)方法會(huì)讀取資源文件,并轉(zhuǎn)成內(nèi)存中的 Bitmap 對(duì)象;
c.drawBitmap(icon,null,new Rect(left,top,right,bottom),null);四個(gè)參數(shù)分別代表:設(shè)置到畫布上的bitmap對(duì)象,源區(qū)域(null代表設(shè)置整張圖片),以及你要放置的位置,設(shè)置透明度等;
子項(xiàng)的拖動(dòng)事件
重寫此方法:
//是否允許長(zhǎng)按拖拽
@Override
public boolean isLongPressDragEnabled() {
return true;
}此處跟刪除的邏輯差不多,解釋放在注釋中,可自行觀看;
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
//返回當(dāng)前正在拖動(dòng)的適配器中的數(shù)據(jù)索引
int i = viewHolder.getAdapterPosition();
//返回目標(biāo)適配器中的數(shù)據(jù)索引
int j = target.getAdapterPosition();
//把適配器中持有的數(shù)據(jù)源里對(duì)應(yīng)的 item 交換;
Collections.swap(cityadapt1.getData(),i,j);
//刷新item移動(dòng)動(dòng)畫
cityadapt1.notifyItemMoved(i,j);
addtomainweather.swapFragment(i,j);
return true;
}這樣我們就可以實(shí)現(xiàn)子項(xiàng)的點(diǎn)擊事件,刪除,拖動(dòng)啦;
到此這篇關(guān)于Android RecycleView的item用法的文章就介紹到這了,更多相關(guān)Android RecycleView item用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android性能測(cè)試關(guān)注的指標(biāo)整理
在本篇文章里小編給各位整理的是關(guān)于Android性能測(cè)試關(guān)注的指標(biāo)整理內(nèi)容,有興趣的朋友們學(xué)習(xí)下。2019-10-10
Android Studio項(xiàng)目適配AndroidX(Android 9.0)的方法步驟
這篇文章主要介紹了Android Studio項(xiàng)目適配AndroidX(Android 9.0)的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
android實(shí)現(xiàn)驗(yàn)證碼按鈕
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)驗(yàn)證碼按鈕功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Android嵌套滾動(dòng)的傳統(tǒng)方法與思路
Android嵌套滾動(dòng)是在開(kāi)發(fā)中經(jīng)常遇到的一個(gè)需求,這篇文章主要介紹了Android嵌套滾動(dòng)的傳統(tǒng)方法與思路的相關(guān)資料,對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
Android 中在有序廣播中添加自定義權(quán)限的實(shí)例
這篇文章主要介紹了Android 中在有序廣播中添加自定義權(quán)限的實(shí)例的相關(guān)資料,這里對(duì)有序廣播的用法進(jìn)行了詳細(xì)介紹并附有簡(jiǎn)單實(shí)例,需要的朋友可以參考下2017-07-07
android使用ViewPager組件實(shí)現(xiàn)app引導(dǎo)查看頁(yè)面
這篇文章主要為大家詳細(xì)介紹了android使用ViewPager組件實(shí)現(xiàn)app引導(dǎo)查看頁(yè)面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Android程序開(kāi)發(fā)中單選按鈕(RadioGroup)的使用詳解
在android程序開(kāi)發(fā)中,無(wú)論是單選按鈕還是多選按鈕都非常的常見(jiàn),接下來(lái)通過(guò)本文給大家介紹Android程序開(kāi)發(fā)中單選按鈕(RadioGroup)的使用,需要的朋友參考下吧2016-03-03
flutter Container容器實(shí)現(xiàn)圓角邊框
這篇文章主要為大家詳細(xì)介紹了flutter Container容器實(shí)現(xiàn)圓角邊框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07

