我是靠谱客的博主 冷酷大侠,最近开发中收集的这篇文章主要介绍Flutter手势操作 ---全局坐标与局部坐标的获取Flutter手势操作 —全局坐标与局部坐标的获取,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Flutter手势操作 —全局坐标与局部坐标的获取

全局坐标与局部坐标

在GestureDetector中有两个重要属性值globalPositionlocalPosition,两者都是Offset对象
globalPosition就像它的命名表示当前手势触点在**全局坐标系位置对应组件顶点坐标的偏移量(dx,dy)
localPosition则就表示当前手势触点在
对应组件坐标系位置对应组件顶点坐标的偏移量(dx,dy)**。

例如如下代码中,为Container设置了GestureDetector手势监听,在update回调中获取updateDetail对象,在Text中显示globalPosition偏移量。从中获取到的globalPosition和localPosition中dx的值相同,dy却不同。也就是因为Scaffold中设置了AppBar,相对于body他的全局坐标系并非它自身。但若将Scaffold中的AppBar去除,让body撑满整个Scaffold,那么在手势监听中获取到的globalPosition和localPosition偏移量将相同。

需要注意的是对于globalPosition在安卓中还包含了手机状态栏的高度。

通过DragUpdateDetails获取全局坐标和局部坐标

DragUpdateDetails 相当网页前端的Evnet事件,可以获取当前触摸点的全局坐标和局部坐标。


onPanUpdate: (DragUpdateDetails detail) {
//获取当前触摸点的全局坐标
var globalPosition=detail.globalPosition;
//获取当前触摸点的局部坐标
var localPosition=detail.localPosition;
}

通过contexnt.findRenderObject()获取全局坐标和局部坐标

当前的页面结构(PainterPage):

  • Scafford

    • body

      • GestureDetector //手势Widget
        • onPanUpdate(detail)
onPanUpdate:(detail){
final RenderBox Box = context.findRenderObject();
// 获取的对象为当前页面对象,PainterPage
Offset localPosition = Box.globalToLocal(detail.globalPosition);
// 转换为局部坐标但实际是全局坐标
Offset globalPosition = Box.localToGlobal(detail.globalPosition);
// 获得的是全局坐标。
}

为甚么通过这样的方式,不能正确获取到局部坐标呢?

原因在于context.findRenderObject(),通过context,获取到的Box,实际上是PaintPage本身。所以,对于Box自身来说全局坐标局部坐标是一致的。

而实际上我们真正想要的是GestureDetector里的坐标系。由前面我们可以知道context.findRenderObject()只能获取context当前所在页面的页面 Widget

为了解决不能获取到GuesterDetector的坐标的问题,我们需要将GuesterDetector封装成一个StatefulWidget或者一个StatelessWidget,即GuesterDetectorWidget。再将GuesterDetectorWidget引入到PainterPage

更详细的说明可以参详字母索引快速定位

onPanUpdate:(detail){
final RenderBox Box = context.findRenderObject();
// 获取的对象为当前页面对象,PainterPage
Offset localPosition = Box.globalToLocal(detail.globalPosition);
// 转换为局部坐标
Offset globalPosition = Box.localToGlobal(detail.globalPosition);
// 获得的是全局坐标。
}
MaterialApp(
theme: AppTheme.themes[store.state.appThemeState.themeType],
home: Scaffold(
appBar: AppBar(),
body: GestureDetector(
onPanStart: (detail) {
showLog(detail.runtimeType, detail.localPosition,
detail.globalPosition);
},
onPanUpdate: (detail) {
showLog(detail.runtimeType, detail.localPosition,
detail.globalPosition);
setState(() {
offsetText = "globalPosition: ${Offset(detail.globalPosition.dx, detail.globalPosition.dy).toString()} n"
"localPosition: ${Offset(detail.localPosition.dx, detail.localPosition.dy).toString()}";
});
},
onPanEnd: (detail) {
setState(() {
offsetText = "end";
});
},
child: Container(
color: Colors.red,
width: double.infinity,
height: double.infinity,
child: Center(
child: Text(
offsetText,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
),
),
),
);

可以看到当Scaffold包含和未包含AppBar时,Container两个偏移量输出的差异。

#### 知识地图
  • Flutter的坐标体系是以Widget的左上角为原点,向左为正x轴,以下为正y轴;

  • 全局坐标是整个屏幕的左上角开始计算的

  • 局部坐标,是以当前GestureDetector包裹的Wiget的左上角为原点开始计算的

参考资料:

Flutter实战之手势操作篇

实现 View 的移动拖拽

flutter 白板工具

最后

以上就是冷酷大侠为你收集整理的Flutter手势操作 ---全局坐标与局部坐标的获取Flutter手势操作 —全局坐标与局部坐标的获取的全部内容,希望文章能够帮你解决Flutter手势操作 ---全局坐标与局部坐标的获取Flutter手势操作 —全局坐标与局部坐标的获取所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部