在 Flutter 中获取父级大小(区域边界)

问题描述 投票:0回答:1

我正在学习 Flutter,我想创建一个包含三个彩色方块的简单示例,我可以在窗口内用鼠标移动/拖动它们。然而,我希望方块的移动受到窗口面积的限制。我设法设置了位置下边界的限制(简单地说它不能小于零)但是我没有找到限制上边界的方法。我需要以某种方式获得大小(宽度和父部件的高度)。但是我没有找到任何方法来获取它。

import 'dart:math';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Moving Boxes',
      home: MyMainPage(),
    );
  }
}

class MyMainPage extends StatelessWidget {
  const MyMainPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
        body: Stack(
        children: <Widget>[
          MovableBox(color: Colors.red, left: 100, top: 100),
          MovableBox(color: Colors.yellow, left: 200, top: 50),
          MovableBox(color: Colors.blue, left: 0, top: 0)
          ]
    ));
  }
}

class MovableBox extends StatefulWidget {
  const MovableBox({super.key, required this.color, this.top = 0, this.left = 0});

  @override
  State<MovableBox> createState() => _MovableBoxState();

  final Color color;
  final double top;
  final double left;
}

class _MovableBoxState extends State<MovableBox> {
  double _left = 0;
  double _top = 0;

  @override
  void initState()
  {
    super.initState();
    _left = widget.left;
    _top = widget.top;
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      top:  max(_top, 0), // here I limit the lower boundary but I would also like to limit the upper one
      left: max(_left, 0),
      width: 200,
      height: 200,
      child: Container(
        color: widget.color,
        child: GestureDetector(
          onPanUpdate: (details) {
            setState(() {
              _left += details.delta.dx;
              _top += details.delta.dy;
            });
          },
        ),
      ),
    );
  }
}

我知道有一个名为

Draggable
的类应该做这样的事情。但出于学习目的,我想从较低级别的组件中实现它。

我猜我的设计可能是错误的。也许有几种方法可以实现这一目标。我想尽可能多地学习它们。

flutter
1个回答
0
投票

好的,经过更多的谷歌搜索,我发现了

MediaQuery.of(context)
所以解决方案是:

@override
Widget build(BuildContext context) {
  final area = MediaQuery.of(context).size;
  const width = 200.0;
  const height = 200.0;
  return Positioned(
        top: min(max(_top, 0), area.height - height),
        left: min(max(_left, 0), area.width - width),
        width: width,
        height: height,
        child: Container(
          color: widget.color,
          child: GestureDetector(
            onPanUpdate: (details) {
              setState(() {
                _left += details.delta.dx;
                _top += details.delta.dy;
              });
            },
            onPanEnd: (details) {
              setState(() {
                _top = min(max(_top, 0), area.height - height);
                _left = min(max(_left, 0), area.width - width);
              });
            },
          ),
        ),
      );
}

请注意,我还添加了

onPanEnd
处理程序以改进平移时的行为。

© www.soinside.com 2019 - 2024. All rights reserved.