【问题标题】:Hello, issue with GestureDetector, Pan and Scale issue您好,GestureDetector、Pan 和 Scale 问题
【发布时间】:2022-01-21 19:09:13
【问题描述】:

我有一个代码,允许我用手指在图像上移动文本,也可以用双指在文本上缩放文本,但是有两个问题,在谷歌上并没有太多,希望有人能提供帮助我,第一个问题是:

如果我取消注释注释的代码,我会收到此错误:

*在构建 HomePage(dirty, state: _HomePageState#8b5a9) 时抛出了以下断言: GestureDetector 参数不正确。 同时拥有平移手势识别器和缩放手势识别器是多余的; scale 是 pan 的超集。 只需使用比例手势识别器。 *

如果我只使用 scale,delta(details.delta.dx) 在 scale 中不可用,所以我得到一个错误。

另一个问题是: 当我在我的 TEXT 小部件中设置 textScaleFactor: _scaleFactor 时,文本消失了,我该如何解决这个问题?非常感谢各位。

import 'package:flutter/material.dart';

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

class TextOverImage extends StatelessWidget {
  const TextOverImage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Size size = MediaQuery.of(context).size;
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: const Text('Text Over Image Image Example'),
        ),
        body: Center(
          child: Container(
            height: 300,
            width: 300,
            child: Stack(
              children: <Widget>[
                Container(
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(5),
                      color: Colors.blue,
                      image: const DecorationImage(
                          image: NetworkImage(
                              "https://thumbs.dreamstime.com/b/funny-face-baby-27701492.jpg"),
                          fit: BoxFit.fill)),
                ),
                const HomePage()
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Offset offset = Offset.zero;
  Offset offset2 = Offset.zero;

  double scale = 0.0;
  double _scaleFactor = 1.0;
  double _baseScaleFactor = 1.0;
  double _savedVal = 1.0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned(
          left: offset.dx,
          top: offset.dy,
          child: Row(
            children: [
              GestureDetector(
                onPanUpdate: (details) {
                  setState(() {
                    offset = Offset(offset.dx + details.delta.dx,
                        offset.dy + details.delta.dy);
                  });
                },

                // behavior: HitTestBehavior.translucent,
                //
                // onScaleStart: (details) {
                //   _baseScaleFactor = _scaleFactor;
                //
                // },
                //
                // onScaleUpdate: (details) {
                //   setState(() {
                //     _scaleFactor = _baseScaleFactor * details.scale;
                //   });
                // },

                child:  SizedBox(
                  width: 300,
                  height: 300,
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Center(

                      child: Text("You Think You Are Funny But You Are Not",

                          // here if I remove _scaleFactor the text is GONE
                          textScaleFactor: _scaleFactor,
                          textAlign: TextAlign.center,
                          style: const TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 18.0,
                              color: Colors.red)),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
        Positioned(
          left: offset2.dx,
          top: offset2.dy,
          child: Row(
            children: [
              GestureDetector(
                onPanUpdate: (details) {
                  setState(() {
                    offset2 = Offset(offset2.dx + details.delta.dx,
                        offset2.dy + details.delta.dy);
                  });
                },
                child: const SizedBox(
                  width: 300,
                  height: 300,
                  child: Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Center(
                      child: Text("xx xxxx x xx   x x xxxxxx",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 18.0,
                              color: Colors.red)),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }
}

【问题讨论】:

    标签: android flutter flutter-layout flutter-animation


    【解决方案1】:

    您可以使用 matrix_gesture_detector 包中的 MatrixGestureDetector 来实现该功能。

    简单的实现如下:

    class FloatingWidget extends StatefulWidget  {
    
      final Widget child;
    
      const FloatingWidget({Key? key, required this.child}) : super(key: key);
    
      @override
      State<FloatingWidget> createState() => _FloatingWidgetState();
    }
    
    class _FloatingWidgetState extends State<FloatingWidget> {
    
      Matrix4 _transform = Matrix4.identity();
    
      @override
      Widget build(BuildContext context) => Transform(
        transform: _transform,
        child: MatrixGestureDetector(
          onMatrixUpdate: (matrix, translationDeltaMatrix, scaleDeltaMatrix, rotationDeltaMatrix)  {
            setState(() {
              _transform = matrix;
            });
          },
          child: widget.child,
        ),
      );
    }
    

    在你的情况下,

    import 'package:flutter/material.dart';
    import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
    
    void main() {
      runApp(const TextOverImage());
    }
    
    class TextOverImage extends StatelessWidget {
      const TextOverImage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        // Size size = MediaQuery.of(context).size;
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              centerTitle: true,
              title: const Text('Text Over Image Image Example'),
            ),
            body: Center(
              child: SizedBox.fromSize(
                size: const Size(300, 300),
                child: Stack(
                  children: <Widget>[
                    Container(
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(5),
                          color: Colors.blue,
                          image: const DecorationImage(
                              image: NetworkImage(
                                  "https://thumbs.dreamstime.com/b/funny-face-baby-27701492.jpg"),
                              fit: BoxFit.fill)),
                    ),
                    const HomePage()
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: [
            FloatingWidget(
              child: Row(
                children: [
                  SizedBox.fromSize(
                    size: const Size(300, 300),
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Center(
                        child: Text("You Think You Are Funny But You Are Not",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                            color: Colors.red,
                          )
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            FloatingWidget(
              child: Row(
                children: [
                  SizedBox.fromSize(
                    size: const Size(300, 300),
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Center(
                        child: Text("xx xxxx x xx   x x xxxxxx",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                            color: Colors.red,
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        );
      }
    }
    

    嗯,缩放手势是平移手势的超集,你可以得到它的offset delta as

    scaleUpdateDetails.focalPointDelta
    

    目前我不知道文本比例因子问题,但如果您使用Transform 小部件,这将无关紧要。

    要了解有关 Transform 小部件的更多信息,我建议来自 Medium 的this article

    【讨论】:

    • 非常感谢朋友,做得很好。
    • 我的荣幸和好运!
    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 2012-02-16
    • 2012-10-04
    • 1970-01-01
    • 2022-08-07
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多