Compose筆記(二十三)--多點觸控

? ? ? ? ?這一節主要了解一下Compose中多點觸控,在Jetpack Compose 中,多點觸控處理需要結合Modifier和手勢API來實現,一般通過組合 pointerInput、TransformableState 和 TransformModifier 來創建支持縮放、旋轉和平移的組件。

一、 API
1. PointerInput
含義:處理低級觸摸事件的主要API,支持多點觸控。
用法:通過pointerInput修飾符攔截和處理觸摸事件。
2. TransformableState
含義:管理變換狀態(縮放、旋轉、平移)的狀態容器。
用法:與transformable修飾符結合,監聽手勢并更新變換值。
3. TransformModifier
含義:應用變換效果(縮放、旋轉、平移)的修飾符。
用法:通過graphicsLayer或transformable應用變換。
二、關鍵類與接口
1. PointerInputScope
提供處理觸摸事件的作用域,包含:
detectDragGestures:處理單指拖拽。
detectTransformGestures:處理雙指縮放 / 旋轉。
detectTapGestures:處理點擊事件。
2. TransformScope
在detectTransformGestures中提供:
panChange:平移變化量。
zoomChange:縮放變化量。
rotationChange:旋轉變化量。
3. Transformation
包含三個變換參數:
scale:縮放因子。
rotation:旋轉角度。
offset:平移偏移量。

栗子:

