Jetpack Compose 双指拖拽实现详解

目录
  • Modifier.offset
  • graphicsLayer
  • Modifier.pointerInput
    • PointerInputScope.detectTransformGestures
  • 逻辑解释
    • 定义4个变量
    • 传入graphicsLayer里面
    • 监听手势
  • 完整代码
  • 效果图

Modifier.offset

Compose遇到一个浏览图片的功能,双指放大和缩小

Modifier的offset可以偏移内容。偏移量可以是正的,也可以是非正的。应用偏移只会更改内容的位置,而不会影响其大小测量。

offset由于用户交互而发生变化的偏移。它避免了在偏移量发生变化时进行重新编译,还添加了一个图形层,以防止在偏移量发生变化时对上下文进行不必要的重画。

graphicsLayer

使内容绘制到绘制层中的元素。绘图层可以与父层分开失效。当内容独立于上面的任何内容进行更新时,应使用graphicsLayer,以最小化无效内容。

graphicsLayer可以用于对内容应用各种效果

  • 缩放(scaleX、scaleY)
  • 旋转(rotationX、rotationY、rotationZ)
  • 不透明度(alpha)
  • 阴影(shadowElevation、shape)
  • 剪裁(clip、shape)
  • 以及使用Renderefect更改层的结果。

官方说,如果提供非零阴影高程,并且传递的形状为凹面,则阴影将不会在小于10的Android版本上绘制。

还有小于1.0f的alpha值会将其内容隐式剪裁到其边界。这是因为创建了一个中间合成层,以便在使用所需的alpha将内容绘制到目标之前,先将内容渲染到first中。该层的大小与配置该修改器的可组合对象的边界一致,这些边界之外的内容将被忽略。

Modifier.pointerInput

用于处理修改元素区域内的指针输入。 PointerInputScope或AwaitPointerEventScope上的扩展函数可以定义为执行更高级别的手势检测。指针输入处理块将被取消,并在指针输入用不同的键1重新组合时重新启动。

PointerInputScope.detectTransformGestures

可以用于旋转、平移和缩放的手势检测器。。当发生任何旋转、缩放或平移时,将调用OnGeture,以度为单位传递旋转角度,以像素为单位放大比例因子并以偏移量平移。

逻辑解释

定义4个变量

var angle by remember { mutableStateOf(0f) }//旋转的角度
var zoom by remember { mutableStateOf(1f) }//缩放
var offsetX by remember { mutableStateOf(0f) }//X轴偏移量
var offsetY by remember { mutableStateOf(0f) }//X轴偏移量

offset

Modifier
    .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }

传入graphicsLayer里面

.graphicsLayer(
    scaleX = zoom,
    scaleY = zoom,
    rotationZ = angle
)

监听手势

接着就是要监听手势,拿到手势的滑动返回的值让mutableStateOf告诉graphicsLayer刷新UI

.pointerInput(Unit) {
    detectTransformGestures(
        onGesture = { _, pan, gestureZoom, gestureRotate ->
            angle += gestureRotate
            zoom *= gestureZoom
            offsetX += pan.x
            offsetY += pan.y
        }
    )
}

图片的话加个Image就可以了,我在这里用背景色代替

 background(Color.Cyan)

完整代码

@Composable
private fun TransformGestures() {
    var angle by remember { mutableStateOf(0f) }
    var zoom by remember { mutableStateOf(1f) }
    var offsetX by remember { mutableStateOf(0f) }
    var offsetY by remember { mutableStateOf(0f) }
    Box(
        Modifier
            .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
            .graphicsLayer(
                scaleX = zoom,
                scaleY = zoom,
                rotationZ = angle
            )
            .background(Color.Cyan)
            .pointerInput(Unit) {
                detectTransformGestures(
                    onGesture = { _, pan, gestureZoom, gestureRotate ->
                        angle += gestureRotate
                        zoom *= gestureZoom
                        offsetX += pan.x
                        offsetY += pan.y
                    }
                )
            }
            .fillMaxSize()
    )
}

效果图

以上就是Jetpack Compose 双指拖拽实现详解的详细内容,更多关于Jetpack Compose 双指拖拽的资料请关注我们其它相关文章!

时间: 2022-11-16

Jetpack Compose DropdownMenu手指跟随点击显示

