Compose Indication:點擊效果設置

Compose Indication:打造獨特點擊效果的秘密武器

在Compose開發中,大家可能都碰到過Indication,不少人第一次接觸它,是在想去掉Material默認的點擊水波紋效果的時候。要是在AI工具里搜“怎么去掉水波紋效果”,會得到這樣一段代碼:

Box(modifier = Modifier.size(200.dp).clickable(// 去除指示效果indication = null, interactionSource = null) {// 點擊事件處理邏輯},contentAlignment = Alignment.Center) {Text(text = "No Ripple Click", color = Color.Black)}

indication參數設成null,水波紋效果就沒了。這背后是怎么實現的呢?先看看Indication的注釋。Indication代表在一些交互發生時出現的視覺效果,像組件被按下時的漣漪效果,或者被聚焦時的高亮顯示。想自定義Indication,可以參考IndicationNodeFactory,它能實現更高效的指示效果。Indication一般通過LocalIndication在整個層級結構中提供,開發者可以自定義LocalIndication,改變組件(比如clickable)的默認指示效果。從這里能看出,Indication就是用來實現點擊、聚焦、拖動等組件效果的,有點像傳統View系統里的selector,但它的功能可要強大得多。

在傳統View系統里,selector能根據組件的不同狀態,指定不同的資源或顏色。不過,要實現交互效果,得知道組件的當前狀態。而Indication本身沒辦法獲取組件的交互狀態,這時就需要Interaction來幫忙了。

在很多情況下,開發普通組件時,我們不用關心Compose組件是怎么解讀用戶操作的。比如創建一個Button,通過Modifier.clickable就能判斷用戶有沒有點擊,設置好onClick代碼就行,不用管是點擊屏幕還是用鍵盤操作。但要是想自定義組件對用戶行為的響應方式,Interaction就派上用場了。

當用戶和界面組件交互時,系統會生成很多Interaction事件。比如用戶點擊按鈕,按鈕會生成PressInteraction.Press;在按鈕范圍內松開手指,會生成PressInteraction.Release,表示點擊完成;要是手指拖出按鈕范圍再松開,就會生成PressInteraction.Cancel,代表點擊取消。這些互動事件沒有預設的含義,也不解讀操作順序和優先級。

如果想跟蹤互動來擴展組件功能,比如讓按鈕按下時變色,最簡單的辦法就是觀察互動狀態。InteractionSource提供了很多方法來獲取各種互動狀態,像調用InteractionSource.collectIsPressedAsState(),就能知道按鈕有沒有被按下:

val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()Button(onClick = { /* do something */ },interactionSource = interactionSource
) {Text(if (isPressed) "Pressed!" else "Not pressed")
}

除了collectIsPressedAsState(),Compose還提供了collectIsFocusedAsState()collectIsDraggedAsState()collectIsHoveredAsState(),這些都是基于InteractionSource低級API的便捷方法,不過在某些場景下,直接用低級函數會更好。

了解完Interaction,再回到Indication。下面講講怎么用Indication創建和應用可復用的自定義效果。

IndicationNodeFactory是用來創建Modifier.Node實例的工廠,這些實例可以是有狀態或無狀態的,能從CompositionLocal檢索值,和其他Modifier.Node一樣。Modifier.indication是個修飾符,用于繪制Indication組件。Modifier.clickable這類高級互動修飾符能直接接受指示參數,既能發出Interaction,又能繪制視覺效果,所以簡單場景下,用Modifier.clickable就行,不一定非要Modifier.indication

來看個例子,把點擊縮放效果用Indication實現,步驟如下:

  1. 創建負責應用縮放效果的Modifier.Node。這個節點要觀察互動來源,和之前的示例類似,但它會直接啟動動畫,而不是把互動轉成狀態。節點需要實現DrawModifierNode,重寫ContentDrawScope#draw(),用Compose的圖形API渲染縮放效果,調用drawContent()繪制應用Indication的組件,注意一定要調用,不然組件不會顯示。
private class ScaleNode(private val interactionSource: InteractionSource) :Modifier.Node(), DrawModifierNode {var currentPressPosition: Offset = Offset.Zeroval animatedScalePercent = Animatable(1f)private suspend fun animateToPressed(pressPosition: Offset) {currentPressPosition = pressPositionanimatedScalePercent.animateTo(0.9f, spring())}private suspend fun animateToResting() {animatedScalePercent.animateTo(1f, spring())}override fun onAttach() {coroutineScope.launch {interactionSource.interactions.collectLatest { interaction ->when (interaction) {is PressInteraction.Press -> animateToPressed(interaction.pressPosition)is PressInteraction.Release -> animateToResting()is PressInteraction.Cancel -> animateToResting()}}}}override fun ContentDrawScope.draw() {scale(scale = animatedScalePercent.value,pivot = currentPressPosition) {this@draw.drawContent()}}
}
  1. 創建IndicationNodeFactory,它的任務就是創建新節點實例。如果沒有配置參數,工廠可以是個對象:
object ScaleIndication : IndicationNodeFactory {override fun create(interactionSource: InteractionSource): DelegatableNode {return ScaleNode(interactionSource)}override fun equals(other: Any?): Boolean = other === ScaleIndicationoverride fun hashCode() = 100
}
  1. Modifier.clickable內部用了Modifier.indication,要讓組件帶有ScaleIndication的點擊效果,直接把Indication作為clickable的參數就行:
Box(modifier = Modifier.size(100.dp).clickable(onClick = {},indication = ScaleIndication,interactionSource = null).background(Color.Blue),contentAlignment = Alignment.Center
) {Text("Hello!", color = Color.White)
}

這樣就實現了一個按住縮放的交互效果,這個Indication可以用在任何Composable函數上。Indication能定義一套交互效果并應用到各種組件上,如果項目里有標準的交互效果設計,用Indication準沒錯。歡迎大家一起交流,有問題可以在評論區留言或者私信我!

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

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

相關文章

Docker build 會在本地產生巨大的文件

Docker build 會在本地產生巨大的文件, 比如 用 這個命令列出本地鏡像 docker images 可見size都是很大的, 到docker目錄下,看到ext4.vhdx的大小 80多G 那只能用這個命令把不用的鏡像刪掉了: (rmi后面是鏡像id&a…

臺式機電腦組裝---電腦機箱與主板接線

臺式機電腦組裝—電腦機箱與主板接線 1、機箱連接主板的跳線一般主要有USB 2.0、USB 3.0、前置音頻接口(HD_AUDIO)以及POWER SW、RESET SW、POWER LED、HDD LED四個主板跳線,這些跳線分別的含義如下。 RESET SW:機箱重啟按鍵;注&#xff1a…

【虛幻引擎UE5】SpawnActor生成Character實例不執行AI Move To,未初始化AIController的原因和解決方法

虛幻引擎版本:5.5.4 問題描述 剛創建的Third Person項目里,定義一個BP_Enemy藍圖,拖拽到場景中產生的實例會追隨玩家,但SpawnActor產生的實例會固定不動。BP_Enemy藍圖具體設計如下: BP_Enemy的Event Graph ?? 又定義…

跨平臺RTSP高性能實時播放器實現思路

跨平臺RTSP高性能實時播放器實現思路 目標:局域網100ms以內超低延遲 一、引言 現有播放器(如VLC)在RTSP實時播放場景中面臨高延遲(通常數秒)和資源占用大的問題。本文提出一種跨平臺解決方案,通過網絡層…

HTTP 失敗重試(重發)方案

在 Qt 網絡開發中,使用 QNetworkAccessManager 進行 HTTP 請求時,可能會遇到網絡超時、服務器錯誤等情況。為了提高請求的可靠性,可以實現 HTTP 失敗重試(重發) 機制。下面介紹幾種常見的 失敗重發方案: 單…

大白話詳細解讀React框架的diffing算法

1. Diffing 算法是什么? Diffing 算法是 React 用來比較虛擬 DOM(Virtual DOM)樹的一種算法。它的作用是找出前后兩次渲染之間的差異(diff),然后只更新這些差異部分,而不是重新渲染整個頁面。 …

【Linux內核系列】:動靜態庫詳解

🔥 本文專欄:Linux 🌸作者主頁:努力努力再努力wz 💪 今日博客勵志語錄: 有些鳥兒是注定是關不住的,因為它們的每一片羽翼都沾滿了自由的光輝 ★★★ 本文前置知識: 編譯與鏈接的過程…

深度解讀DeepSeek部署使用安全(48頁PPT)(文末有下載方式)

深度解讀DeepSeek:部署、使用與安全 詳細資料請看本解讀文章的最后內容。 引言 DeepSeek作為一款先進的人工智能模型,其部署、使用與安全性是用戶最為關注的三大核心問題。本文將從本地化部署、使用方法與技巧、以及安全性三個方面,對Deep…

【詳細解決】pycharm 終端出現報錯:“Failed : 無法將“Failed”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。

昨天在終端一頓操作后突然打開pycharm時就開始報錯: 無法將“Failed”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果包括路徑,請確保路徑正確,然后再試一次。 所在位置 行:1 字符: 1 Failed to act…

【電路筆記】-D型觸發器

D型觸發器 文章目錄 D型觸發器1、概述2、主從D觸發器3、使用D型觸發器進行分頻4、D觸發器作為數據鎖存器5、透明數據鎖存器6、總結D型觸發器是一種改進的置位-復位觸發器,通過增加一個反相器來防止S和R輸入處于相同的邏輯電平。 1、概述 D型觸發器克服了基本SR NAND門雙穩態電…

智慧共享桿:城市智能化管理的 “多面手”

智慧共享桿:城市智能化管理的 “多面手” 在智慧城市建設的進程中,智慧共享桿憑借其多功能與集約化的特性,逐漸成為城市基礎設施建設領域的重點關注對象。它不僅革新了傳統路燈桿的固有模式,更為城市的高效管理與便捷服務開創了全…

【Tips】pip臨時換源

pip換源網站 用法: pip install xxx庫 -i https://pypi.tuna.tsinghua.edu.cn/simple https://pypi.tuna.tsinghua.edu.cn/simplehttps://mirrors.aliyun.com/pypi/simplehttps://pypi.douban.com/simplehttps://pypi.mirrors.ustc.edu.cn/simplehttps://mirrors.…

AcWing 838:堆排序 ← 數組模擬

【題目來源】 https://www.acwing.com/problem/content/840/ 【題目描述】 輸入一個長度為 n 的整數數列,從小到大輸出前 m 小的數。 【輸入格式】 第一行包含整數 n 和 m。 第二行包含 n 個整數,表示整數數列。 【輸出格式】 共一行,包含…

Microchip AN1477中關于LLC數字補償器的疑問

最近在學習Microchip的AN1477關于LLC的功率級傳遞函數推導及數字補償器設計,對其中的2P2Z數字補償器的系數有一些困惑。我在MATLAB中運行了源程序提供的VMC_LLC.m文件,發現有些地方和AN1477中的結果不一致。現在把相關有疑問的地方列舉出來,也…

【原創】使用ElasticSearch存儲向量實現大模型RAG

一、概述 檢索增強生成(Retrieval-Augmented Generation,RAG)已成為大型語言模型(LLM)應用的重要架構,通過結合外部知識庫來增強模型的回答能力,特別是在處理專業領域知識、最新信息或企業私有數…

分享下web3j 常見用法

轉賬 fun sendEthTransaction(privateKey: String,toAddress: String,amount: BigDecimal) {//chainIdval chainId:Long 1//url 可以從https://chainlist.org/里面獲取可用節點//eth轉賬,bnb同理,但需發送到bnb對應節點val url "https://xxx"…

《真·滕王閣序》

《滕工閣序》 西二旗故地,后廠新府。 星分百度網易,地接騰訊阿里。 襟PRD而帶OKR,控需求以引撕逼。 物華天寶,龍光射工卡芯片;人杰地靈,徐孺坐產品經理之榻。 工位霧列,碼農星馳。 臺積電…

云盤搭建筆記

報錯問題: No input file specified. 偽靜態 location / {if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last;break;} } location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; break; } } 設…

如何打造安全穩定的亞馬遜采購測評自養號下單系統?

在當今的電商領域,亞馬遜作為全球領先的在線購物平臺,其商品種類繁多,用戶基數龐大,成為了眾多商家和消費者的首選。而對于一些需要進行商品測評或市場調研的用戶來說,擁有一個穩定、安全的亞馬遜賬號體系顯得尤為重要…

c語言數據結構 單循環鏈表設計(完整代碼)

單鏈表的增刪查改代碼: 1.創建結構體 // 結構體類型的創建 struct node {int data; // 數據域struct node *next; // 指針域 };2.創建節點,節點的存儲在malloc申請的空間內,也就是堆空間。 // 創建節點 struct node *create_node…