您好,GestureDetector、Pan 和 Scale 问题
Hello, issue with GestureDetector, Pan and Scale issue
我有一个代码可以让我用手指在图像上移动文本,还可以用双指在文本上缩放文本,但是有两个问题,在 google,希望有人能帮帮我,第一个问题是:
如果我取消对注释代码的注释,我会得到这个错误:
*构建主页时引发了以下断言(脏,状态:_HomePageState#8b5a9):
GestureDetector 参数不正确。
同时拥有平移手势识别器和缩放手势识别器是多余的; scale 是 pan 的超集。
只需使用比例手势识别器。
*
如果我只使用scale,delta(details.delta.dx)在scale中不可用,所以我得到一个错误。
另一个问题是:
当我在我的文本小部件中设置 textScaleFactor: _scaleFactor 时,文本消失了,我该如何解决这个问题?非常感谢大家。
import 'package:flutter/material.dart';
void main() {
runApp(const TextOverImage());
}
class TextOverImage extends StatelessWidget {
const TextOverImage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Size size = MediaQuery.of(context).size;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Text Over Image Image Example'),
),
body: Center(
child: Container(
height: 300,
width: 300,
child: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.blue,
image: const DecorationImage(
image: NetworkImage(
"https://thumbs.dreamstime.com/b/funny-face-baby-27701492.jpg"),
fit: BoxFit.fill)),
),
const HomePage()
],
),
),
),
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Offset offset = Offset.zero;
Offset offset2 = Offset.zero;
double scale = 0.0;
double _scaleFactor = 1.0;
double _baseScaleFactor = 1.0;
double _savedVal = 1.0;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
left: offset.dx,
top: offset.dy,
child: Row(
children: [
GestureDetector(
onPanUpdate: (details) {
setState(() {
offset = Offset(offset.dx + details.delta.dx,
offset.dy + details.delta.dy);
});
},
// behavior: HitTestBehavior.translucent,
//
// onScaleStart: (details) {
// _baseScaleFactor = _scaleFactor;
//
// },
//
// onScaleUpdate: (details) {
// setState(() {
// _scaleFactor = _baseScaleFactor * details.scale;
// });
// },
child: SizedBox(
width: 300,
height: 300,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text("You Think You Are Funny But You Are Not",
// here if I remove _scaleFactor the text is GONE
textScaleFactor: _scaleFactor,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red)),
),
),
),
),
],
),
),
Positioned(
left: offset2.dx,
top: offset2.dy,
child: Row(
children: [
GestureDetector(
onPanUpdate: (details) {
setState(() {
offset2 = Offset(offset2.dx + details.delta.dx,
offset2.dy + details.delta.dy);
});
},
child: const SizedBox(
width: 300,
height: 300,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text("xx xxxx x xx x x xxxxxx",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red)),
),
),
),
),
],
),
),
],
);
}
}
您可以使用 matrix_gesture_detector 包中的 MatrixGestureDetector 实现该功能。
直接实施如下:
class FloatingWidget extends StatefulWidget {
final Widget child;
const FloatingWidget({Key? key, required this.child}) : super(key: key);
@override
State<FloatingWidget> createState() => _FloatingWidgetState();
}
class _FloatingWidgetState extends State<FloatingWidget> {
Matrix4 _transform = Matrix4.identity();
@override
Widget build(BuildContext context) => Transform(
transform: _transform,
child: MatrixGestureDetector(
onMatrixUpdate: (matrix, translationDeltaMatrix, scaleDeltaMatrix, rotationDeltaMatrix) {
setState(() {
_transform = matrix;
});
},
child: widget.child,
),
);
}
在你的情况下,
import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
void main() {
runApp(const TextOverImage());
}
class TextOverImage extends StatelessWidget {
const TextOverImage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Size size = MediaQuery.of(context).size;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Text Over Image Image Example'),
),
body: Center(
child: SizedBox.fromSize(
size: const Size(300, 300),
child: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.blue,
image: const DecorationImage(
image: NetworkImage(
"https://thumbs.dreamstime.com/b/funny-face-baby-27701492.jpg"),
fit: BoxFit.fill)),
),
const HomePage()
],
),
),
),
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
FloatingWidget(
child: Row(
children: [
SizedBox.fromSize(
size: const Size(300, 300),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text("You Think You Are Funny But You Are Not",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red,
)
),
),
),
),
],
),
),
FloatingWidget(
child: Row(
children: [
SizedBox.fromSize(
size: const Size(300, 300),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text("xx xxxx x xx x x xxxxxx",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red,
),
),
),
),
),
],
),
),
],
);
}
}
嗯,缩放手势是平移手势的超集,你可以得到它的 offset delta 作为
scaleUpdateDetails.focalPointDelta
目前我不知道文本比例因子问题,但如果您使用 Transform 小部件,它就无关紧要了。
要了解有关变换小部件的更多信息,我建议 this article 来自 Medium。
我有一个代码可以让我用手指在图像上移动文本,还可以用双指在文本上缩放文本,但是有两个问题,在 google,希望有人能帮帮我,第一个问题是:
如果我取消对注释代码的注释,我会得到这个错误:
*构建主页时引发了以下断言(脏,状态:_HomePageState#8b5a9): GestureDetector 参数不正确。 同时拥有平移手势识别器和缩放手势识别器是多余的; scale 是 pan 的超集。 只需使用比例手势识别器。 *
如果我只使用scale,delta(details.delta.dx)在scale中不可用,所以我得到一个错误。
另一个问题是: 当我在我的文本小部件中设置 textScaleFactor: _scaleFactor 时,文本消失了,我该如何解决这个问题?非常感谢大家。
import 'package:flutter/material.dart';
void main() {
runApp(const TextOverImage());
}
class TextOverImage extends StatelessWidget {
const TextOverImage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Size size = MediaQuery.of(context).size;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Text Over Image Image Example'),
),
body: Center(
child: Container(
height: 300,
width: 300,
child: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.blue,
image: const DecorationImage(
image: NetworkImage(
"https://thumbs.dreamstime.com/b/funny-face-baby-27701492.jpg"),
fit: BoxFit.fill)),
),
const HomePage()
],
),
),
),
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Offset offset = Offset.zero;
Offset offset2 = Offset.zero;
double scale = 0.0;
double _scaleFactor = 1.0;
double _baseScaleFactor = 1.0;
double _savedVal = 1.0;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
left: offset.dx,
top: offset.dy,
child: Row(
children: [
GestureDetector(
onPanUpdate: (details) {
setState(() {
offset = Offset(offset.dx + details.delta.dx,
offset.dy + details.delta.dy);
});
},
// behavior: HitTestBehavior.translucent,
//
// onScaleStart: (details) {
// _baseScaleFactor = _scaleFactor;
//
// },
//
// onScaleUpdate: (details) {
// setState(() {
// _scaleFactor = _baseScaleFactor * details.scale;
// });
// },
child: SizedBox(
width: 300,
height: 300,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text("You Think You Are Funny But You Are Not",
// here if I remove _scaleFactor the text is GONE
textScaleFactor: _scaleFactor,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red)),
),
),
),
),
],
),
),
Positioned(
left: offset2.dx,
top: offset2.dy,
child: Row(
children: [
GestureDetector(
onPanUpdate: (details) {
setState(() {
offset2 = Offset(offset2.dx + details.delta.dx,
offset2.dy + details.delta.dy);
});
},
child: const SizedBox(
width: 300,
height: 300,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text("xx xxxx x xx x x xxxxxx",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red)),
),
),
),
),
],
),
),
],
);
}
}
您可以使用 matrix_gesture_detector 包中的 MatrixGestureDetector 实现该功能。
直接实施如下:
class FloatingWidget extends StatefulWidget {
final Widget child;
const FloatingWidget({Key? key, required this.child}) : super(key: key);
@override
State<FloatingWidget> createState() => _FloatingWidgetState();
}
class _FloatingWidgetState extends State<FloatingWidget> {
Matrix4 _transform = Matrix4.identity();
@override
Widget build(BuildContext context) => Transform(
transform: _transform,
child: MatrixGestureDetector(
onMatrixUpdate: (matrix, translationDeltaMatrix, scaleDeltaMatrix, rotationDeltaMatrix) {
setState(() {
_transform = matrix;
});
},
child: widget.child,
),
);
}
在你的情况下,
import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
void main() {
runApp(const TextOverImage());
}
class TextOverImage extends StatelessWidget {
const TextOverImage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Size size = MediaQuery.of(context).size;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Text Over Image Image Example'),
),
body: Center(
child: SizedBox.fromSize(
size: const Size(300, 300),
child: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.blue,
image: const DecorationImage(
image: NetworkImage(
"https://thumbs.dreamstime.com/b/funny-face-baby-27701492.jpg"),
fit: BoxFit.fill)),
),
const HomePage()
],
),
),
),
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
FloatingWidget(
child: Row(
children: [
SizedBox.fromSize(
size: const Size(300, 300),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text("You Think You Are Funny But You Are Not",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red,
)
),
),
),
),
],
),
),
FloatingWidget(
child: Row(
children: [
SizedBox.fromSize(
size: const Size(300, 300),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text("xx xxxx x xx x x xxxxxx",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.red,
),
),
),
),
),
],
),
),
],
);
}
}
嗯,缩放手势是平移手势的超集,你可以得到它的 offset delta 作为
scaleUpdateDetails.focalPointDelta
目前我不知道文本比例因子问题,但如果您使用 Transform 小部件,它就无关紧要了。
要了解有关变换小部件的更多信息,我建议 this article 来自 Medium。