【问题标题】:IllegalFloatingActionButtonSizeException Floating action button must be a circleIllegalFloatingActionButtonSizeException 浮动动作按钮必须是圆形
【发布时间】:2021-02-01 18:34:50
【问题描述】:

我收到以下错误:

IllegalFloatingActionButtonSizeException:浮动操作按钮必须 是一个圆圈文件“circular_notch_and_corner_clipper.dart”,第 25 行, 在 CircularNotchedAndCorneredRectangleClipper.getClip 文件中 _RenderCustomClip._updateClip 文件中的“proxy_box.dart”,第 1314 行 “proxy_box.dart”,第 1935 行,在 RenderPhysicalShape.paint 文件中 “object.dart”,第 2311 行,在 RenderObject._paintWithContext 文件中 “object.dart”,第 189 行,在 PaintingContext.paintChild 文件中 “box.dart”,第 2826 行,在 RenderBoxContainerDefaultsMixin.defaultPaint 文件“custom_layout.dart”,第 407 行,在 RenderCustomMultiChildLayoutBox.paint 文件“object.dart”,第 2311 行, 在 RenderObject._paintWithContext 文件“object.dart”,第 189 行,在 PaintingContext.paintChild 文件“proxy_box.dart”,第 131 行,在 RenderProxyBoxMixin.paint 文件“material.dart”,第 555 行,在 _RenderInkFeatures.paint 文件“object.dart”,第 2311 行,在 RenderObject._paintWithContext 文件“object.dart”,第 189 行,在 PaintingContext.paintChild 文件“proxy_box.dart”,第 131 行,在 RenderProxyBoxMixin.paint 文件“object.dart”,第 396 行,在 PaintingContext.pushLayer 文件“proxy_box.dart”,第 1862 行,在 RenderPhysicalModel.paint 文件“object.dart”,第 2311 行,在 RenderObject._paintWithContext 文件“object.dart”,第 189 行,在 PaintingContext.paintChild 文件“proxy_box.dart”,第 131 行,在 RenderProxyBoxMixin.paint 文件“object.dart”,第 2311 行,在 RenderObject._paintWithContext 文件“object.dart”,第 189 行,在 PaintingContext.paintChild 文件“proxy_box.dart”,第 131 行,在 RenderProxyBoxMixin.paint 文件“object.dart”,第 2311 行,在 RenderObject._paintWithContext 文件“object.dart”,第 189 行,在 PaintingContext.paintChild 文件“proxy_box.dart”,第 131 行,在 RenderProxyBoxMixin.paint 文件“object.dart”,第 2311 行,在 RenderObject._paintWithContext 文件“object.dart”,第 140 行,在 PaintingContext._repaintCompositedChild 文件“object.dart”,行 100、在 PaintingContext.repaintCompositedChild 文件“object.dart”中, 第 978 行,在 PipelineOwner.flushPaint 文件“binding.dart”中,第 438 行, 在 RendererBinding.drawFrame 文件“binding.dart”,第 914 行,在 WidgetsBinding.drawFrame 文件“binding.dart”,第 302 行,在 RendererBinding._handlePersistentFrameCallback 文件“binding.dart”, 第 1117 行,在 SchedulerBinding._invokeFrameCallback 文件中 “binding.dart”,第 1055 行,在 SchedulerBinding.handleDrawFrame 文件中 “binding.dart”,第 971 行,在 SchedulerBinding._handleDrawFrame 文件中 “zone.dart”,第 1190 行,在 _rootRun 文件中“zone.dart”,第 1093 行,在 _CustomZone.run 文件“zone.dart”,第 997 行,_CustomZone.runGuarded 文件“hooks.dart”,第 251 行,_invoke 文件“hooks.dart”,第 209 行,_drawFrame

我想这可能与设备类型有关,但我不确定。这是我看到错误的设备之一:

品牌:“三星”,设备:“crownlte”,型号:“SM-N960F”

相关代码:

import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';

AnimationController _animationController;
  Animation<double> animation;

  @override
  void initState() {
    _animationController = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    );

    CurvedAnimation curve = CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.5,
        1.0,
        curve: Curves.fastOutSlowIn,
      ),
    );

    animation = Tween<double>(
      begin: 0,
      end: 1,
    ).animate(curve);

    WidgetsBinding.instance.addPostFrameCallback(
      (_) {
        _handleInternetConnection();

        Future.delayed(
          Duration(seconds: 1),
          () {
            if (mounted) _animationController.forward();
          },
        );
      },
    );

    super.initState();
  }

