提问人:İBRAHİM 提问时间:10/26/2023 最后编辑:İBRAHİM 更新时间:10/26/2023 访问量:73
如何在 Flutter 中让小部件保持在屏幕边框内?
How do I make a widget stay within the screen borders in Flutter?
问:
我正在设计一个可调整大小和可重新定位的小部件。我可以将这个小部件保持在上部和左侧屏幕边界内,但我还没有设法将其保持在右侧和下部屏幕边界内。该小部件是使用 GestureDetector 创建的,并通过在 Stack 结构中占据一个位置来定义。我正在尝试在 onPanUpdate 方法中更新小部件位置,但右侧和底部屏幕边界不起作用。如何定义右框和底框边界,并确保小组件保持在这些边界内?top_and_left_frame_part |bottom_and_right_frame_part
这是我的代码块,第一个重要问题:
,onPanUpdate: (details) {
setState(() {
if (!isResizing) {
posx += details.delta.dx / 2;
posy += details.delta.dy / 2;
posx = posx.clamp(0, areaW);
posy = posy.clamp(0, areaH);
right = posx + width;
if (right > areaW) {
right = areaW;
}
}
在此块中,onPanUpdate 方法有效,但 'if' 语句和 'right = areaW' 不起作用。
import 'dart:math';
import 'package:flutter/material.dart';
class Note2Widget extends StatefulWidget {
const Note2Widget({super.key});
@override
State<Note2Widget> createState() => _Note2WidgetState();
}
class _Note2WidgetState extends State<Note2Widget> {
double width = 100;
double height = 100;
double posx = 0;
double posy = 0;
late double areaW;
late double areaH;
bool isResizing = false;
Offset startPosition = const Offset(0, 0);
double right = 0;
@override
Widget build(BuildContext context) {
areaW = MediaQuery.sizeOf(context).width;
areaH = MediaQuery.sizeOf(context).height;
return Positioned(
top: posy,
left: posx,
width: areaW,
height: areaH,
child: GestureDetector(
onPanStart: (details) {
if (details.localPosition.dx >= width - 15 &&
details.localPosition.dy >= height - 15) {
setState(() {
isResizing = true;
startPosition = details.localPosition;
});
}
},
onPanUpdate: (details) {
setState(() {
if (!isResizing) {
posx += details.delta.dx / 2;
posy += details.delta.dy / 2;
posx = posx.clamp(0, areaW);
posy = posy.clamp(0, areaH);
right = posx + width;
if (right > areaW) {
right = areaW;
}
}
if (isResizing) {
double dx = details.localPosition.dx - startPosition.dx;
double dy = details.localPosition.dy - startPosition.dy;
width += dx;
height += dy;
startPosition = details.localPosition;
}
if (height < 50) {
height = 50;
}
if (width < 50) {
width = 50;
}
});
},
onPanEnd: (details) {
setState(() {
isResizing = false;
});
},
child: Stack(children: [
Positioned(
top: posy,
left: posx,
width: width,
height: height,
child: Container(
decoration: BoxDecoration(
border: Border.all(width: 2, color: Colors.black)),
child: Center(
child: Padding(
padding: const EdgeInsets.all(8),
child: Container(
width: width - 10,
height: height - 10,
color: Colors.orangeAccent,
child: const TextField(
textAlign: TextAlign.center,
maxLines: null,
decoration: InputDecoration(
border: InputBorder.none,
),
style: TextStyle(
color: Colors.black,
fontSize: 20,
decoration: TextDecoration.none),
),
),
)),
))
]),
));
}
}
这是屏幕上的小部件按钮
class ExampleWidgetButton extends StatefulWidget {
const ExampleWidgetButton({super.key});
@override
State<ExampleWidgetButton> createState() => _ExampleWidgetButtonState();
}
class _ExampleWidgetButtonState extends State<ExampleWidgetButton> {
@override
Widget build(BuildContext context) {
return Positioned(
bottom: 30,
left: 60,
child: CircleAvatar(
backgroundColor: Colors.amberAccent,
radius: 35,
child: IconButton(
onPressed: () {
context
.read<PageDraggable>()
.addWidget(const Note2Widget());
},
color: Colors.black,
icon: const Icon(Icons.pix)),
));
}
}
这是项目的主页
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:provider/provider.dart';
import 'package:star_menu/star_menu.dart';
import 'widgets/interfaceButtons.dart';
double globalPosX = 0;
double globalPosY = 0;
double containerLeft = 0;
double containerTop = 0;
bool isResizing = false;
Offset startPosition = Offset.zero;
String tempText = "";
class PageDraggable extends StatefulWidget with ChangeNotifier {
PageDraggable({super.key});
static List<Widget> widgets = [];
void addWidget(Widget widget) {
PageDraggable.widgets.add(widget);
notifyListeners();
print("${widgets.toList()}");
}
void removeWidget(Widget widget) {
PageDraggable.widgets.remove(widget);
notifyListeners();
}
void allRemoveWidget() {
PageDraggable.widgets.clear();
notifyListeners();
}
@override
State<PageDraggable> createState() => _PageDraggableState();
}
class _PageDraggableState extends State<PageDraggable> with ChangeNotifier {
int count = 0;
Color pickerColor = const Color(0xff443a49);
Color currentColor = const Color(0xff443a49);
void changeColor(Color color) {
setState(() => pickerColor = color);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(children: <Widget>[
// AreaControlWidget(),
Consumer<PageDraggable>(
builder: (context, value, child) {
return Positioned(
top: 5,
left: 250,
child: Text("| x: $globalPosX \n| y: $globalPosY "));
},
),
Consumer<PageDraggable>(
builder: (context, value, child) {
return Stack(
children: [...PageDraggable.widgets],
);
},
),
///Delete Button
const DeleteWidget(),
///
Positioned(
bottom: 40,
left: 120,
child: ElevatedButton(
onPressed: () {
showDialog(
builder: (context) => AlertDialog(
title: const Text('Pick a Color'),
content: SingleChildScrollView(
child: MaterialPicker(
pickerColor: pickerColor,
onColorChanged: changeColor,
),
),
actions: <Widget>[
ElevatedButton(
child: const Text('Got it'),
onPressed: () {
setState(() => currentColor = pickerColor);
Navigator.of(context).pop();
},
),
],
),
context: context);
},
child: const Text("Click"))),
///
Positioned(
bottom: 60,
right: 30,
child: StarMenu(
params: const StarMenuParameters(
shape: MenuShape.circle,
circleShapeParams:
CircleShapeParams(startAngle: 90, endAngle: 180),
animationCurve: Curves.bounceInOut,
),
onStateChanged: (state) => print("state changed"),
onItemTapped: (index, controller) {
controller.closeMenu!();
print("Menu item $index tapped");
},
items: const [
///Create Widget Button
CreateWidget(),
///Create Text Widget Button
CreateTextWidget(),
///Resizeable Widget Button
ResizeableWidget(),
///StickyNote Widget Button
StickyNoteWidgetButton(),
///Example Widget Button
ExampleWidgetButton(),
],
child: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.looks_one),
),
),
)
]),
),
);
}
}
这是main.dart文件
import 'package:draggable_example/ui/pageDraggable.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => PageDraggable(),
),
],
child: MaterialApp(
home: PageDraggable(),
)));
所有必要的库都已安装并运行,并且 flutter 正在最新版本上运行。
-flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.13.9, on Microsoft Windows [Version 10.0.19045.3570], locale tr-TR)
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[X] Chrome - develop for the web (Cannot find Chrome executable at .\Google\Chrome\Application\chrome.exe)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.6.5)
[√] Android Studio (version 2022.3)
[√] VS Code, 64-bit edition (version 1.81.1)
[√] Connected device (3 available)
[√] Network resources
答: 暂无答案
评论