在扩展的小部件内使用AnimatedSize小部件

时间:2019-08-12 00:04:52

标签: android flutter dart

因此,我试图使用Flutter及其预定义的小部件构建“自定义底部导航”栏,我希望将栏项目(按钮)展开以填充空白区域,但在动画过程中始终会出现“溢出”错误。我将在下面分享我的代码,希望有人可以提供一些帮助:)

也尝试了Flexible但同样的问题。

StringUtils

,您可以在脚手架内部以这种方式使用它:

import 'package:flutter/material.dart';

class AnimatedBottomBar extends StatefulWidget {
  final List<BarItem> barItems;
  final Duration animationDuration;
  final Function onBarTap;
  final BarStyle barStyle;
  final Color unselectedBackgroundColor;
  final Color unselectedIconColor;
  final EdgeInsetsGeometry padding;

  AnimatedBottomBar(
      {this.barItems,
      this.animationDuration = const Duration(milliseconds: 500),
      this.onBarTap,
      this.barStyle,
      this.unselectedBackgroundColor,
      this.unselectedIconColor,
      this.padding});

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

class _AnimatedBottomBarState extends State<AnimatedBottomBar>
    with TickerProviderStateMixin {
  int selectedBarIndex = 1;

  @override
  Widget build(BuildContext context) {
    return Material(
      elevation: 30.0,
      child: Padding(
        padding: widget.padding == null
            ? EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0)
            : widget.padding,
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: _buildBarItems(),
        ),
      ),
    );
  }

  List<Widget> _buildBarItems() {
    List<Widget> _barItems = List();
    for (int i = 0; i < widget.barItems.length; i++) {
      BarItem item = widget.barItems[i];
      bool isSelected = selectedBarIndex == i;
      _barItems.add(Flexible(
        fit: FlexFit.loose,
        flex: isSelected ? 7 : 4,
        child: AnimatedSize(
          duration: widget.animationDuration,
          vsync: this,
          child: InkWell(
            splashColor: Colors.transparent,
            onTap: () {
              setState(() {
                selectedBarIndex = i;
                widget.onBarTap(selectedBarIndex);
              });
            },
            child: AnimatedContainer(
              padding:
                  const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
              duration: widget.animationDuration,
              decoration: BoxDecoration(
                  color: isSelected
                      ? item.color.withOpacity(0.15)
                      : widget.unselectedBackgroundColor != null
                          ? widget.unselectedBackgroundColor
                          : Colors.transparent,
                  borderRadius: BorderRadius.all(Radius.circular(20))),
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                children: <Widget>[
                  Stack(
                    children: <Widget>[
                      Icon(
                        item.iconData,
                        color: isSelected
                            ? item.color
                            : widget.unselectedIconColor,
                        size: widget.barStyle.iconSize,
                      ),
                      if (item.notificationCount > 0)
                        Positioned(
                          right: 0.0,
                          top: 0.0,
                          child: AnimatedContainer(
                            duration: Duration(seconds: 1),
                            height: widget.barStyle.iconSize / 2,
                            width: widget.barStyle.iconSize / 2,
                            child: Center(
                              child: Text(
                                widget.barItems[i].notificationCount < 99
                                    ? '${widget.barItems[i].notificationCount}'
                                    : '99',
                                textAlign: TextAlign.center,
                                maxLines: 1,
                                style: TextStyle(
                                    fontSize: item.notificationCount > 9
                                        ? widget.barStyle.fontSize / 2
                                        : widget.barStyle.fontSize / 2 + 2,
                                    color: Colors.white,
                                    fontWeight: FontWeight.w600,
                                    height: 0.85),
                              ),
                            ),
                            decoration: BoxDecoration(
                                shape: BoxShape.rectangle,
                                color: Colors.red.shade600,
                                borderRadius:
                                    BorderRadius.all(Radius.circular(4.0))),
                          ),
                        ),
                    ],
                  ),
                  if (isSelected)
                    SizedBox(
                      width: 10.0,
                    ),
                  AnimatedSize(
                    duration: widget.animationDuration,
                    curve: Curves.easeInOut,
                    vsync: this,
                    child: Text(
                      isSelected ? item.text : "",
                      style: TextStyle(
                          color: item.color,
                          fontWeight: widget.barStyle.fontWeight,
                          fontSize: widget.barStyle.fontSize),
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ));
      _barItems.add(SizedBox(width: 4.0,));
    }
    return _barItems;
  }
}

class BarStyle {
  final double fontSize, iconSize;
  final FontWeight fontWeight;

  BarStyle(
      {this.fontSize = 18.0,
      this.iconSize = 32,
      this.fontWeight = FontWeight.w600});
}

class BarItem {
  final String text;
  final IconData iconData;
  final Color color;
  int notificationCount;

  setNotificationCount(int i) {
    this.notificationCount = i;
  }

  BarItem({this.text, this.iconData, this.color, this.notificationCount = 0});
}

注意:不要忘了像这样预定义项目列表,并且当列表包含5个项目时,它会显示所需的结果,因为5个项目填满了所有空间(但请先删除扩展的小部件)。

Scaffold(
        bottomNavigationBar:AnimatedBottomBar(
        barItems: barItems,
        animationDuration: const Duration(milliseconds: 200),
        barStyle: BarStyle(
            fontSize: 25.0, iconSize: 30.0, fontWeight: FontWeight.w500),
        unselectedBackgroundColor: Colors.grey.shade600,
        unselectedIconColor: Colors.yellow,
        onBarTap: (index) {
          setState(() {
            _index = index;
            barItems[index].notificationCount++;
          });
        }); );

我希望有人可以帮我解决这个问题,因为它使我感到困惑:)

我还计划将其作为颤振包,供人们在按预期方式使用后使用。它还包含一个通知选项,如下面的此GIF所示:

Animated Gif Example

0 个答案:

没有答案