Flutter:是否有一个小部件可以弯曲切换按钮

时间:2020-01-12 17:58:28

标签: flutter flutter-layout

所以我是n : Nat中引入的import Data.SortedMap -- pretty much a Vector data Key : Type -> Nat -> Type where KNil : Key a 0 KCons : a -> Key a n -> Key a (S n) Eq a => Eq (Key a n) where KNil == KNil = True (KCons x xs) == (KCons y ys) = x == y && xs == ys Ord a => Ord (Key a n) where compare KNil KNil = EQ compare (KCons x xs) (KCons y ys) = case compare x y of EQ => compare xs ys x => x -- same as Key data Value : Type -> Nat -> Type where VNil : Value a 0 VCons : a -> Value a n -> Value a (S n) -- Map for keys and values of a fixed length NatIndexedMap : (Nat -> Type) -> (Nat -> Type) -> Nat -> Type NatIndexedMap k v n = SortedMap (k n) (v n) nim2 : NatIndexedMap (Key Nat) (Value String) 2 nim2 = SortedMap.fromList [(KCons 0 (KCons 0 KNil), VCons "a" (VCons "a" VNil))] nim3 : NatIndexedMap (Key Nat) (Value String) 3 nim3 = SortedMap.fromList [(KCons 0 (KCons 0 (KCons 0 KNil)), VCons "a" (VCons "a" (VCons "a" VNil)))] -- List of maps with keys and values which increase in length data WonderMap : (Nat -> Type) -> (Nat -> Type) -> Nat -> Type where WonderMapNil : {k : Nat -> Type} -> {v : Nat -> Type} -> WonderMap k v 0 WonderMapCons : {n : Nat} -> {k : Nat -> Type} -> {v : Nat -> Type} -> NatIndexedMap k v (S n) -> WonderMap k v n -> WonderMap k v (S n) wm : WonderMap (Key Nat) (Value String) 3 wm = WonderMapCons nim3 (WonderMapCons nim2 (WonderMapCons SortedMap.empty WonderMapNil)) -- will return Nothing if Key n > Map n lookup : {n : Nat} -> {m : Nat} -> {k : Nat -> Type} -> {v : Nat -> Type} -> k n -> WonderMap k v m -> Maybe (v n) lookup {n = Z} _ WonderMapNil = Nothing lookup {m = Z} _ _ = Nothing lookup {n = S n'} {m = S m'} key (WonderMapCons map maps) = case decEq (S n') (S m') of Yes prf => SortedMap.lookup key (rewrite prf in map) No _ => if (S n') < (S m') then lookup key maps else Nothing ,如下所示:

$ idris -p contrib WonderMap.idr
     ____    __     _                                          
    /  _/___/ /____(_)____                                     
    / // __  / ___/ / ___/     Version 1.3.1
  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/      
 /___/\__,_/_/  /_/____/       Type :? for help               

Idris is free software with ABSOLUTELY NO WARRANTY.            
For details type :warranty.
*WonderMap> :t wm
wm : WonderMap (Key Nat) (Value String) 3
*WonderMap> lookup (KCons 0 KNil) wm                                    -- there are no key/value pairs for n = 0
Nothing : Maybe (Value String 1)
*WonderMap> lookup (KCons 0 (KCons 0 KNil)) wm
Just (VCons "a" (VCons "a" VNil)) : Maybe (Value String 2)
*WonderMap> lookup (KCons 0 (KCons 0 (KCons 0 KNil))) wm
Just (VCons "a" (VCons "a" (VCons "a" VNil))) : Maybe (Value String 3)
*WonderMap> lookup (KCons 0 (KCons 0 (KCons 1 KNil))) wm                -- good n, bad key
Nothing : Maybe (Value String 3)
*WonderMap> lookup (KCons 0 (KCons 0 (KCons 0 (KCons 0 KNil)))) wm      -- wm only has key/value pairs for n <= 3
Nothing : Maybe (Value String 4)

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

右侧溢出了X个像素

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

编辑:

ToggleButtons只是一个1.9.1,我在其中将小部件的文本与它们的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(), ), ), ], ), 值一起存储:

state.sortBy

1 个答案:

答案 0 :(得分: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),
      ),
    );
  }
}