目录 引言 效果图 实现方法 1使用DropdownMenu的offset参数 2Modifier.offset 获取到点击的位置 Box创建用于监听点击事件修饰符 DropdownMenu外层的Box()设置偏移量 完整代码 使用方法 引言 DropdownMenu显示时默认会避开点击的view 通常默认显示在左下方 本篇文章教你实现跟随手指按下位置显示 效果图 实现方法 首先要获取到点击的位置之后计算偏移量 先分析两种offset参数 1使用DropdownMenu的offset参数 获取到

Jetpack Compose惯性衰减动画AnimateDecay详解

目录 什么是惯性衰减动画 惯性衰减动画 使用要点 block 监听 什么是惯性衰减动画 比如说我们玩微信的时候 手指一拉,微信的列表就会惯性滑动 ,这个滑动的速率当然是越来越慢的,最终停止, 这个其实就是惯性衰减动画的典型例子 那这个例子和animateTo 有啥区别呢? 一个速率变慢的动画 ,听起来似乎 我们用animateTo 设置一些参数也可以实现 其实这里最大的区别就是 animateTo 你是需要设置目标值的,也就是动画结束的那一刻 某个view属性的值 你必须明确指定 而所谓的惯性衰

Android Jetpack Compose开发实用小技巧

目录 前言 实用小技巧 如何移除View点击阴影 Text文本如何垂直居中 如何移除Button的点击阴影 Dialog宽度如何全屏 如何提升编码效率 前言 在Compose开发的过程中,我们会经常遇到一些看起来很简单却不知道如何处理的小问题,比如去除点击阴影.Dialog全屏等问题,本文记录了这些常见小问题的处理方式.如有更好方案欢迎大佬们交流探讨- 实用小技巧 如何移除View点击阴影 这里的View指的是除了Button系列的之外,如Button.TextButton等,也就是自身没有on

Jetpack Compose自定义动画与Animatable详解

