Har*_*ish 8 flutter flutter-layout
我是 Flutter 的初学者,我试图弄清楚当用户在自定义形状和/或多个堆叠的自定义形状上移动手指时,如何检测触摸进入、移动和退出。像下面这样
理想情况下,我希望在用户进入/退出每个自定义形状的像素边界时获得触摸事件,但我想让它至少与形状的 MBR 一起工作。下面是我拥有的代码。我究竟做错了什么?当触摸在形状内开始时,它似乎所做的就是打印移动。我也尝试过 GestureDetector,结果相似。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.deepOrange,
),
home: MyHomePage(title: 'Flutter Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Stack(
children: <Widget>[
Listener(
onPointerSignal: (PointerEvent details) {
print("Signal yellow");
},
onPointerMove: (PointerEvent details) {
print("Move yellow");
},
onPointerHover: (PointerEvent details) {
print("Hover yellow");
},
onPointerEnter: (PointerEvent details) {
print("Enter yellow");
},
onPointerExit: (PointerEvent details) {
print("Exit yellow");
},
child: CustomPaint(
painter: ShapesPainter(),
child: Container(
height: 400,
width: 400,
),
),
),
Listener(
onPointerEnter: (PointerEvent details) {
print("Enter red");
},
onPointerExit: (PointerEvent details) {
print("Exit red");
},
child: CustomPaint(
painter: ShapesPainter1(),
child: Container(
height: 200,
width: 200,
),
),
),
],
),
],
),
),
);
}
}
class ShapesPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
// set the color property of the paint
paint.color = Colors.yellow;
// center of the canvas is (x,y) => (width/2, height/2)
var center = Offset(size.width / 2, size.height / 2);
// draw the circle on centre of canvas having radius 75.0
canvas.drawCircle(center, size.width / 2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
@override
bool hitTest(Offset position) {
// TODO: implement hitTest
return super.hitTest(position);
}
}
class ShapesPainter1 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
// set the color property of the paint
paint.color = Colors.red;
// center of the canvas is (x,y) => (width/2, height/2)
var center = Offset(size.width / 2, size.height / 2);
// draw the circle on centre of canvas having radius 75.0
canvas.drawCircle(center, size.width / 2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
@override
bool hitTest(Offset position) {
// TODO: implement hitTest
return super.hitTest(position);
}
}
Run Code Online (Sandbox Code Playgroud)
die*_*per 13
那是因为您使用了一个Listenerper CustomPainter,您应该Listener为所有Stack.
如果你想知道当前的触摸事件是否在每个 Circle 内,你可以使用GlobalKeys 来获取RenderBox每个 Circle 的s ,然后你有 renderBox 和PointerEvent,你可以很容易地检查 HitTest,检查代码:
class _MyHomePageState extends State<MyHomePage> {
GlobalKey _keyYellow = GlobalKey();
GlobalKey _keyRed = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text("title"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Listener(
onPointerMove: (PointerEvent details) {
final RenderBox box = _keyRed.currentContext.findRenderObject();
final RenderBox boxYellow =
_keyYellow.currentContext.findRenderObject();
final result = BoxHitTestResult();
Offset localRed = box.globalToLocal(details.position);
Offset localYellow = boxYellow.globalToLocal(details.position);
if (box.hitTest(result, position: localRed)) {
print("HIT...RED ");
} else if (boxYellow.hitTest(result, position: localYellow)) {
print("HIT...YELLOW ");
}
},
child: Stack(
children: <Widget>[
CustomPaint(
key: _keyYellow,
painter: ShapesPainter(),
child: Container(
height: 400,
width: 400,
),
),
CustomPaint(
key: _keyRed,
painter: ShapesPainter1(),
child: Container(
height: 200,
width: 200,
),
),
],
),
),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我还修改了hitTest您的CustomPainters方法以忽略圆圈外的触摸。
class ShapesPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
// set the color property of the paint
paint.color = Colors.yellow;
// center of the canvas is (x,y) => (width/2, height/2)
final center = Offset(size.width / 2, size.height / 2);
// draw the circle on centre of canvas having radius 75.0
canvas.drawCircle(center, size.width / 2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
@override
bool hitTest(Offset position) {
final Offset center = Offset(200, 200);
Path path = Path();
path.addRRect(RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: 400, height: 400),
Radius.circular(center.dx)));
path.close();
return path.contains(position);
}
}
class ShapesPainter1 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
// set the color property of the paint
paint.color = Colors.red;
// center of the canvas is (x,y) => (width/2, height/2)
var center = Offset(size.width / 2, size.height / 2);
// draw the circle on centre of canvas having radius 75.0
canvas.drawCircle(center, size.width / 2, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
@override
bool hitTest(Offset position) {
final Offset center = Offset(100, 100);
Path path = Path();
path.addRRect(RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: 200, height: 200),
Radius.circular(center.dx)));
path.close();
return path.contains(position);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4113 次 |
| 最近记录: |