在颤动中使用按钮手势旋转文本或图像

Posted

技术标签:

【中文标题】在颤动中使用按钮手势旋转文本或图像【英文标题】:Rotate text or image using button gesture in flutter 【发布时间】:2020-05-11 09:39:45 【问题描述】:

现在,当我做出 360 度手势时,图像仅从左到右平滑旋转。

要求的结果:

当我们做出 360 度手势时,应该从右向左旋转。 完成:当我们做出 360 度手势时,应该从右向左旋转。 一旦我们在某个点开始从左向右旋转,然后又从右向左旋转,它应该从做出手势的任一方向旋转。

  import 'dart:math';

  import 'package:flutter/material.dart';

  class RotateImage extends StatefulWidget 
    RotateImage(Key key) : super(key: key); // changed

    @override
    _RotateImageState createState() => _RotateImageState();
  

  class _RotateImageState extends State<RotateImage> 
    double finalAngle = 0.0;

    @override
    Widget build(BuildContext context) 
      return _defaultApp(context);
    

    _defaultApp(BuildContext context) 
      return Scaffold(
        appBar: AppBar(
          title: Text('Single finger Rotate text'), // changed
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              Container(
                color: Colors.red,
                padding: EdgeInsets.all(10),
                margin: EdgeInsets.only(top: 50),
                child: Transform.rotate(
                  angle: finalAngle,
                  origin: Offset(0, 0),
                  child: Container(
                    height: 100.0,
                    width: 100.0,
                    child: Image.network(
                      'https://picsum.photos/250?image=9',
                    ),
                  ),
                ),
              ),
              GestureDetector(
                onPanStart: (detials) ,
                onPanEnd: (detials) ,
                onPanUpdate: (details) 
                  setState(
                    () 
                      finalAngle += details.delta.distance * -pi / 180;
                    ,
                  );
                ,
                child: Container(
                  margin: EdgeInsets.only(top: 30),
                  color: Colors.black54,
                  width: 50,
                  height: 50,
                  child: Icon(
                    Icons.rotate_left,
                    color: Colors.white,
                  ),
                ),
              )
            ],
          ),
        ),
      );
    
  

【问题讨论】:

有什么问题? 它在旋转之字形。它旋转不顺畅。 您应该尝试在设备上查看动画的实际结果 已经在真机上试过了。您是否尝试运行代码? 您希望它在用手指画圈时旋转吗?因为那是非常不同的方法。我目前的答案是基于直线拖动。 【参考方案1】:

在这里,如果您在图标周围做手势(用一根手指),它会旋转。

源代码 1:(此处角度基于手指距GestureDetector 中心的位置

演示: DartPad,

import 'dart:math';

import 'package:flutter/material.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: RotateText(),
    );
  


class RotateText extends StatefulWidget 
  RotateText(Key key) : super(key: key); // changed

  @override
  _RotateTextState createState() => _RotateTextState();


class _RotateTextState extends State<RotateText> 
  double finalAngle = 0.0;

  @override
  Widget build(BuildContext context) 
    return _defaultApp(context);
  

  _defaultApp(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Single finger Rotate text'), // changed
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.red,
              padding: EdgeInsets.all(10),
              margin: EdgeInsets.only(top: 50),
              child: Transform.rotate(
                angle: finalAngle,
                child: Container(
                  height: 100.0,
                  width: 100.0,
                  child: Image.network(
                    'https://picsum.photos/250?image=9',
                  ),
                ),
              ),
            ),
            Container(
              width: 250,
              height: 250,
              color: Colors.grey,
              margin: EdgeInsets.all(30.0),
              child: LayoutBuilder(
                builder: (context, constraints) 
                  return GestureDetector(
                    behavior: HitTestBehavior.translucent,
                    onPanUpdate: (details) 
                      Offset centerOfGestureDetector = Offset(
                          constraints.maxWidth / 2, constraints.maxHeight / 2);
                      final touchPositionFromCenter =
                          details.localPosition - centerOfGestureDetector;
                      print(touchPositionFromCenter.direction * 180/pi);
                      setState(
                            () 
                          finalAngle = touchPositionFromCenter.direction;
                        ,
                      );
                    ,
                    child: Transform.rotate(
                      angle: finalAngle,
                      child: Icon(
                        Icons.arrow_forward,
                        color: Colors.white,
                        size: 200,
                      ),
                    ),
                  );
                ,
              ),
            )
          ],
        ),
      ),
    );
  

源代码 2:(这里的角度是持续更新每个onPanStart

演示: DartPad,

import 'package:flutter/material.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: RotateText(),
    );
  


class RotateText extends StatefulWidget 
  RotateText(Key key) : super(key: key); // changed

  @override
  _RotateTextState createState() => _RotateTextState();


class _RotateTextState extends State<RotateText> 
  double finalAngle = 0.0;
  double offsetAngle = 0.0;

  @override
  Widget build(BuildContext context) 
    return _defaultApp(context);
  

  _defaultApp(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Single finger Rotate text'), // changed
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.red,
              padding: EdgeInsets.all(10),
              margin: EdgeInsets.only(top: 50),
              child: Transform.rotate(
                angle: finalAngle,
                child: Container(
                  height: 100.0,
                  width: 100.0,
                  child: Image.network(
                    'https://picsum.photos/250?image=9',
                  ),
                ),
              ),
            ),
            Container(
              width: 250,
              height: 250,
              color: Colors.grey,
              margin: EdgeInsets.all(30.0),
              child: LayoutBuilder(
                builder: (context, constraints) 
                  return GestureDetector(
                    behavior: HitTestBehavior.translucent,
                    onPanStart: (details) 
                      Offset centerOfGestureDetector = Offset(
                          constraints.maxWidth / 2, constraints.maxHeight / 2);
                      final touchPositionFromCenter =
                          details.localPosition - centerOfGestureDetector;
                      offsetAngle =
                          touchPositionFromCenter.direction - finalAngle;
                    ,
                    onPanUpdate: (details) 
                      Offset centerOfGestureDetector = Offset(
                          constraints.maxWidth / 2, constraints.maxHeight / 2);
                      final touchPositionFromCenter =
                          details.localPosition - centerOfGestureDetector;
                      setState(() 
                        finalAngle =
                            touchPositionFromCenter.direction - offsetAngle;
                      );
                    ,
                    child: Transform.rotate(
                      angle: finalAngle,
                      child: Icon(
                        Icons.settings,
                        color: Colors.white,
                        size: 200.0,
                      ),
                    ),
                  );
                ,
              ),
            )
          ],
        ),
      ),
    );
  

【讨论】:

1.当点击以某个未知角度旋转按钮时,小部件会移动。为什么? 2.对手势过于敏感。那么,我们可以做得更流畅吗?请帮我解决这个问题。 第一个例子是根据你的手指从中心点的位置旋转。你可以试试第二个例子

以上是关于在颤动中使用按钮手势旋转文本或图像的主要内容,如果未能解决你的问题,请参考以下文章

Android-用单指手势旋转图像

ios中图像上的文本手势

颤动中文本上的纹理(图像)

调整平面按钮的大小并在颤动中提供水平滚动选项

在旋转视图上调整拖动手势

如何在颤动中绘制带有图像和文本的卡片列表