...
floatingActionButton: (_currentIndex != 3 && showFAB)
            ? ScaleTransition(
                scale: animation,
                child: FloatingActionButton(
                  elevation: 8,
                  foregroundColor: Colors.white,
                  child: Icon(
                    _currentIndex == 0
                        ? Icons.edit
                        : Icons.face_retouching_natural,
                    size: 36,
                  ),
                  onPressed: () => _currentIndex == 0
                      ? NewStory.show(context, null)
                      : NewMood.show(context, null),
                ),
              )
            : null,
floatingActionButtonLocation:
              FloatingActionButtonLocation.centerDocked,
          bottomNavigationBar: AnimatedBottomNavigationBar(
            icons: allDestinations()
                .map((NavbarOption destination) => destination.icon)
                .toList(),
            activeColor: Colors.white,
            splashColor: Theme.of(context).primaryColor,
            activeIndex: _currentIndex,
            gapLocation: GapLocation.center,
            inactiveColor: Colors.white60,
            notchAndCornersAnimation: animation,
            backgroundColor: Theme.of(context).primaryColor,
            notchSmoothness: NotchSmoothness.softEdge,
            onTap: (index) => setState(() => _currentIndex = index),
          ),
        ),

【问题讨论】:

  • 您确定可以使用最新版本的 animated_bottom_navigation_bar (0.3.2) 重现该问题吗?
  • 我们能看到浮动操作按钮的代码吗?
  • @Deczaloth 是的,它发生在最后一个版本上,虽然这是一个间歇性问题,但我无法每次都重现它
  • @Apps247 我已经添加了代码

标签: flutter dart widget floating-action-button


【解决方案1】:

也许以下原因可能会导致错误,因为您提到它不会每次都发生

也许,从 0 (begin:0) 开始的比例转换会导致错误,因为当它被缩放到 0 时,它不再是一个圆。因此,将开始更改为大约的值。 0 可能会解决错误,即begin:0.00001

 WidgetsBinding.instance.addPostFrameCallback(
      (_) {
        _handleInternetConnection();

        Future.delayed(
          Duration(seconds: 1),
          () {
            if (mounted) _animationController.forward();
          },
        );
      },
    );

解决方案:

  1. 设置开始于begin:0.00001

  2. 此外,如果您希望小部件在构建后立即进行动画处理,则最好使用隐式动画。我修改了代码以包含隐式动画而不是显式动画(其中必须显式调用 forward() 以进行动画处理)。

试试这个例子(使用空安全)

import 'package:flutter/material.dart';

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

/// This is the main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Index 0: Home',
      style: optionStyle,
    ),
    Text(
      'Index 1: Business',
      style: optionStyle,
    ),
    Text(
      'Index 2: School',
      style: optionStyle,
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Sample'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      floatingActionButton: _selectedIndex == 0
          ? TweenAnimationBuilder<double>(
              tween: Tween<double>(
                begin: 0.00001,
                end: 1,
              ),
              curve: Interval(
                0.5,
                1.0,
                curve: Curves.fastOutSlowIn,
              ),
              duration: Duration(milliseconds: 700),
              builder: (_, double scaleValue, __) {
                return Transform.scale(
                    scale: scaleValue,
                    child: FloatingActionButton(
                      elevation: 8,
                      foregroundColor: Colors.white,
                      child: Icon(
                        Icons.face_retouching_natural,
                        size: 36,
                      ),
                      onPressed: () {
                        print("hi");
                      },
                    ));
              })
          : null,
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: 'Business',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'School',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

【讨论】:

  • 如果您仍然收到错误,请告诉我。
  • 谢谢!我会试试的。
  • 在我的情况下我需要控制器,因为当用户更改底部导航时我隐藏了操作按钮,是否可以使用隐式动画来做到这一点?
  • 我已经更新了示例代码,它演示了相同的。
  • 我想你错过了在组件内分配控制器的位置,我不知道该怎么做。
【解决方案2】:

首先,尝试使用最新版本的库和颤振运行它。如果它仍然存在,请告诉我。我不能复制它,所以如果你能复制,请提供一个最小的可复制样本。

其次,关于“我猜可能与设备类型有关,但我不确定。”,可能与设备无关,因为Flutter是跨平台的,您的代码似乎不相关到本机代码。

第三,尝试使用“二进制搜索调试”技术。例如,尝试从 AnimatedBottomNavigationBar() 中删除所有参数并查看它是否有效。如果是这样,请添加一些参数并重试。如果再次起作用,请添加更多参数;否则删除一些。通过这样做,您将看到哪个参数导致了问题。

【讨论】:

  • 它仍然存在于最新版本中。关于设备特定案例,我记得一个名为“不保留活动”的设置,即使使用 Flutter,也会导致我出现特定错误,我相信这是可能的(我将对此进行测试,但可以是其他任何事情)。我将尝试进行更多调试,但正如我所说,它有时会发生,有时不会(它是一个公共应用程序,我看到了 Sentry 的错误)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 2017-08-17
  • 2015-03-19
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多