我如何使用 Transform.transalte 确保我的容器不会超出我的屏幕范围
How can i make sure that my Container does not go outside my screen using Transform.transalte
我正在使用 Transform.translate
为 Container
制作动画,就像我的手指在屏幕上四处移动一样,我正在使用 Listener 小部件来增加我的 offset
。但我注意到,如果我继续将我的 container
移到屏幕外,它也会一直穿过屏幕外。
我也把它包装成 safe area
但它也一直在边界外。
如何防止这种行为?
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
late Offset offsetLocal= const Offset(0,0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Listener(
onPointerMove:(t){
offsetLocal+=t.delta;
setState(() {});
},
child: Center(
child: Transform.translate(
offset: offsetLocal,
child: Container(
color: Colors.red,
width: 200,
height: 200,
)
),
),
),
),
);
}
}
使用 Transform.translate
的更新位置将基于用户点击位置。
///Tap position needed to be centered
updatePositionOnTransform(BoxConstraints constraints, PointerMoveEvent t) {
debugPrint(t.position.toString());
//* using single condition force to one dimension
// if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
// t.position.dx > boxSize.width / 2 &&
// t.localPosition.dy > boxSize.height / 2 &&
// t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
// offsetLocal += t.delta;
// setState(() {});
// }
double dx = 0;
double dy = 0;
if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
t.position.dx > boxSize.width / 2) {
dx = t.delta.dx;
}
if (t.localPosition.dy > boxSize.height / 2 &&
t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
dy = t.delta.dy;
}
offsetLocal += Offset(dx, dy);
setState(() {});
}
使用 Stack 用户可以点击任何地方
updatePosition(BoxConstraints constraints, offset) {
double dx = offset.dx;
double dy = offset.dy;
//* -100 is coming from half container size
if (dx < constraints.maxWidth - boxSize.width / 2 &&
dx > boxSize.width / 2) {
offsetLocal = Offset(dx - (boxSize.width / 2), offsetLocal.dy);
}
if (dy > boxSize.height / 2 &&
dy < constraints.maxHeight - boxSize.height / 2) {
offsetLocal = Offset(offsetLocal.dx, dy - (boxSize.height / 2));
}
setState(() {});
}
你可以按照这个例子和select你喜欢的那个。
class _TestState extends State<Test> {
late Offset offsetLocal = const Offset(0, 0);
updatePosition(BoxConstraints constraints, offset) {
double dx = offset.dx;
double dy = offset.dy;
//* -100 is coming from half container size
if (dx < constraints.maxWidth - boxSize.width / 2 &&
dx > boxSize.width / 2) {
offsetLocal = Offset(dx - (boxSize.width / 2), offsetLocal.dy);
}
if (dy > boxSize.height / 2 &&
dy < constraints.maxHeight - boxSize.height / 2) {
offsetLocal = Offset(offsetLocal.dx, dy - (boxSize.height / 2));
}
setState(() {});
}
///Tap position needed to be centered
updatePositionOnTransform(BoxConstraints constraints, PointerMoveEvent t) {
debugPrint(t.position.toString());
//* using single condition force to one dimension
// if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
// t.position.dx > boxSize.width / 2 &&
// t.localPosition.dy > boxSize.height / 2 &&
// t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
// offsetLocal += t.delta;
// setState(() {});
// }
double dx = 0;
double dy = 0;
if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
t.position.dx > boxSize.width / 2) {
dx = t.delta.dx;
}
if (t.localPosition.dy > boxSize.height / 2 &&
t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
dy = t.delta.dy;
}
offsetLocal += Offset(dx, dy);
setState(() {});
}
final Size boxSize = const Size(200, 200);
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => SafeArea(
// child: usingTransform(constraints),
child: usingStack(constraints),
),
),
);
}
Listener usingTransform(constraints) {
return Listener(
onPointerMove: (t) {
updatePositionOnTransform(constraints, t);
},
child: Center(
child: Transform.translate(
offset: offsetLocal,
child: Container(
color: Colors.red,
width: 200,
height: 200,
)),
),
);
}
GestureDetector usingStack(BoxConstraints constraints) {
return GestureDetector(
onPanUpdate: (details) {
updatePosition(constraints, details.localPosition);
},
child: Stack(
children: [
Positioned(
// duration: const Duration(milliseconds: 100), //you can use `AnimatedPositioned`
left: offsetLocal.dx,
top: offsetLocal.dy,
child: Container(
color: Colors.red,
width: boxSize.width,
height: boxSize.height,
),
),
],
),
);
}
}
我正在使用 Transform.translate
为 Container
制作动画,就像我的手指在屏幕上四处移动一样,我正在使用 Listener 小部件来增加我的 offset
。但我注意到,如果我继续将我的 container
移到屏幕外,它也会一直穿过屏幕外。
我也把它包装成 safe area
但它也一直在边界外。
如何防止这种行为?
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
late Offset offsetLocal= const Offset(0,0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Listener(
onPointerMove:(t){
offsetLocal+=t.delta;
setState(() {});
},
child: Center(
child: Transform.translate(
offset: offsetLocal,
child: Container(
color: Colors.red,
width: 200,
height: 200,
)
),
),
),
),
);
}
}
使用 Transform.translate
的更新位置将基于用户点击位置。
///Tap position needed to be centered
updatePositionOnTransform(BoxConstraints constraints, PointerMoveEvent t) {
debugPrint(t.position.toString());
//* using single condition force to one dimension
// if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
// t.position.dx > boxSize.width / 2 &&
// t.localPosition.dy > boxSize.height / 2 &&
// t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
// offsetLocal += t.delta;
// setState(() {});
// }
double dx = 0;
double dy = 0;
if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
t.position.dx > boxSize.width / 2) {
dx = t.delta.dx;
}
if (t.localPosition.dy > boxSize.height / 2 &&
t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
dy = t.delta.dy;
}
offsetLocal += Offset(dx, dy);
setState(() {});
}
使用 Stack 用户可以点击任何地方
updatePosition(BoxConstraints constraints, offset) {
double dx = offset.dx;
double dy = offset.dy;
//* -100 is coming from half container size
if (dx < constraints.maxWidth - boxSize.width / 2 &&
dx > boxSize.width / 2) {
offsetLocal = Offset(dx - (boxSize.width / 2), offsetLocal.dy);
}
if (dy > boxSize.height / 2 &&
dy < constraints.maxHeight - boxSize.height / 2) {
offsetLocal = Offset(offsetLocal.dx, dy - (boxSize.height / 2));
}
setState(() {});
}
你可以按照这个例子和select你喜欢的那个。
class _TestState extends State<Test> {
late Offset offsetLocal = const Offset(0, 0);
updatePosition(BoxConstraints constraints, offset) {
double dx = offset.dx;
double dy = offset.dy;
//* -100 is coming from half container size
if (dx < constraints.maxWidth - boxSize.width / 2 &&
dx > boxSize.width / 2) {
offsetLocal = Offset(dx - (boxSize.width / 2), offsetLocal.dy);
}
if (dy > boxSize.height / 2 &&
dy < constraints.maxHeight - boxSize.height / 2) {
offsetLocal = Offset(offsetLocal.dx, dy - (boxSize.height / 2));
}
setState(() {});
}
///Tap position needed to be centered
updatePositionOnTransform(BoxConstraints constraints, PointerMoveEvent t) {
debugPrint(t.position.toString());
//* using single condition force to one dimension
// if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
// t.position.dx > boxSize.width / 2 &&
// t.localPosition.dy > boxSize.height / 2 &&
// t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
// offsetLocal += t.delta;
// setState(() {});
// }
double dx = 0;
double dy = 0;
if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
t.position.dx > boxSize.width / 2) {
dx = t.delta.dx;
}
if (t.localPosition.dy > boxSize.height / 2 &&
t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
dy = t.delta.dy;
}
offsetLocal += Offset(dx, dy);
setState(() {});
}
final Size boxSize = const Size(200, 200);
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => SafeArea(
// child: usingTransform(constraints),
child: usingStack(constraints),
),
),
);
}
Listener usingTransform(constraints) {
return Listener(
onPointerMove: (t) {
updatePositionOnTransform(constraints, t);
},
child: Center(
child: Transform.translate(
offset: offsetLocal,
child: Container(
color: Colors.red,
width: 200,
height: 200,
)),
),
);
}
GestureDetector usingStack(BoxConstraints constraints) {
return GestureDetector(
onPanUpdate: (details) {
updatePosition(constraints, details.localPosition);
},
child: Stack(
children: [
Positioned(
// duration: const Duration(milliseconds: 100), //you can use `AnimatedPositioned`
left: offsetLocal.dx,
top: offsetLocal.dy,
child: Container(
color: Colors.red,
width: boxSize.width,
height: boxSize.height,
),
),
],
),
);
}
}