如何检查两个小部件是否重叠?
How to check if two widgets are overlapping in flutter?
我想知道我们是否可以检查 flutter 中的两个小部件是否重叠。我实际上有两个使用 Stack 堆叠的 AnimatedContainer。我想检查两者的 children 是否重叠。我实际上是从头开始创建游戏并想检查碰撞。虽然 x 和 y 是一个选项,但它取决于两者的高度和宽度 objects 并且由于它们有不同,所以结果非常不准确。
如有任何帮助,我们将不胜感激。
您可以将 key
传递给小部件,然后使用 key.currentContext.findRenderObject()
获取渲染对象。
这是一个工作示例
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(home: MyPage());
}
class MyPage extends StatefulWidget {
@override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> with WidgetsBindingObserver {
final containerKey1 = GlobalKey();
final containerKey2 = GlobalKey();
Alignment box2Align = Alignment.topRight;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: Container(
key: containerKey1,
color: Colors.pink,
width: 100.0,
height: 100.0,
),
),
Align(
alignment: box2Align,
child: Transform.translate(
offset: const Offset(10.0, 10.0),
child: Container(
key: containerKey2,
color: Colors.purple.withOpacity(0.75),
width: 100.0,
height: 100.0,
),
),
),
// Buttons
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FlatButton(
color: Colors.yellow,
child: Text('Move containers'),
onPressed: () => setState(() {
if (box2Align == Alignment.topRight)
box2Align = Alignment.topLeft;
else
box2Align = Alignment.topRight;
}),
),
FlatButton(
color: Colors.yellow,
child: Text('Check if boxesCollide'),
onPressed: _onCheckTap,
),
],
),
],
),
),
);
}
void _onCheckTap() {
RenderBox box1 = containerKey1.currentContext.findRenderObject();
RenderBox box2 = containerKey2.currentContext.findRenderObject();
final size1 = box1.size;
final size2 = box2.size;
final position1 = box1.localToGlobal(Offset.zero);
final position2 = box2.localToGlobal(Offset.zero);
final collide = (position1.dx < position2.dx + size2.width &&
position1.dx + size1.width > position2.dx &&
position1.dy < position2.dy + size2.height &&
position1.dy + size1.height > position2.dy);
print('Containers collide: $collide');
}
}
我想知道我们是否可以检查 flutter 中的两个小部件是否重叠。我实际上有两个使用 Stack 堆叠的 AnimatedContainer。我想检查两者的 children 是否重叠。我实际上是从头开始创建游戏并想检查碰撞。虽然 x 和 y 是一个选项,但它取决于两者的高度和宽度 objects 并且由于它们有不同,所以结果非常不准确。
如有任何帮助,我们将不胜感激。
您可以将 key
传递给小部件,然后使用 key.currentContext.findRenderObject()
获取渲染对象。
这是一个工作示例
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(home: MyPage());
}
class MyPage extends StatefulWidget {
@override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> with WidgetsBindingObserver {
final containerKey1 = GlobalKey();
final containerKey2 = GlobalKey();
Alignment box2Align = Alignment.topRight;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: Container(
key: containerKey1,
color: Colors.pink,
width: 100.0,
height: 100.0,
),
),
Align(
alignment: box2Align,
child: Transform.translate(
offset: const Offset(10.0, 10.0),
child: Container(
key: containerKey2,
color: Colors.purple.withOpacity(0.75),
width: 100.0,
height: 100.0,
),
),
),
// Buttons
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FlatButton(
color: Colors.yellow,
child: Text('Move containers'),
onPressed: () => setState(() {
if (box2Align == Alignment.topRight)
box2Align = Alignment.topLeft;
else
box2Align = Alignment.topRight;
}),
),
FlatButton(
color: Colors.yellow,
child: Text('Check if boxesCollide'),
onPressed: _onCheckTap,
),
],
),
],
),
),
);
}
void _onCheckTap() {
RenderBox box1 = containerKey1.currentContext.findRenderObject();
RenderBox box2 = containerKey2.currentContext.findRenderObject();
final size1 = box1.size;
final size2 = box2.size;
final position1 = box1.localToGlobal(Offset.zero);
final position2 = box2.localToGlobal(Offset.zero);
final collide = (position1.dx < position2.dx + size2.width &&
position1.dx + size1.width > position2.dx &&
position1.dy < position2.dy + size2.height &&
position1.dy + size1.height > position2.dy);
print('Containers collide: $collide');
}
}