flutter - 小部件可以有一个“联合”状态吗?
问题描述
我想实现一个自定义单选按钮,但我可以选择所有这些,当然,“单选”的意思是,我只能选择一个。
我的代码:
class RadioSelect extends StatefulWidget {
const RadioSelect(this.text, this.index, {Key key}) : super(key: key);
final String text;
final int index;
@override
_RadioSelectState createState() => _RadioSelectState();
}
class _RadioSelectState extends State<RadioSelect> {
int sizeIndex = 0;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
sizeIndex = widget.index;
});
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
margin: EdgeInsets.only(right: 8, top: 8),
width: 70,
height: 55,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 3,
color: sizeIndex == widget.index
? Color.fromARGB(255, 139, 195, 74)
: Colors.white,
),
borderRadius: BorderRadius.all(
Radius.circular(10) // <--- border radius here
)),
child: Text(
widget.text,
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
);
}
}
我知道这是因为每个RadioSelect()
都是不同的实例,但我怎样才能让它工作呢?
解决方案
您可以根据Radio
小部件执行此操作:
- 将您的小部件更改为
StatelessWidget
.
class RadioSelect extends StatelessWidget {
@override
Widget build(BuildContext context) {
// ...
}
}
- 创建一个
isSelected
属性并基于此属性设置小部件布局。
class RadioSelect extends StatelessWidget {
final bool isSelected;
const RadioSelect({this.isSelected});
@override
Widget build(BuildContext context) {
return Container(
// Some logic based on isSelected
color: isSelected ? Colors.red : Colors.white,
);
}
}
- 创建一个
onChanged
属性,每次用户点击它时,调用这个属性。
class RadioSelect extends StatelessWidget {
final void Function() onChanged;
final bool isSelected;
const RadioSelect({this.isSelected, this.onChanged});
@override
Widget build(BuildContext context) {
return GestureDetector(
// Use onChanged as callback
onTap: () => onChanged(),
child: Container(
color: isSelected ? Colors.red : Colors.white,
),
);
}
}
现在,当您必须使用它的多个实例时,您可以使用索引来跟踪当前选择的收音机:
class _MainWidgetState extends State<MainWidget> {
// Keeping track of the number of ratios you are using
final int _numRadios = 10;
int _currentIndex;
@override
Widget build(BuildContext context) {
return Column(
children: [
for (int i = 0; i < _numRatios; i++)
RadioSelect(
// The radio is select if the current index of this widget
// is equal to the current index of this child in the Column
isSelected: _currentIndex == i,
// When the user taps one ratio, updte the current index
// of this widget and set a new state
onChanged: () => setState(() => _currentIndex = i),
)
]
);
}
}
注意:上面的代码认为所有比率的布局都是相等的。例如,如果每个比率都必须有自己的文本,则可以替换_numRatios
为字符串列表或更具描述性的数据对象:
class _MainWidgetState extends State<MainWidget> {
final List<String> texts = ["radio1", "radio2", "radio3", "radio4"];
int _currentIndex;
@override
Widget build(BuildContext context) {
return Column(
children: [
for (int i = 0; i < texts.length; i++)
RadioSelect(
// Supposing you have a text property in your RadioSelect
// Access the text of the current child in the list of strings
text: texts[i],
isSelected: _currentIndex == i,
onChanged: () => setState(() => _currentIndex = i),
)
]
);
}
}
推荐阅读
- recursion - 方案:过程是递归的,但过程是递归的还是迭代的?
- pandas - 在 DataFrame 中展开列表
- awk - 如何将csv中的四列与awk进行比较?
- javascript - .mouseleave 具有相同类的多个元素
- javascript - 自定义图形属性/对象一致性
- google-cloud-platform - 未找到请求的项目
- javascript - 在反应路由器中设置baseurl
- tensorflow - 使用经过训练的对象检测 API 模型和 TF 2 进行批量预测
- ruby-on-rails - 覆盖gem的初始化方法?
- javascript - Firebase getDownloadURL 错误“用户取消了上传/下载”