简体   繁体   English

Flutter 转换 animation 打破底部导航栏中浮动操作按钮的“按下” function。 需要解决方法

[英]Flutter transform animation breaks “on pressed” function of floating action button in bottom nav bar. Workaround needed

I'm currently trying to implement a radial menu appearing when the floating action button in the bottom navigation menu is clicked (image1).我目前正在尝试实现单击底部导航菜单中的浮动操作按钮时出现的径向菜单(image1)。 The animation and rendering works fine but after the animation, the on pressed button function is no even triggered, when the buttons get clicked. animation 和渲染工作正常,但在 animation 之后,按下按钮 function 甚至没有触发,当按钮被点击时。 I already read that this is due to the stack, wrapping the buttons and the animation.我已经读到这是由于堆栈、包装按钮和 animation。 The area of the transformed buttons is not defined a priori.转换按钮的区域不是先验定义的。 This causes gesture detection of the Buttons to stay behind the FAB.这会导致按钮的手势检测停留在 FAB 之后。 Wrapping the Stack with a fixed size container solves the problem, however, it totally breaks the layout.用固定大小的容器包装 Stack 解决了这个问题,但是,它完全破坏了布局。 Also, the clickable navigations icons in the background are not reachable as the container is laying above the navbar (see image2).此外,由于容器位于导航栏上方,因此无法访问背景中的可点击导航图标(参见图 2)。 Is there a known workaround to fix this problem?是否有解决此问题的已知解决方法? I am really looking forward to getting some professional help.我真的很期待得到一些专业的帮助。 :) :)

Image of not working buttons and desired layout不工作的按钮和所需布局的图像

Image of the broken UI after wrapping the stack with a container.使用容器包装堆栈后损坏的 UI 的图像。 But in this solution button pressed is working但是在这个解决方案中,按下的按钮正在工作

The code is attached here:代码附在这里:

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:vector_math/vector_math.dart' show radians;

class RadialFloatingActionButton extends StatefulWidget {
  @override
  _RadialFloatingActionButtonState createState() => _RadialFloatingActionButtonState();
 }

class _RadialFloatingActionButtonState extends State<RadialFloatingActionButton> with 
      SingleTickerProviderStateMixin {
      AnimationController controller;

      @override
      void initState() {
        super.initState();
        controller = AnimationController(
            duration: Duration(milliseconds: 1100), vsync: this);
      }

      @override
      Widget build(BuildContext context) {
        return RadialAnimation(controller: controller);
      }
    }

    class RadialAnimation extends StatelessWidget {
      RadialAnimation({Key key, this.controller})
          : scale = Tween<double>(
              begin: 1.5,
              end: 0.0,
            ).animate(
              CurvedAnimation(parent: controller, curve: Curves.elasticInOut),
             ),
            translation = Tween<double>(
              begin: 0.0,
              end: 90.0,
            ).animate(
              CurvedAnimation(parent: controller, curve: Curves.easeInOutCirc),
            ),
            super(key: key);

      final AnimationController controller;
      final Animation<double> scale;
      final Animation<double> translation;

      build(context) {
        return AnimatedBuilder(
             animation: controller,
             builder: (context, builder) {
              return Stack(alignment: Alignment.center, children: [
                _buildButton(200, color: Colors.black, emoji: "A"),
                _buildButton(245, color: Colors.black, emoji: "B"),
                _buildButton(295, color: Colors.black, emoji: "C"),
                _buildButtonMore(340, color: Colors.grey),
                Transform.scale(
                  scale: scale.value -
                      1.5, // subtract the beginning value to run the opposite animation
                  child: FloatingActionButton(
                      child: Icon(
                        Icons.close,
                      ),
                      onPressed: _close,
                      backgroundColor: Colors.black),
                 ),
                Transform.scale(
                  scale: scale.value,
                  child: FloatingActionButton(
                      child: Icon(
                        Icons.people,
                        color: Colors.white,
                      ),
                      onPressed: _open,
                      backgroundColor: Colors.black),
                 )
              ]);
            });
      }

      _buildButtonMore(double angle, {Color color}) {
        final double rad = radians(angle);
        return Transform(
            transform: Matrix4.identity()
              ..translate(
                  (translation.value) * cos(rad), (translation.value) * sin(rad)),
            child: FloatingActionButton(
                child: Icon(Icons.more_horiz),
                backgroundColor: color,
                onPressed: _close,
                elevation: 0));
      }

      _buildButton(double angle, {Color color, String emoji}) {
        final double rad = radians(angle);
        return Transform(
            transform: Matrix4.identity()
              ..translate(
                  (translation.value) * cos(rad), (translation.value) * sin(rad)),
            child: FloatingActionButton(
                child: Center(
                  child: new Text(
                    emoji,
                    style: TextStyle(fontSize: 30),
                    textAlign: TextAlign.center,
                  ),
                 ),
                backgroundColor: color,
                onPressed: _close,
                elevation: 0));
      }

      _open() {
        controller.forward();
      }

      _close() {
        controller.reverse();
      }
    }

I am not able to test right now, but wrapping in a container seems like the proper workaround, as Transforms seems to not apply to hit test behaviors in unbounding boxes (thats why Container makes it work).我现在无法测试,但包装在容器中似乎是正确的解决方法,因为转换似乎不适用于无边界框中的命中测试行为(这就是 Container 使其工作的原因)。 Maybe there's a way (some sort of widget or property) that allows hitTestBehavior like GestureDetector where you can set it to “opaque areas” instead the entire bounding box of the Container capturing the touches.也许有一种方法(某种小部件或属性)允许像 GestureDetector 这样的 hitTestBehavior,您可以将其设置为“不透明区域”,而不是 Container 的整个边界框捕获触摸。 Sorry cause i cant provide you an answer directly, will check it out later on the computer:)抱歉,我无法直接为您提供答案,稍后将在计算机上查看:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用具有良好动画颤动的动态浮动动作按钮创建底部导航栏? - how to create bottom nav bar with dynamic floating action button with good animation flutter? 带有浮动操作按钮的底部导航栏 flutter - bottom navigation bar with Floating Action Button flutter Flutter 使浮动动作粘在底部导航栏 - Flutter make floating action stick to bottom nav bar 使用浮动操作按钮将渐变颜色应用于底部导航栏 - Apply Gradient colours to Bottom Nav bar with floating action button 底部导航栏中的可扩展浮动操作按钮 - Flutter - Expandable Floating Action button in bottom navigation bar - Flutter 导航栏中的居中浮动操作按钮 Flutter - Centering Floating Action Button in navigation bar Flutter Flutter 底部导航栏 - Flutter bottom nav bar 如何使用浮动操作按钮自定义底部导航栏以及左右曲线设计? - How to customize a bottom navigation bar in flutter with floating action button and and also curve design to the left and right? 如何在带边框的中心底部导航栏中添加浮动操作按钮? - How to add Floating action Button in Bottom Navigation Bar in Center with border? 如何在带有缺口的底部导航栏中心添加浮动操作按钮? - How to add Floating action Button in Bottom Navigation Bar Center with notch?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM