在Flutter中创建可调整大小的视图 [英] Create a resizable view in flutter

查看:77
本文介绍了在Flutter中创建可调整大小的视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为图像创建可调整大小的视图.代码如下:

I am creating a resizable view for an image. The code is as follows:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SafeArea(
          child: ImageManager(),
        ),
      ),
    );
  }
}

final ballRadius = 7.5;

class ImageManager extends StatefulWidget {
  @override
  _ImageManagerState createState() => _ImageManagerState();
}

class _ImageManagerState extends State<ImageManager> {
  double _x = 0;
  double _y = 0;

  double _height = 200;
  double _width = 300;

  double _aspectRatio = 200 / 300;

  @override
  Widget build(BuildContext context) {
    return Stack(
      overflow: Overflow.visible,
      children: <Widget>[
        Positioned(
          top: _y,
          left: _x,
          child: GestureDetector(
            onPanUpdate: (DragUpdateDetails details) {
              setState(() {
                _x += details.delta.dx;
                _y += details.delta.dy;
              });
            },
            child: Image.network(
              "https://via.placeholder.com/300x200",
              width: _width,
            ),
          ),
        ),

        // top left
        Positioned(
          top: _y - ballRadius,
          left: _x - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // top middle
        Positioned(
          top: _y - ballRadius,
          left: _x + _width / 2 - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // top right
        Positioned(
          top: _y - ballRadius,
          left: _x + _width - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // middle left
        Positioned(
          top: _y + _height / 2 - ballRadius,
          left: _x - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // middle right
        Positioned(
          top: _y + _height / 2 - ballRadius,
          left: _x + _width - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // bottom left
        Positioned(
          top: _y + _height - ballRadius,
          left: _x - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // bottom middle
        Positioned(
          top: _y + _height - ballRadius,
          left: _x + _width / 2 - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {},
            onDragEnd: () {},
          ),
        ),

        // bottom right
        Positioned(
          top: _y + _height - ballRadius,
          left: _x + _width - ballRadius,
          child: Ball(
            onDragStart: () {},
            onDrag: (double dx, double dy) {
              var mid = (dx + dy) / 2;
              var newWidth = _width + 2 * mid;
              var newHeight = newWidth * _aspectRatio;

              setState(() {
                _width = newWidth;
                _height = newHeight;
                _y = _y - dy;
                _x = _x - 2 * dx;
              });
            },
            onDragEnd: () {},
          ),
        ),
      ],
    );
  }
}

class Ball extends StatelessWidget {
  final Function onDragStart;
  final Function onDrag;
  final Function onDragEnd;

  const Ball({this.onDragStart, this.onDrag, this.onDragEnd});

  void _onDragStart(DragStartDetails details) {
    if (onDragStart != null) onDragStart();
  }

  void _onDragUpdate(DragUpdateDetails details) {
    if (onDrag != null) onDrag(details.delta.dx, details.delta.dy);
  }

  void _onDragEnd(DragEndDetails details) {
    if (onDragEnd != null) onDragEnd();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanStart: _onDragStart,
      onPanUpdate: _onDragUpdate,
      onPanEnd: _onDragEnd,
      child: Container(
        height: 2 * ballRadius,
        width: 2 * ballRadius,
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(ballRadius),
          border: Border.all(
            width: 3,
            color: Colors.white,
          ),
        ),
      ),
    );
  }
}

我的目标是统一调整尺寸,如下所示:

My goal is to uniformly resize like the following:

但是,目前看起来像这样.

However, currently, it looks like this.

您可以看到x和y坐标弄乱了.这里的目标是,如果您从右下角调整图像大小,则图像将保留在左上角.请帮忙.谢谢.

As you can see that the x and y coordinates are messed up. The goal here is if you resize the image from the bottom right corner then the image will stay at the top left corner. Please help with this. Thanks.

推荐答案

我将左上方的位置更改为这样

i change the the top left positioned like this

 // top left
    Positioned(
      top: _y - ballRadius,
      left: _x - ballRadius,
      child: Ball(
        onDragStart: () {},
        onDrag: (double dx, double dy) {
          var newWidth = _width - dx;
          var newHeight = newWidth * _aspectRatio;
          setState(() {
            _y = _y + (_height - newHeight);
            _x = _x + dx;
            _width = newWidth ;
            _height = newHeight;
          });
        },
        onDragEnd: () {},
      ),
    ),

和位于右下角(仅用于完成答案)

and bottom right positioned (just for completing Answer)

        Positioned(
      top: _y + _height - ballRadius,
      left: _x + _width - ballRadius,
      child: Ball(
        onDragStart: () {},
        onDrag: (double dx, double dy) {

          var newWidth = _width + dx;
          var newHeight = newWidth * _aspectRatio;

          setState(() {
            _width = newWidth ;
            _height = newHeight;
          });
        },
        onDragEnd: () {},
      ),
    ),

并将此参数添加到image.network

and adding this parameter to image.network

fit: BoxFit.fill,

完整代码在这里: https://dartpad.dev/44adae92cecbd2dddc00f264293e5c3a

这篇关于在Flutter中创建可调整大小的视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