[英]Flutter: Custom Multiple Choice Row from List of Widgets
我正在尝试从容器小部件列表(包装在 GestureDetector 中用于 onTap)构建一个多选 Row。 当用户单击行中的容器小部件之一时,该容器小部件会更改颜色(变为蓝色)以反映用户的选择。 如果用户随后点击行中的不同容器小部件,该小部件会更改颜色以反映用户的选择,而所有其他小部件将重置为初始颜色(白色)。 此外,用户的选择(索引?)必须是可检索的。
到目前为止,我所能做的就是创建一排容器小部件,这些小部件在点击时改变颜色,但彼此独立运行。 也就是说用户可能会点击多选,这是不好的。 我需要一些关于如何突破到下一级别功能的建议,在该级别只能选择一个容器并传递所选值。
干杯,T
//choice button
class ChoiceButton extends StatefulWidget {
final String label;
final bool isPressed;
const ChoiceButton({
Key key,
this.isPressed = false,
this.label,
}) : super(key: key);
@override
_ChoiceButtonState createState() => _ChoiceButtonState();
}
class _ChoiceButtonState extends State<ChoiceButton> {
bool _isPressed;
@override
void initState() {
super.initState();
_isPressed = widget.isPressed;
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
_isPressed = !_isPressed;
});
},
child: Container(
height: 80,
width: 80,
decoration: BoxDecoration(
color: _isPressed ? Colors.blue : Colors.transparent,
border: Border.all(
color: Colors.blue,
width: 80 * 0.05,
),
),
child: Center(
child: Text(
widget.label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: _isPressed ? Colors.white : Colors.blue,
),
textAlign: TextAlign.center,
),
),
),
);
}
}
//choice row
class ChoiceRow extends StatefulWidget {
@override
_ChoiceRowState createState() => _ChoiceRowState();
}
class _ChoiceRowState extends State<ChoiceRow> {
bool isPressed = false;
String classChoice = '';
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: \[
SizedBox(width: 30),
ChoiceButton(
isPressed: isPressed,
label: 'A',
),
SizedBox(width: 10),
ChoiceButton(
isPressed: isPressed,
label: 'B',
),
SizedBox(width: 10),
ChoiceButton(
isPressed: isPressed,
label: 'C',
),
\],
);
}
}
我为此提供了两个答案......使用您喜欢的任何一个。
因此 Flutter 提供了一个名为ToggleButton的小部件,它将满足上述所有需求。 按照此文档了解有关此小部件的更多信息。
您可以在切换按钮的小部件列表中添加自定义的 ChoiceButton 设计,通过一些调整,您也可以实现您的 ChioceRow 设计。
class ChoiceRow extends StatefulWidget {
@override
_ChoiceRowState createState() => _ChoiceRowState();
}
class _ChoiceRowState extends State<ChoiceRow> {
List<bool> isPressedList = [false,false,false];
String classChoice = '';
@override
Widget build(BuildContext context) {
print("Status L $isPressedList");
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 30),
GestureDetector(
onTap: (){
print("Hello");
setState(() {
isPressedList[0] = true;
isPressedList[1] = false;
isPressedList[2] = false;
});
},
child: ChoiceButton(
isPressed: isPressedList[0],
label: 'A',
),
),
SizedBox(width: 10),
GestureDetector(
onTap: (){
setState(() {
isPressedList[0] = false;
isPressedList[1] = true;
isPressedList[2] = false;
});
},
child: ChoiceButton(
isPressed: isPressedList[1],
label: 'B',
),
),
SizedBox(width: 10),
GestureDetector(
onTap: (){
setState(() {
isPressedList[0] = false;
isPressedList[1] = false;
isPressedList[2] = true;
});
},
child: ChoiceButton(
isPressed: isPressedList[2],
label: 'C',
),
),
],
);
}
}
class ChoiceButton extends StatelessWidget {
final String label;
final bool isPressed;
ChoiceButton({this.label,this.isPressed});
@override
Widget build(BuildContext context) {
return Container(
height: 80,
width: 80,
decoration: BoxDecoration(
color: isPressed ? Colors.blue : Colors.transparent,
border: Border.all(
color: Colors.blue,
width: 80 * 0.05,
),
),
child: Center(
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: isPressed ? Colors.white : Colors.blue,
),
textAlign: TextAlign.center,
),
),
);
}
}
变化 :
我制作了一个列表 (onPressedList),它跟踪切换按钮的当前状态(比如哪个是打开的,哪些是关闭的)。
我在 ChoiceRow 类中的按钮上移动了 GestureDetector 包装。 这是因为很难将 onTap 结果从 ChoiceButton 传递到 ChoiceRow。 (现在,如果您想要 Button 类本身中的手势检测器,那么您可以将列表设为全局或完全不同的静态值,以便可以正确访问它)
我将 ChoiceButton 类设为无状态,因为现在不需要保持它有状态。
我所做的两件事是添加一个列表来跟踪切换按钮的当前状态,当一个切换按钮处于活动状态时,所有其他按钮都将被停用。
现在它按照您上面提到的方式工作,您还可以通过“isPressedList”跟踪所有按钮的当前状态。
GLHF :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.