【问题标题】:Flutter: Is there a widget to flex toggle buttonsFlutter:是否有一个小部件可以灵活切换按钮
【发布时间】:2020-01-13 06:13:43
【问题描述】:

所以我是1.9.1 中介绍的ToggleButtons 像这样:

Column(
    mainAxisAlignment: MainAxisAlignment.start,
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Padding(padding: EdgeInsets.only(top: 8),),
      Text('Sort By: '),
      Align(
        alignment: Alignment.topLeft,
        child: ToggleButtons(
          borderColor: Color(0xffED7D31),
          selectedBorderColor: Color(0xffED7D31),
          selectedColor: Color(0xffAD7651),
          fillColor: Color(0xffFBE5D6),
          color: Color(0xffBF987E),
          children: <Widget>[
            ...state.sortBy.keys.map((name) => Text(name)).toList()
          ],
          onPressed: (index) => state.toggleSortBy(index),
          isSelected: state.sortBy.values.toList(),
        ),
      ),
    ],
),

这显然会从地图创建按钮小部件列表,我面临的问题是我在屏幕上看到以下警告

右溢出 X 个像素

所以我的问题很简单,就是有没有办法像 CSS 中那样“弯曲”按钮,这意味着当按钮的数量超过屏幕大小时,按钮会自动从下一行开始。

编辑:

state.sortBy 只是一个 Map,我将小部件的文本与它们的 selected 值一起存储在其中:

LinkedHashMap<String,bool> sortBy = LinkedHashMap.from({
    'Ascending' : true,
    'Descending' : false,
})

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    所以这有点工作,但我制作了一个名为 WrapIconToggleButtons 的小部件,它应该适合您的需求。它是基本的,但您可以根据需要对其进行自定义。请看:

    使用方法(类似于ToggleButtons)

    class Main extends StatefulWidget {
      @override
      _MainState createState() => _MainState();
    }
    
    class _MainState extends State<Main> {
      List<bool> isSelected = [
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
      ];
    
      @override
      Widget build(BuildContext context) {
        return Center(
          child: Container(
            child: WrapToggleIconButtons(
              iconList: [
                Icons.ac_unit,
                Icons.shopping_cart,
                Icons.shopping_cart,
                Icons.done,
                Icons.fiber_pin,
                Icons.sentiment_satisfied,
                Icons.looks_6,
                Icons.apps,
              ],
              isSelected: isSelected,
              onPressed: (int index) {
                setState(() {
                  for (int buttonIndex = 0; buttonIndex < isSelected.length; buttonIndex++) {
                    if (buttonIndex == index) {
                      isSelected[buttonIndex] = !isSelected[buttonIndex];
                    } else {
                      isSelected[buttonIndex] = false;
                    }
                  }
                });
              },
            ),
          ),
        );
      }
    }
    

    WrapToggleIconButtons 小部件

    class WrapToggleIconButtons extends StatefulWidget {
      final List<IconData> iconList;
      final List<bool> isSelected;
      final Function onPressed;
    
      WrapToggleIconButtons({
        @required this.iconList,
        @required this.isSelected,
        @required this.onPressed,
      });
    
      @override
      _WrapToggleIconButtonsState createState() => _WrapToggleIconButtonsState();
    }
    
    class _WrapToggleIconButtonsState extends State<WrapToggleIconButtons> {
      int index;
    
      @override
      Widget build(BuildContext context) {
        assert(widget.iconList.length == widget.isSelected.length);
        index = -1;
        return Wrap(
          children: widget.iconList.map((IconData icon){
            index++;
            return IconToggleButton(
              active: widget.isSelected[index],
              icon: icon,
              onTap: widget.onPressed,
              index: index,
            );
          }).toList(),
        );
      }
    }
    
    class IconToggleButton extends StatelessWidget {
      final bool active;
      final IconData icon;
      final Function onTap;
      final int width;
      final int height;
      final int index;
    
      IconToggleButton({
        @required this.active,
        @required this.icon,
        @required this.onTap,
        @required this.index,
        this.width,
        this.height,
      });
    
      @override
      Widget build(BuildContext context) {
        return Container(
          width: width ?? 60,
          height: height ?? 60,
          child: InkWell(
            child: Icon(icon,
              color: active ? Theme.of(context).accentColor : Theme.of(context).disabledColor,
            ),
            onTap: () => onTap(index),
          ),
        );
      }
    }
    

    【讨论】:

    • 如果某个答案解决了您的问题,请记住将其标记为正确。将来可能会对其他用户有所帮助。
    • 我不能使用Wrap,因为我正在使用的小部件是自动注入按钮的ToggleButtons,这意味着小部件的子项是直接进入注入按钮的文本或图标。
    • 让我研究一下并寻找可能的解决方案。
    • 我一直在寻找ToggleButtons 的工作原理。显然,小部件的初始版本没有constraints 属性,后来才通过PR 添加。尽管如此,它并没有提供足够的灵活性来控制按钮,现在我们只能设置按钮的大小
    • 我正在编写一个行为类似于 ToggleButton 的小部件,但在深入研究您的代码后,我意识到您在对行中按钮的顺序进行排序时有更复杂的行为。做同样的事情需要更多的工作,但它可能会做你想做的事。你知道如何创建这样的小部件吗?
    猜你喜欢
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2021-07-01
    • 2020-11-07
    • 2021-04-20
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    相关资源
    最近更新 更多