1. 單指拖拽

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.consumeAllChanges
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.example.composenavigationdemo.R@Composable
fun TestImage() {var offset by remember { mutableStateOf(Offset.Zero) }Box(modifier = Modifier.size(200.dp).background(Color.LightGray).pointerInput(Unit) {detectDragGestures { change, dragAmount ->// 阻止事件冒泡change.consumeAllChanges()// 更新偏移量offset = offset + dragAmount}}.graphicsLayer {translationX = offset.xtranslationY = offset.y}) {Image(painter = painterResource(R.drawable.android),contentDescription = null,modifier = Modifier.fillMaxSize())}
}

2. 雙指縮放與旋轉

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.painterResource
import com.example.composenavigationdemo.R@Composable
fun TestImage() {var scale by remember { mutableStateOf(1f) }var rotation by remember { mutableStateOf(0f) }var offset by remember { mutableStateOf(Offset.Zero) }Box(modifier = Modifier.fillMaxSize().background(Color.LightGray).pointerInput(Unit) {detectTransformGestures { centroid, pan, zoom, rotationChange ->// 更新變換參數scale = (scale * zoom).coerceIn(0.5f, 5f)rotation += rotationChangeoffset = centroid}}) {Image(painter = painterResource(R.drawable.android),contentDescription = null,modifier = Modifier.align(Alignment.Center).graphicsLayer {scaleX = scalescaleY = scalerotationZ = rotationtranslationX = offset.x - size.width / 2translationY = offset.y - size.height / 2})}
}

3?組合多種手勢

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.painterResource
import com.example.composenavigationdemo.R
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch@Composable
fun TestImage() {var scale by remember { mutableStateOf(1f) }var rotation by remember { mutableStateOf(0f) }var offset by remember { mutableStateOf(Offset.Zero) }var isDragging by remember { mutableStateOf(false) }Box(modifier = Modifier.fillMaxSize().background(Color.LightGray).pointerInput(Unit) {coroutineScope {launch {detectDragGestures(onDragStart = { isDragging = true },onDragEnd = { isDragging = false }) { change, dragAmount ->offset += dragAmount}}launch {detectTransformGestures(panZoomLock = true) { _, pan, zoom, rotationChange ->scale *= zoomrotation += rotationChangeoffset += pan}}}}.graphicsLayer {scaleX = scalescaleY = scalerotationZ = rotationtranslationX = offset.xtranslationY = offset.y}) {Image(painter = painterResource(R.drawable.android),contentDescription = null,modifier = Modifier.align(Alignment.Center))}
}

注意:
1 事件消費:通過change.consumeAllChanges()阻止事件冒泡。
2 坐標系轉換:注意centroid(雙指中心點)和offset的坐標系差異。
3 狀態管理:使用remember保存變換狀態,確保配置變更后狀態恢復。

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

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

相關文章

【Java ee初階】HTTP(4)

構造HTTP請求 1)開發中,前后端交互。瀏覽器運行的網頁中,構造出HTTP請求 2)調試階段,通過構造HTTP請求測試服務器 樸素的方案: 通過tcp socket 的方式構造HTTP請求 按照HTTP請求格式,往TCP…

STM32 __main

STM32開發中__main與用戶main()函數的本質區別及工作機制 在STM32開發中,__main和用戶定義的main()函數是啟動過程中的兩個關鍵節點,分別承擔運行時初始化和用戶程序入口的職責。以下是它們的核心差異及協作機制: 一、定義與層級差異 ?__ma…

什么是PMBus

一、PMBus的定義與背景 PMBus(Power Management Bus,電源管理總線) 是一種基于SMBus(System Management Bus)的開放標準數字通信協議,專為電源設備的監控、配置和控制設計。由PMBus聯盟(現并入…

Python OOP核心技巧:如何正確選擇實例方法、類方法和靜態方法

Python方法類型全解析:實例方法、類方法與靜態方法的使用場景 一、三種方法的基本區別二、訪問能力對比表三、何時使用實例方法使用實例方法的核心場景:具體應用場景:1. 操作實例屬性2. 對象間交互3. 實現特定實例的行為 四、何時使用類方法使…

業務中臺-典型技術棧選型(微服務、容器編排、分布式數據庫、消息隊列、服務監控、低代碼等)

在企業數字化中臺建設中,業務中臺是核心支撐平臺,旨在通過技術手段將企業核心業務能力抽象、標準化和復用,以快速響應前端業務需求。其核心技術流涉及從業務抽象到服務化、治理和持續優化的全流程。以下是業務中臺建設中的核心技術體系及關鍵…

期望是什么:(無數次的均值,結合概率)21/6=3.5

https://seeing-theory.brown.edu/basic-probability/cn.html 期望是什么:(無數次的均值,結合概率)21/6=3.5 一、期望(數學概念) 在概率論和統計學中,**期望(Expectation)**是一個核心概念,用于描述隨機變量的長期平均取值,反映隨機變量取值的集中趨勢。 (一…

matlab官方免費下載安裝超詳細教程2025最新matlab安裝教程(MATLAB R2024b)

文章目錄 準備工作MATLAB R2024b 安裝包獲取詳細安裝步驟1. 文件準備2. 啟動安裝程序3. 配置安裝選項4. 選擇許可證文件5. 設置安裝位置6. 選擇組件7. 開始安裝8. 完成輔助設置 常見問題解決啟動失敗問題 結語 準備工作 本教程將幫助你快速掌握MATLAB R2024b的安裝技巧&#x…

第3章 自動化測試:從單元測試到硬件在環(HIL)

在前兩章中,我們已完成從環境搭建到流水線編譯的自動化配置。為了真正保障軟件質量、降低回歸風險,本章將聚焦測試自動化,涵蓋從最基礎的單元測試,到集成測試,再到硬件在環(Hardware-in-the-Loop, HIL)測試的全流程。通過腳本驅動、測試報告可視化和與 CI 平臺深度集成,…

信息收集+初步漏洞打點

目標:理解信息收集在滲透測試中的意義,熟悉常用工具用法,完成基本打點測試 一.理論學習: 模塊內容說明信息收集分類主動信息收集 vs 被動信息收集目標發現子域名、IP、端口、子站點、目錄、接口技術指紋識別Web框架(如…

uniapp+vue3開發項目之引入vuex狀態管理工具

前言: 我們在vue2的時候常用的狀態管理工具就是vuex,vue3開發以后,又多了一個pinia的選項,相對更輕便,但是vuex也用的非常多的,這里簡單說下在uni-app中vuex的使用。 實現步驟: 1、安裝&#x…

淺談“量子計算應用:從基礎原理到行業破局”

量子計算應用:從基礎原理到行業破局 引言:量子計算為何成為科技革命新引擎? 量子計算利用量子力學原理(疊加態、糾纏態、量子干涉)突破經典計算的極限,在特定領域可實現指數級加速。根據中研普華預測,2025年全球量子計算市場規模將突破80億美元,2035年可達8117億美元。…

UNiAPP地區選擇

<template> <view class"container"> <!-- 左側地區列表 --> <scroll-view class"left-list" scroll-y :scroll-into-view"currentLetterId" scroll-with-animation scroll"…

嵌入式硬件篇---CAN

文章目錄 前言1. CAN協議基礎1.1 物理層特性差分信號線終端電阻通信速率總線拓撲 1.2 幀類型1.3 數據幀格式 2. STM32F103RCT6的CAN硬件配置2.1 硬件連接2.2 CubeMX配置啟用CAN1模式波特率引腳分配過濾器配置&#xff08;可選&#xff09; 3. HAL庫代碼實現3.1 CAN初始化3.2 發…

DeepSeek-R1 Supervised finetuning and reinforcement learning (SFT + RL)

DeepSeek-R1Supervised finetuning and reinforcement learning (SFT RL) 好啊&#xff0c;我們今天的直播會非常透徹的跟大家系統性的分享一下整個agents AI就大模型智能體系統和應用程序。我們在做開發的時候&#xff0c;或者實際做企業級的產品落地的時候&#xff0c;你必…

機器學習 day04

文章目錄 前言一、線性回歸的基本概念二、損失函數三、最小二乘法 前言 通過今天的學習&#xff0c;我掌握了機器學習中的線性回歸的相關基本概念&#xff0c;包括損失函數的概念&#xff0c;最小二乘法的理論與算法實現。 一、線性回歸的基本概念 要理解什么是線性回歸&…

img.dims() <= 2 in function ‘cv::matchTemplate報錯

Mat src mat_ori;//imread(img_original);Mat src_template imread(img_template);cvtColor(src, src, COLOR_BGR2RGB);//不轉換&#xff0c;matchTemplate將報錯cvtColor(src_template, src_template,COLOR_BGR2RGB);//不轉換&#xff0c;matchTemplate將報錯 error: (-215…

NY321NY322美光閃存芯片NY323NY336

NY321NY322美光閃存芯片NY323NY336 在存儲技術飛速發展的今天&#xff0c;美光科技的閃存芯片憑借其創新架構與高性能表現&#xff0c;已成為工業自動化、智能終端等領域的核心組件。本文將圍繞技術解析、產品評測、行業趨勢、應用案例及市場動態五大維度&#xff0c;深入探討…

exit耗時高

背景&#xff1a;程序退出發現被強制退出&#xff0c;而不是正常的退出。正常退出是發送15信號&#xff0c;而異常退出是發送信號9&#xff0c;強制退出。退出機制是先發送信號15&#xff0c;然后6s內沒有退出完成&#xff0c;會發送信號9。通過查看退出流程&#xff0c;是將初…

docker compose up -d 是一個用于 通過 Docker Compose 在后臺啟動多容器應用 的命令

docker compose 表示調用 Docker Compose 工具&#xff0c;用于管理基于 YAML 文件定義的多容器應用。 up 核心指令&#xff0c;作用是根據 docker-compose.yml 文件中的配置&#xff0c;創建并啟動所有定義的服務、網絡、卷等資源。 如果容器未創建&#xff0c;會先構建鏡像&…

從輔助到協作:GitHub Copilot的進化之路

如果說現代程序員的標配工具除了VS Code、Stack Overflow之外&#xff0c;還有誰能入選&#xff0c;那一定是GitHub Copilot。從2021年首次亮相&#xff0c;到如今深度集成進開發者日常流程&#xff0c;這個“AI編程助手”已經不只是寫幾行自動補全代碼的小幫手了&#xff0c;而…