Compose (11/N) - 手势

news2024/10/5 23:30:52

一、点击

1.1 可点击 Modifier.clickable( )

允许应用检测对该元素的点击。

@Composable
fun ClickableSample() {
    val count = remember { mutableStateOf(0) }
    Text(
        text = count.value.toString(),
        modifier = Modifier.clickable { count.value += 1 }
    )
}

1.2 手势检测 Modifier.pointerInput( )

当需要更大灵活性时,提供点按手势检测器。

detectTapGestures(
    onDoubleTap: ((Offset) -> Unit)? = null,        //双击
    onLongPress: ((Offset) -> Unit)? = null,        //长按
    onPress: suspend PressGestureScope.(Offset) -> Unit = NoPressGesture, //短按(其它三个都会触发有一次)
    onTap: ((Offset) -> Unit)? = null        //单击
)

检测点击手势

detectDragGestures(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onDragCancel: () -> Unit = { },
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit        //dragAmount拖动距离
)

检测拖动手势:dragAmount.x 和 dragAmount.y 拿到各方向上的拖动距离。

Modifier.pointerInput(Unit) {
    detectTapGestures(
        ...
    )
}

二、滚动

2.1 滚动修饰符 Modifier.verticalScroll( )、Modifier.horizontalScroll( )

Modifier.verticalScroll 和 Modifier.horizontalScroll 可以让内容边界大于最大尺寸约束时滚动里面的元素。借助 ScrollState 还可以更改滚动位置或获取当前状态。

@Composable
fun ScrollBoxes() {
    val scrollState = rememberScrollState()
    LaunchedEffect(Unit) { scrollState.animateScrollTo(100) }
    Column(
        modifier = Modifier
            .background(Color.LightGray)
            .size(100.dp)
//            .verticalScroll(rememberScrollState())  //使用默认参数
            .verticalScroll(scrollState)    //一显示就会自动滚动100px
    ) {
        repeat(10) {
            Text("Item $it", modifier = Modifier.padding(2.dp))
        }
    }
}

2.2 可滚动修饰符 Modifier.scrollable( )

只检测手势不偏移内容。构造时需要提供一个 consumeScrollDelta( ) 函数,该函数在每个滚动步骤都会调用,以像素为单位,返回所消耗的距离。

@Composable
fun ScrollableSample() {
    var offset by remember { mutableStateOf(0f) }
    Box(
        Modifier
            .size(150.dp)
            .scrollable(
                orientation = Orientation.Vertical,
                state = rememberScrollableState { delta ->
                    //拿到每次滑动的偏移量delta
                    offset += delta
                    delta
                }
            )
            .background(Color.LightGray),
        contentAlignment = Alignment.Center
    ) {
        Text(offset.toString())
    }
}

2.3 嵌套滚动

2.3.1 自动嵌套滚动

简单的嵌套滚动无需额外操作,当子元素无法进一步滚动时手势会由父元素处理,手势会自动从子元素传播到父元素。

//父Box嵌套10个子Box,子Box滚动到边界会滚动父Box
@Composable
fun ScrollableSample() {
    //设置渐变色方便观察子Box滚动(蓝→黄1000级)
    val gradient = Brush.verticalGradient(0f to Color.Blue, 1000f to Color.Yellow)
    Box(
        modifier = Modifier
            .background(Color.LightGray)
            .verticalScroll(rememberScrollState())
            .padding(32.dp)
    ) {
        Column {
            repeat(10) {
                Box(
                    modifier = Modifier
                        .height(128.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    Text(
                        text = "Scroll here",
                        color = Color.Red,
                        modifier = Modifier
                            .border(12.dp, Color.DarkGray)
                            .background(brush = gradient)
                            .padding(24.dp)
                            .height(150.dp)
                    )
                }
            }
        }
    }
}

2.3.2 nestedScroll 修饰符

2.3.3 嵌套滚动互操作性(v1.2.0)

三、拖动

只检测手势不偏移内容(需要保存状态并在屏幕上表示,例如通过 offset 修饰符移动元素),以像素为单位。

3.1 线性拖动(一维)Modifier.draggable( )

//文字横向拖动
var offsetX by remember { mutableStateOf(0f) }
Text(
    modifier = Modifier
        .offset { IntOffset(offsetX.roundToInt(), 0) }
        .draggable(
            orientation = Orientation.Horizontal,
            state = rememberDraggableState { delta ->
                offsetX += delta
            }
        ),
    text = "Drag me!"
)

3.2 平面拖动(二维)Modifier.pointerInput( )

改为 pointerInput 修饰符使用手势检测。

//父Box中拖动蓝色子Box
@Composable
fun ScrollableSample() {
    Box(modifier = Modifier.fillMaxSize()) {
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }
        Box(
            Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .background(Color.Blue)
                .size(50.dp)
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        change.consume()
                        offsetX += dragAmount.x
                        offsetY += dragAmount.y
                    }
                }
        )
    }
}

