我是Flutter的初学者,我正在尝试创建一个名为IconSelect的自定义Widget。它应该呈现带有图例的图标列表,用户将只选择一个选项。当用户点击图标时,它应该更改所选图标的背景颜色并取消选择所有其他图标。
我的第一个方法是将IconSelect类创建为Stateful小部件,将另一个名为IconSelectItem的小部件创建为Stateless。 IconSelect将有一个子属性,包含IconSelectItem的实例。
如何处理儿童水龙头以更改IconSelect状态?其他人的任何想法都是适用的吗?
我的代码:
class IconSelect extends StatefulWidget {
final List<IconSelectItem> children;
final ValueChanged<int> onSaved;
IconSelect({
this.children,
this.onSaved
});
@override
State<StatefulWidget> createState() => new IconSelectState();
}
class IconSelectState extends State<IconSelect> {
int _selectedValue;
_handleTap(int value) {
setState(() {
_selectedValue = value;
});
widget.onSaved(_selectedValue);
}
@override
Widget build(BuildContext context) {
return new Row(
children: widget.children,
);
}
@override
void initState() {
super.initState();
// I tried the code below without success
widget.children.forEach((IconSelectItem item) {
item.onTap = _handleTap(item);
});
}
}
class IconSelectItem extends StatelessWidget {
final Icon icon;
final String legend;
final int value;
VoidCallback onTap;
final bool _selected = false;
IconSelectItem({
Key key,
this.icon,
this.legend,
this.value,
}) : super(key: key);
_handleTap() {
onTap();
}
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: () => _handleTap(),
child: new Column(
children: <Widget>[
new CircleAvatar(
radius: 30.0,
child: icon,
backgroundColor: _selected ? Colors.blue : Colors.white,
),
new Center(
child: new Text(legend),
)
],
),
);
}
}
答案 0 :(得分:0)
在IconSelectItem的祖先上调用setState
:
class YourPageState extends State<YourPage> {
int _selectedValue;
@override
Widget build(BuildContext context) {
return new Row(
children: widget.items.map((Item item) {
return new GestureDetector(
onTap: () {
// this class is a ancestor of IconSelectItem.
// setState will rebuild children.
setState(() {
_selectedValue = value;
});
},
child: new IconSelectItem(
icon: item.icon,
legend: item.legend,
value: item.value,
// every time _selectedValue changes,
// IconSelectItem is rebuild by setState.
selected: item.value == _selectedValue,
),
);
}).toList(),
);
}
}
class IconSelectItem extends StatelessWidget {
final Icon icon;
final String legend;
final int value;
final bool selected;
IconSelectItem({
Key key,
this.icon,
this.legend,
this.value,
this.selected = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new CircleAvatar(
radius: 30.0,
child: icon,
backgroundColor: selected ? Colors.blue : Colors.white,
),
new Center(
child: new Text(legend),
),
],
);
}
}