[Android]RecycleView的item用法

RecyclerView 是 Android 提供的一個強大的列表控件,用來顯示大量數據。

RecyclerView 的主要特點

1. 高性能的視圖復用機制

Recycle就是循環的意思,那么recycleview的特點也很鮮明了,它只會創建出在屏幕內和一定緩存的itemview,當view滑出屏幕時,不會銷毀重建,而是復用舊的view,可以極高的提高性能;

2. 高度可定制

可以添加分割線、動畫、拖拽、滑動刪除;

3. 支持多種布局

支持線性、網格、瀑布流等布局實現;

子項的點擊事件和長按點擊事件

總體思路:因為我們在適配器的viewholder中可以拿到每個子項的view的,此時可以設置監聽調用Onclick方法或者OnLongClick方法,然后通過接口回調的方式在RecycleView中設置回調的邏輯處理;

那么為什么要通過接口回調的方式呢?是因為適配器的任務就是綁定數據后顯示UI,它不應該決定點擊事件后的邏輯處理,所以在適配器中實現子項的監聽,但是真正的實現我們放到Activity或者Fragment中,這樣有利于解耦;

接下來看看具體的實現:

在適配器中:

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;
}
//實現接口,使得調用適配器中的Onclick的方法,然后再進行接口回調
public class cityviewholder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public cityviewholder(@NonNull View itemView) {super(itemView);itemView.setOnClickListener(this);
}@Overridepublic void onClick(View view) {if(onItemClickListener!= null){onItemClickListener.onItemClick(cityadapt.this,getAdapterPosition());}}@Overridepublic boolean onLongClick(View view) {return true;}
}

在實現類中

cityadapt1.setOnItemClickListener(new cityadapt.OnItemClickListener() {@Overridepublic void onItemClick(cityadapt cityadapt, int position) {viewPager2.setCurrentItem(position,true);}@Overridepublic void onItemLongClick(cityadapt cityadapt, int position) {}
});

在進行子項的刪除和拖動的學習之前,得先了解一個類:ItemTouchHelper

ItemTouchHelper

  • ItemTouchHelper 是 Android 官方提供的一個 RecyclerView 輔助類

  • 它通過 監聽手勢事件,幫助我們輕松實現:
    Item 拖動(上下或左右移動)
    Item 滑動(左滑/右滑刪除,或執行其他操作)

  • 不需要自己去寫復雜的手勢檢測邏輯。

我理解的本質也是接口回調,我們只定義接口的實現,然后作為構造方法的參數傳入ItemTouchHelper的實例中,最后與RecycleView綁定;

在這里我們定義回調后的實現,比如允許滑動的方向等等;

ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
}

然后通過ItemTouchHelper的實例傳入,使得后續做出自定義的邏輯判斷和反應等;

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);

最后通過attachToRecyclerView與recycleview綁定,binding.recyCity是recycleview的實例;

itemTouchHelper.attachToRecyclerView(binding.recyCity);

ItemTouchHelper.Callback中有必須實現的三個抽象方法:

  • getMovementFlags():用來指定支持的拖拽和滑動方向

  • onMove():拖拽時回調(交換兩個 item 的位置)

  • onSwiped():側滑時回調(比如刪除 item)