四、滑动 Modifier.swipeable( )

只检测手势不偏移内容(需要保存状态并在屏幕上表示,例如通过 offset 修饰符移动元素)。具有惯性,释放后会朝着锚点呈现动画效果,常见用途是滑动关闭。

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SwipeableSample() {
    val squareSize = 48.dp    //子Box的大小
    val swipeableState = rememberSwipeableState(0)
    val sizePx = with(LocalDensity.current) { squareSize.toPx() }   //DP转PX
    //设置锚点(key是像素,value是索引)
    val anchors = mapOf(0f to 0, sizePx to 1)
    Box(
        modifier = Modifier
            .width(96.dp)
            .swipeable(
                state = swipeableState,
                anchors = anchors,
                //阈值(超过就会自己滑到底,达不到就会滑回来)
                thresholds = { _, _ -> FractionalThreshold(0.3f) },
                orientation = Orientation.Horizontal
            )
            .background(Color.LightGray)
    ) {
        Box(
            Modifier
                .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
                .size(squareSize)
                .background(Color.DarkGray)
        )
    }
}

五、多点触控 Modifier.transformable( )

只检测手势不转换元素。平移、缩放、旋转。

@Composable
fun TransformableSample() {
    var scale by remember { mutableStateOf(1f) }    //缩放
    var rotation by remember { mutableStateOf(0f) }    //旋转
    var offset by remember { mutableStateOf(Offset.Zero) }    //平移
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale *= zoomChange
        rotation += rotationChange
        offset += offsetChange
    }
    Box(
        Modifier
            .graphicsLayer(
                scaleX = scale,    //等比缩放
                scaleY = scale,    //等比缩放
                rotationZ = rotation,
                translationX = offset.x,
                translationY = offset.y
            )
            .transformable(state = state)
            .background(Color.Blue)
            .fillMaxSize()
    )
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【技术分享】接口自动化测试中,如何做断言验证?

在服务端自动化测试过程中,发起请求之后还需要对响应值进行验证。验证响应信息符合预期值之后,这一条接口自动化测试用例才算完整的通过。所以这一章节,将会讲解在接口自动化测试中,如何对服务端返回的响应内容做断言验证。 实战…

C语言函数大全-- i 开头的函数

C语言函数大全 本篇介绍C语言函数大全– i 开头的函数 1. imagesize 1.1 函数说明 函数声明函数功能unsigned imagesize(int left, int top, int right, int bottom);获取保存位图像所需的字节数 1.2 演示示例 #include <graphics.h> #include <stdlib.h> #in…

【Java数据结构】链表OJ提交小记

目录 1.删除链表中所有值为val的节点 2.反转单链表 3.返回链表的中间节点 4.返回链表倒数第k个节点 5.按次序合并链表 6.按值分割链表 7.判断链表是否为回文 1.删除链表中所有值为val的节点 1. 删除链表中所有值为val的节点https://leetcode.cn/problems/remove…

考研数据结构-绪论

绪论 文章目录绪论1. 什么是数据结构2. 基本概念数据结构的四类基本结构&#xff08;逻辑结构&#xff09;存储结构顺序存储和链式存储比较分析3. 算法概念特征优点&#xff08;也是要求&#xff09;算法效率的度量概念时间复杂度空间复杂度(了解)1. 什么是数据结构 数据结构是…

【Python】字符串 ⑦ ( input 字符串输入 | input 函数自带提示参数 | input 函数接收的变量类型 )

文章目录一、input 字符串输入二、代码示例三、input 函数自带提示参数四、input 函数接收的变量类型一、input 字符串输入 在命令行中 , 使用 printf 可以输出数据 , 将 变量 , 字面量 , 表达式 输出到命令行中 ; 在命令行中 , 使用 input 语句可以 在 命令行 中 , 从键盘获取…

2023年第五届传智杯前四题题解(后俩没写出来)

比赛链接&#xff1a;第五届“传智杯”全国大学生计算机大赛&#xff08;决赛B组&#xff09; - 比赛详情 - 洛谷 时效「月岩笠的诅咒」 题目背景 蓬莱之药&#xff0c;被诅咒的不死之药。 奉命将蓬莱之药投入富士山中销毁的月岩笠&#xff0c;最终打算把蓬莱之药改投入八岳销…

STM32Cube的debug和release切换

一&#xff0c; Debug / Release版本区别 来源&#xff1a;STM32CUBEIDE中 Debug 和 Release 的作用/区别/使用场景 - svchao - 博客园 (cnblogs.com) 二&#xff0c;Debug / Release使用。 1&#xff0c;在编译的时候可以选择Debug 还是 Release . 2,使用stm32CubeIDE调试或运…