目录 AnimationSpec 1.spring 2.tween 3.keyframes 4.repeatable 5.snap Animatable 本篇主要是自定义动画与Animatable. AnimationSpec 上一篇中,出现了多次animationSpec属性,它是用来自定义动画规范的.例如: fun Modifier.animateContentSize( animationSpec: FiniteAnimationSpec<IntSize> = spring(), fin

Jetpack Compose 分步指南教程详解

目录 前言 可组合函数 显示简单文本 将样式应用于文本 使用 TextField 进行输入 在 Android Studio 中预览 预览参数 Column Scrollable Column Lazy Column Box Button Card Clickable Image Alert Dialog Material AppBar Material BottomNavigation Material Checkbox Material ProgressBar Material Slider

Jetpack Compose重写TopAppBar实现标题多行折叠详解

目录 前言 MediumTopAppBar 阅读源码 核心 解决方法 重写TopAppBarLayout 完整代码 前言 想用composes实现类似掘金的文章详细页面的标题栏 上滑隐藏标题后标题栏显示标题 compose.material3下的TopAppBar不能嵌套滚动 MediumTopAppBar 便使用了MediumTopAppBar一开始用着没什么问题,但是标题字数多了,MediumTopAppBar就不支持了,最多就两行,进入源码一看就明白了 @ExperimentalMater

Java导出excel时合并同一列中相同内容的行思路详解

一.有时候导出Excel时需要按类别导出,一大类下好几个小类,小类下又有好几个小小类,就像下图: 要实现这个也不难, 思路如下:按照大类来循环,如上就是按照张江校区.徐汇校区.临港校区三个大类循环,然后再处理小类,因为本例小小类不涉及合并,所以只涉及处理小类,如果需要处理小小类,还需要在处理一下,具体实现原理同小类: 每次循环时记录下此次循环的房屋类型和上次循环的房屋类型,两者相同时,要合并的结束行++,否者,说明这个房屋类型已经循环完毕(前提是各类型都按顺序order by 了,保证相同类型相

对Python中DataFrame选择某列值为XX的行实例详解

如下所示: #-*-coding:utf8-*- import pandas as pd all_data=pd.read_csv("E:/协和问答系统/SenLiu/熵测试数据.csv") #获取某一列值为xx的行的候选列数据 print(all_data) feature_data=all_data.iloc[:,[0,-1]][all_data[all_data.T.index[0]]=='青年'] print(feature_data) 实验结果如下: "C:\Pro

对pandas通过索引提取dataframe的行方法详解

一.假设有这样一个原始dataframe 二.提取索引 (已经做了一些操作将Age为NaN的行提取出来并合并为一个dataframe,这里提取的是该dataframe的索引,道理和操作是相似的,提取的代码没有贴上去是为了不显得太繁杂让读者看着繁琐) >>> index = unknown_age_Mr.index.tolist() #记得转换为list格式 三.提取索引对应的原始dataframe的行 使用iloc函数将数据块提取出 >>> age_df.iloc[in

Django model重写save方法及update踩坑详解

一个非常实用的小方法 试想一下,Django中如果我们想对保存进数据库的数据做校验,有哪些实现的方法? 我们可以在view中去处理,每当view接收请求,就对提交的数据做校验,校验不通过直接返回错误,不写数据库,校验通过再调用create或update方法写入数据库 以上方式比较简单,容易理解,但随之又带来了麻烦,我们需在所有接收数据的地方都要去校验,那么有没有更加优雅的方式呢?如果你看过我之前的文章『Django使用Signals监测model字段变化发送通知』]就能想到可以通过signals

Javascript异步流程控制之串行执行详解

这篇文章主要讲一下如何串行执行一组异步任务,例如有下面几个任务,在这里我们用setTimeout模拟一个异步任务: let taskA = () => setTimeout(() => console.log('run task A'), 100); let taskB = () => setTimeout(() => console.log('run task B'), 50); let taskC = () => setTimeout(() => console.l

使用maven创建普通项目命令行程序详解

目录 引言 下载并配置Maven maven项目的构建 通过Maven配置mysql.myBtais.myBtais-plus maven命令工具 引言 maven是一个软件项目管理工具,其核心是基于项目对象模型(POM project object model),即就是通过对其生成的pom.xml进行配置来管理项目的构建,报告和文档的.其功能包括两部分,一是对项目依赖jar包的管理,二是提供项目的构建.打包.测试等命令 下载并配置Maven 参考地址:百度 maven项目的构建 打开idea,

如何更改Dialog的标题与按钮颜色详解

前言 本文主要给大家介绍了如何更改Dialog的标题与按钮颜色的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. android.support.v7.app.AlertDialog 在这个类中第一行就定义了如下变量: final AlertController mAlert; AlertDialog的功能的具体实现都在这个AlertController内部封装. 修改按钮颜色 1. AlertDialog.getButton public Button getButt

PHP 命令行参数详解及应用

复制代码 代码如下: # 不带参数的执行格式 php安装目录/bin/php scriptname.php # 带参数的执行格式 php安装目录/bin/php scriptname.php [参数1] [参数2] ..... 在scriptname.php通过$argv和$argc访问参数 # $argv(正式写法$_SERVER['argv'])数组保存着传递的全部参数,需要注意的是第一个参数$argv[0] / $_SERVER['argv'][0] 为执行脚本的名称如, scriptna

python的pytest框架之命令行参数详解(上)

前言 pytest是一款强大的python自动化测试工具,可以胜任各种类型或者级别的软件测试工作.pytest提供了丰富的功能,包括assert重写,第三方插件,以及其他测试工具无法比拟的fixture模型.pytest是一个软件测试框架,是一款命令行工具,可以自动找到测试用例执行,并且回报测试结果.有丰富的基础库,可以大幅度提高用户编写测试用例的效率.具备扩展性,用户可以自己编写插件,或者安装第三方提供的插件.可以很容易地与其他工具集成到一起使用.比如持续集成,web自动化测试等. 下面列举了

关于读取popen输出结果时未截断字符串导致的命令行注入详解

0x00 前言 这种命令行注入在pwn中出现的比较少,所以记录分享一下. 0x01 命令行注入介绍 熟悉web安全的话就知道,如果对特殊字符过滤不当,会引发sql注入或者xss等安全漏洞.其中,命令行注入较为严重,因为可以直接拿到漏洞程序当前权限的OSshell. 然而,命令行注入不仅在web中会出现,在C语言程序中,也会出现命令行注入的漏洞.比方说这道pwn题,就是调用system时,没有对输入数据进行\0截断以及对特殊字符处理不当而导致的. 命令行注入相对于其他二进制漏洞相比利用比较简单,比