在本模塊中介紹一下`getMovementFlags()

//規定可以滑動的方向
@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);
}
  • 最后返回一個方法makeMovementFlags(ver,hor),參數有兩個,第一個是關于允許上下滑動或拖拽的,第二個是關于上下的;
int position = viewHolder.getAdapterPosition();
if(position == 0){return 0;
}

這里這么寫得到當前滑動或者拖動的位置,如果這個是recycleview中第一個的話,就返回0,意味著不允許滑動或者拖拽;

  • ItemTouchHelper.LEFTItemTouchHelper.LEFTItemTouchHelper 里定義的一個常量,代表滑動(swipe)時允許的方向之一;

剩余的其他:

ItemTouchHelper.UP // 向上拖動

ItemTouchHelper.DOWN // 向下拖動

ItemTouchHelper.LEFT // 向左滑動

ItemTouchHelper.RIGHT // 向右滑動

子項的刪除事件

ItemTouchHelper的基礎上,我們還需重寫一個方法:

//是否允許滑動移除@Overridepublic boolean isItemViewSwipeEnabled() {return true;}

然后在ItemTouchHelper中的onSwiped方法內規定邏輯;

           //規定左滑后的邏輯@Overridepublic 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);}}

里面有三個方法:

  • cityadapt1.getData().remove(i) : 把適配器中持有的數據源里對應的 item 移除;

  • cityadapt1.notifyItemRemoved(i):觸發刪除的動畫;

  • addtomainweather.deleteFragment(i):通過接口回調的方式,自定義實現刪除的邏輯;

當然我們也可以定義刪除的動畫

子項刪除事件的動畫效果

代碼如下:

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);}}
}

這個方法是 ItemTouchHelper.Callback 提供的 onChildDraw,用來在 拖動/滑動時繪制額外的 UI 效果(比如背景、按鈕、圖標;

先看看這個方法對應的參數:

@NonNull Canvas c, // 畫布

@NonNull RecyclerView recyclerView, // 當前的 RecyclerView

@NonNull RecyclerView.ViewHolder viewHolder, // 當前正在交互的 item

float dX, // X 方向的位移

float dY, // Y 方向的位移

int actionState, // 當前手勢狀態(滑動/拖動)

boolean isCurrentlyActive // 手指是否還在按住 item

代碼中的部分說明:

actionState == ItemTouchHelper.ACTION_STATE_SWIPE是如果手勢是滑動的話;

其他的滑動:

  • ItemTouchHelper.ACTION_STATE_IDLE → 沒有操作

  • ItemTouchHelper.ACTION_STATE_DRAG → 拖動中

View view = viewHolder.itemView;獲得當前的item;

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);``recyclerView.getContext().getResources(),得到文件資源管理器,得到對應的圖片等;
BitmapFactory.decodeResource(Resources res, int id)BitmapFactory是一個解碼工具類,這個方法會讀取資源文件,并轉成內存中的 Bitmap 對象

c.drawBitmap(icon,null,new Rect(left,top,right,bottom),null);四個參數分別代表:設置到畫布上的bitmap對象,源區域(null代表設置整張圖片),以及你要放置的位置,設置透明度等;

子項的拖動事件

重寫此方法:

//是否允許長按拖拽
@Override
public boolean isLongPressDragEnabled() {return true;
}

此處跟刪除的邏輯差不多,解釋放在注釋中,可自行觀看;

            @Overridepublic boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {//返回當前正在拖動的適配器中的數據索引int i = viewHolder.getAdapterPosition();//返回目標適配器中的數據索引int j = target.getAdapterPosition();//把適配器中持有的數據源里對應的 item 交換;Collections.swap(cityadapt1.getData(),i,j);//刷新item移動動畫cityadapt1.notifyItemMoved(i,j);addtomainweather.swapFragment(i,j);return true;}

這樣我們就可以實現子項的點擊事件,刪除,拖動啦;
–未完待續–

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98337.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98337.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98337.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI驅動的軟件測試:革命性的自動化、缺陷檢測與實驗優化

引言在當今快節奏的軟件開發生命周期&#xff08;SDLC&#xff09;中&#xff0c;傳統測試方法已逐漸無法滿足對速度、覆蓋面和準確性的極高要求。人工智能&#xff08;AI&#xff09;和機器學習&#xff08;ML&#xff09;技術的融入&#xff0c;正在從根本上重塑軟件測試的格…

繼續優化基于樹狀數組的cuda前綴和

在之前的博客《借助樹狀數組的思想實現cuda版前綴和》中&#xff0c;我們用三個kernel實現了基于樹狀數組的cuda版前綴和&#xff0c;但是在數據量較大時速度不如傳統的reduce-then-scan方法&#xff0c;主要原因在于跨block的reduce階段沒有充分利用所有的cuda核心。在本博客中…

Qt圖片資源導入

右鍵項目&#xff0c;點擊添加新文件 選擇Qt -> Qt Resource File 資源文件起名 如&#xff1a;res 生成res.qrc文件 在項目的同級目錄下創建文件夾res&#xff0c;并將準備好的資源粘貼進去 右鍵qrc文件&#xff0c;選中Open in Editor 添加前綴 前綴是各種類型圖片的分類&…

嵌入式第四十六天(51單片機(中斷,定時器))

一.獨立按鍵設置1.#include "key.h"void init_key(void) {P1 | (0x0F << 4); }int key_pressed(void) {static int ret 0;if((P1 & (1 << 4)) 0){ret 1;}else if((P1 & (1 << 5)) 0){ret 2;}else if((P1 & (1 << 6)) 0){r…

Visual Studio Code2024安裝包及安裝教程

一、軟件下載軟件名稱&#xff1a;Visual Studio Code 2024安裝環境&#xff1a;window10及以上系統下載鏈接&#xff1a;https://pan.quark.cn/s/d9831b28c69a解壓軟件Bandizip下載鏈接&#xff1a;https://pan.quark.cn/s/a54e79b5d553二、軟件安裝1、下載后&#xff0c;先解…

fps:游戲玩法

能幫到你的話&#xff0c;就給個贊吧 &#x1f618; 文章目錄游戲玩法倒計時僵尸潮游戲成功&失敗計時玩法&#xff1a;玩家在計時內存活&#xff0c;成功&#xff1b;反之失敗Game界面&#xff1a;由關卡調用計時系統計時完成&#xff1a;調用結果界面結果界面玩家死亡&…

如何建立針對 .NET Core web 程序的線程池的長期監控

如何建立針對 .NET Core web 程序的線程池的長期監控 建立針對 .NET Core Web 應用程序線程池的長期監控是一個系統性的工程&#xff0c;它涉及代碼集成、指標收集、存儲、可視化和告警。 核心思路 線程池監控不是孤立的&#xff0c;它必須與應用程序的整體性能指標&#xff08…

前端開發學習路徑

前端開發學習路徑前端開發基礎技能HTML、CSS和JavaScript是前端開發的三大核心技術。HTML用于構建網頁結構&#xff0c;CSS負責樣式設計&#xff0c;JavaScript實現交互功能。掌握這三項技術是學習前端開發的基礎。現代前端開發通常需要了解ES6語法&#xff0c;包括箭頭函數、解…

一款沒有任何限制的免費遠程手機控制手機的軟件簡介

這是一款沒有任何限制的免費遠程手機控制手機的軟件支持安卓和蘋果1.安裝1.1被控制端安裝airdroid1.2控制端air mirror2.登錄同一個賬號3.控制使用打開控制端軟件選擇要控制的機器直接點“遠程控制“連接上后就可以任意操作被控手機了

在word中使用lateX公式的方法

非常好的問題&#xff01;這是一個許多科研人員和學生都渴望實現的功能。但需要明確的是&#xff1a; **Microsoft Word 本身并不具備“自動”將 LaTeX 代碼實時轉換為渲染后公式的功能。** 它不像 Overleaf 或 VS Code 的 Markdown 插件那樣&#xff0c;輸入 $Emc^2$ 就立刻變…

23種設計模式——代理模式(Proxy Pattern)詳解

?作者簡介&#xff1a;大家好&#xff0c;我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式&#xff0c;持續分享Java技術內容。 &#x1f34e;個人主頁&#xff1a;Meteors.的博客 &#x1f49e;當前專欄&#xff1a;設計模式 ?特色專欄&#xff1a;知識分享 &#x…

webpack scope hositing 和tree shaking

Scope Hoisting&#xff08;作用域提升&#xff09; 和 Tree Shaking&#xff08;搖樹優化&#xff09; 是現代前端構建中至關重要的概念。它們是構建工具&#xff08;如 Webpack、Rollup、Vite&#xff09;用來優化最終打包產物的核心技術。 核心概念快速理解 Tree Shaking&am…

手寫React狀態hook

在日常開發中&#xff0c;我們經常用到 React 的狀態管理 Hook&#xff1a;useState 和 useReducer。 但你有沒有想過&#xff1a;這些 Hook 內部是怎么實現的&#xff1f;為什么調用 setState 之后組件會重新渲染&#xff1f; 今天我們就來從零手寫 useState 和 useReducer&am…

力扣hot100:相交鏈表與反轉鏈表詳細思路講解(160,206)

問題描述核心思路&#xff1a;雙指針交替遍歷算法思想&#xff1a; 使用兩個指針 pa 和 pb 分別從鏈表A和鏈表B的頭節點出發&#xff0c;同步向后遍歷。當任一指針走到鏈表末尾時&#xff0c;將其重定位到另一鏈表的頭節點繼續遍歷。若兩鏈表相交&#xff0c;pa 和 pb 最終會在…

跨平臺游戲引擎 Axmol-2.8.1 發布

所有使用 axmol-2.8.0 的開發者都應更新至此版本 Axmol 2.8.1 版本是一個以錯誤修復和功能改進為主的次要 LTS 長期支持版本&#xff0c;發布時間: 2025 年 9 月 5 日 &#x1f64f;感謝所有對 axmol 項目的貢獻者&#xff0c;包括財務贊助者&#xff1a;scorewarrior、peter…

通過PXE的方式實現Ubuntu 24.04 自動安裝

PXE自動化安裝Ubuntu 24.04的配置文件之前都是通過PXE來自動化安裝Redhat系列的&#xff0c;例如&#xff1a;Rocky9、Rocky10、CentOS7、銀河麒麟 Kylin-V10、Kylin-V11、OpenEuler 24.03等。現在安裝Ubuntu系列的跟紅帽的不太一樣&#xff0c;所以在這里介紹下。創建三個文件…

AOSP Framework開發的一些超方便的快捷命令

在系統源碼中發現的一些命令和快捷方式。我們在編譯源碼之前執行的source build/envsetup.sh,通過cat build/envsetup.sh發現如下命令 - lunch: lunch <product_name>-<build_variant>Selects <product_name> as the product to build, and <build_…

【Protues仿真】基于AT89C52單片機的數碼管驅動事例

目錄 0案例視頻效果展示 1 AT89C52單片機驅動單個數碼管 1.1 數碼管基礎知識 1.1.1外觀與引腳 1.1.2 共陰(CC) vs 共陽(CA) 1.1.3段碼表(以數字1為例) 1.1.4驅動方式A. 直連IO(最簡單,占用IO多)一個段一根線,共陰或共陽公共端固定接GND/VCC。適合單個數碼管、…

01-Redis 發展簡史與核心定位解析:從誕生到三大產品矩陣

目錄引言一、Redis 的起源與發展&#xff1a;從定制工具到開源生態二、Redis 的核心定位&#xff1a;不止是緩存的多面手三、Redis 三大產品矩陣&#xff1a;按需選擇的完整解決方案3.1 Redis Open Source&#xff08;社區版&#xff09;&#xff1a;入門與輕量場景首選3.2 Red…

記錄jilu~

centos1、安裝最小版Linux 安裝必要工具yum -install -y epel-releaseyum -install -y net-toolsyum -install -y vim2、修改hostname hostnamectl net-hostname newhostname3、網絡配置文件&#xff0c;網關 &#xff0c; 使用ip &#xff0c;dns。。/etc/sysconfig/network-s…