所以我是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
答案 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),
),
);
}
}