【模型复现】resnet,使用net.add_module()的方法构建模型。小小的改进大大的影响,何大神思路很奇妙,基础很扎实

从经验来看&#xff0c;网络的深度对模型的性能至关重要&#xff0c;当增加网络层数后&#xff0c;网络可以进行更加复杂的特征模式的提取&#xff0c;所以当模型更深时理论上可以取得更好的结果。但是更深的网络其性能一定会更好吗&#xff1f;实验发现深度网络出现了退化问题…

Git的安装与基本使用

Git是一个分布式版本控制工具&#xff0c;可以快速高效地处理从小型到大型的各种项目。 1.Git的安装 官网下载地址 &#xff1a;https://git-scm.com/ 安装过程 选择 Git 安装位置&#xff0c;要求是非中文并且没有空格的目录&#xff0c;然后下一步。 Git 选项配置&#xf…

ChatGPT搭建语音智能助手

环境 python&#xff1a;3 ffmpeg:用于处理视频和语音 gradio:UI界面和读取语音 概述 我们的目的是做一个语音智能助手 下面我们开始 准备工作 下载Visual Studio Code Visual Studio Code 因为需要写python代码&#xff0c;用Visual Studio Code比较方便。 安装pytho…

( “树” 之 DFS) 101. 对称二叉树 ——【Leetcode每日一题】

101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 提示&#xff1a…

webgl-画任意多边形

注意&#xff1a; let canvas document.getElementById(webgl) canvas.width window.innerWidth canvas.height window.innerHeight let radio window.innerWidth/window.innerHeight; let ctx canvas.getContext(webgl) 由于屏幕长宽像素不一样&#xff0c;导致了长宽像素…

移远云服务QuecCloud正式发布,一站式为全球客户提供创新有效的解决方案

4月12日&#xff0c;在“万物智联共数未来”移远通信物联网生态大会上&#xff0c;移远通信宣布正式推出其物联网云服务——QuecCloud。QuecCloud具备智能硬件开发、物联网开放平台、行业解决方案三大能力&#xff0c;可为开发者和企业用户提供从硬件接入到软件应用的全流程解决…

Java 进阶(5) Java IO流

⼀、File类 概念&#xff1a;代表物理盘符中的⼀个⽂件或者⽂件夹。 常见方法&#xff1a; 方法名 描述 createNewFile() 创建⼀个新文件。 mkdir() 创建⼀个新⽬录。 delete() 删除⽂件或空⽬录。 exists() 判断File对象所对象所代表的对象是否存在。 getAbsolute…

4.2 方差

学习目标&#xff1a; 我认为学习方差需要以下几个步骤&#xff1a; 确定学习目标&#xff1a;在开始学习方差之前&#xff0c;需要明确学习的目标和意义&#xff0c;例如&#xff0c;理解方差的定义、掌握方差的计算方法、了解方差在实际问题中的应用等。 学习相关数学概念&…

宝塔Linux面板安装命令脚本大全(Centos/Ubuntu/Debian/Fedora/Deepin)

宝塔面板Linux服务器操作系统安装命令大全&#xff0c;包括Centos、Alibaba Cloud Linux、Ubuntu、TencentOS Server、Deepin、Debian和Fedora安装脚本&#xff0c;云服务器吧分享宝塔面板Linux服务器系统安装命令大全&#xff1a; 目录 宝塔面板Linux系统安装命令 Centos安…

【Vue】学习笔记-事件处理

事件的基本用法 使用v-on:xxx 或xxx 绑定事件&#xff0c;其中xxx是事件名事件的回调需要配置在methods对象中&#xff0c;最终会在vm上methods中配置的函数&#xff0c;不要用箭头函数&#xff0c;否则this就不是vm了methods中配置的函数&#xff0c;都是被vue所管理的函数。…

Pandas库:从入门到应用(三)——多表连接操作

一 、concat数据连接 1.1、concat()函数参数 pd.concat(objs, axis0, joinouter, ignore indexFalse, keysNone, levelsNone, namesNoneverify integrityFalse, sort False, copyTrue)objs&#xff1a;多个 DataFrame 或者 Series axis&#xff1a;0-行拼接 1-列拼接 join&am…

011:Mapbox GL两种方式隐藏logo和版权,个性化版权的声明

第011个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中用两种方式隐藏logo和版权,并个性化版权的声明 。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共91行)相关API参考:专栏目标示例效果 配置方式…

2023高性价比学生手机选购攻略,预算不多入手这3款超值

学生党在预算不多的情况&#xff0c;想要换颜值高的新手机&#xff0c;应该选什么样的手机才实惠&#xff1f; 手机已经成为生活中的必需品&#xff0c;市场上的手机品牌和型号多种多样&#xff0c;价格逐年攀升&#xff0c;对于预算有限的学生党来说&#xff0c;在保证性能和…