Android 与单选按钮类似的按钮交互的良好代码设计是什么?
我想做一个类似单选按钮的用户交互,因此列表中只能有一个项目处于活动状态。我想使用ListItem小部件,而不是单选按钮图形 因此,我想:Android 与单选按钮类似的按钮交互的良好代码设计是什么?,android,flutter,design-patterns,dart,Android,Flutter,Design Patterns,Dart,我想做一个类似单选按钮的用户交互,因此列表中只能有一个项目处于活动状态。我想使用ListItem小部件,而不是单选按钮图形 因此,我想: 列表项A:点击“激活”列表项 ListItem B:点击“停用”当前活动项并激活此ListItem 实现这一点的最佳算法体系结构是什么 我尝试使用下面示例中的架构。问题是它不跟踪单击了哪个列表项,因此它会同时更改父项的所有子项的“状态” //------------------------ ParentWidget -------------------
- 列表项A:点击“激活”列表项李>
- ListItem B:点击“停用”当前活动项并激活此ListItem
//------------------------ ParentWidget --------------------------------
class ParentWidget extends StatefulWidget {
@override
_ParentWidgetState createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
bool _active = false;
void _handleTapboxChanged(bool newValue) {
setState(() {
_active = newValue;
});
}
@override
Widget build(BuildContext context) {
return Expanded (
ListView.builder(
itemCount: listOfBoxes.length,
itemBuilder: (BuildContext context, int index) {
return TapboxB(
active: _active,
onChanged: _handleTapboxChanged,
),
}
)
)
}
}
//------------------------- TapboxB ----------------------------------
class TapboxB extends StatelessWidget {
TapboxB({Key key, this.active: false, @required this.onChanged})
: super(key: key);
final bool active;
final ValueChanged<bool> onChanged;
void _handleTap() {
onChanged(!active);
}
Widget build(BuildContext context) {
return GestureDetector(
onTap: _handleTap,
child: Container(
child: Center(
child: Text(
active ? 'Active' : 'Inactive',
style: TextStyle(fontSize: 32.0, color: Colors.white),
),
),
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
color: active ? Colors.lightGreen[700] : Colors.grey[600],
),
),
);
}
}```
//------------------------ParentWidget--------------------------------
类ParentWidget扩展了StatefulWidget{
@凌驾
_ParentWidgetState createState()=>\u ParentWidgetState();
}
类_ParentWidgetState扩展状态{
bool _active=false;
void\u handleTapboxChanged(布尔新值){
设置状态(){
_活动=新值;
});
}
@凌驾
小部件构建(构建上下文){
扩大回报(
ListView.builder(
itemCount:ListofBox.length,
itemBuilder:(构建上下文,int索引){
返回TapboxB(
活动:_活动,
一旦更改:_handleTapboxChanged,
),
}
)
)
}
}
//-------------------------TapboxB----------------------------------
类TapboxB扩展了无状态小部件{
TapboxB({Key Key,this.active:false,@required this.onChanged})
:super(key:key);
最终bool激活;
变更后的最终价值;
void_handleTap(){
一旦改变(!活动);
}
小部件构建(构建上下文){
返回手势检测器(
onTap:_handleTap,
子:容器(
儿童:中心(
子:文本(
活动?“活动”:“非活动”,
样式:TextStyle(fontSize:32.0,颜色:Colors.white),
),
),
宽度:200.0,
高度:200.0,
装饰:盒子装饰(
颜色:活动?颜色。浅绿色[700]:颜色。灰色[600],
),
),
);
}
}```
尝试此方法,只需将粘贴复制到中即可查看结果
class _ParentWidgetState extends State<ParentWidget> {
int currentActiveItem = -1;
final listItems = [
'Albania',
'Andorra',
'Armenia',
'Austria',
'Azerbaijan',
'Belarus',
'Belgium',
'Bosnia and Herzegovina',
'Bulgaria',
'Croatia',
'Cyprus',
'Czech Republic',
'Denmark',
'Estonia'
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: ListView.builder(
itemCount: listItems.length,
itemBuilder: (context, index) {
return Container(
color: currentActiveItem == index ? Colors.blue : Colors.white,
child: MaterialButton(
onPressed: () {
setState(() {
currentActiveItem = index;
});
},
child: Text(
listItems[index],
),
),
);
},
),
),
);
}
}
class\u ParentWidgetState扩展状态{
int currentActiveItem=-1;
最终清单项目=[
“阿尔巴尼亚”,
“安道尔”,
“亚美尼亚”,
“奥地利”,
“阿塞拜疆”,
“白俄罗斯”,
“比利时”,
“波斯尼亚和黑塞哥维那”,
“保加利亚”,
“克罗地亚”,
“塞浦路斯”,
“捷克共和国”,
“丹麦”,
“爱沙尼亚”
];
@凌驾
小部件构建(构建上下文){
返回脚手架(
主体:容器(
子项:ListView.builder(
itemCount:listItems.length,
itemBuilder:(上下文,索引){
返回容器(
颜色:currentActiveItem==索引?颜色。蓝色:颜色。白色,
子:材质按钮(
已按下:(){
设置状态(){
currentActiveItem=索引;
});
},
子:文本(
列表项[索引],
),
),
);
},
),
),
);
}
}
根据需要进行修改!
//默认视图为空,没有任何选择
//如果要预先选择,请指定其中一个选项
字符串选择='nil';
最终清单=['方案一'、'方案二'、'方案三'、'方案四'];
@凌驾
小部件构建(构建上下文){
返回脚手架(
主体:容器(
子项:ListView.builder(
itemCount:list.length,
项目生成器:(con,ind){
返回列表块(
领先:集装箱(
宽度:20,
身高:20,
装饰:盒子装饰(
形状:BoxShape.circle,
边界:边界(
颜色:选择==列表[ind]
?颜色:绿色
:颜色。黑色,
宽度:1.0),
),
子:容器(
边距:所有边集(2.0),
宽度:10,
身高:10,
装饰:盒子装饰(
形状:BoxShape.circle,
颜色:选择==列表[ind]
?颜色:绿色
:颜色。白色,
边界:边界(
颜色:选择==列表[ind]
?颜色:绿色
:颜色。黑色,
宽度:1.0),
),
)),
标题:文本(列表[ind]),
onTap:(){
设置状态(){
选择=列表[ind];
});
});
},
),
),
);
}
检查此项:创建一个名为:selectedListItem的变量,并将所选项目存储在其中,在两个项目的点击事件中,将值存储在同一变量中,然后检索该变量以执行简单条件Why?如果您需要太多的项目,则选择为单选组是一种错误的模式;如果您需要以编程方式添加单选按钮,则使用单选按钮构造函数,然后从单选组添加视图;如果您需要列表,则使用recyclerview并使用类似{isSelected:Boolean,country:String}的对象
Modify as your requirement !
//default view is to be empty without any selection
//If you want to pre-select, then assign one of the option
String selection = 'nil';
final List<String> list = ['Option 1', 'Option 2', 'Option 3', 'Option 4'];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: ListView.builder(
itemCount: list.length,
itemBuilder: (con, ind) {
return ListTile(
leading: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: selection == list[ind]
? Colors.green
: Colors.black,
width: 1.0),
),
child: Container(
margin: EdgeInsets.all(2.0),
width: 10,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: selection == list[ind]
? Colors.green
: Colors.white,
border: Border.all(
color: selection == list[ind]
? Colors.green
: Colors.black,
width: 1.0),
),
)),
title: Text(list[ind]),
onTap: () {
setState(() {
selection = list[ind];
});
});
},
),
),
);
}