在Flutter 应用开发中,经常会遇到各种单选效果,虽然官方提供了Radio组件,但是并不能满足我们实际的开发需求,所以往往还需要自定义控件才能满足平时的开发需求。下面就平时开发中用到的单选进行介绍:
自定义SegmentBar
对于分段组件大家肯定不会陌生,主要是实现多个分段,实现单选功能,效果如下图。
话不多说,直接上代码:
class SegmentBarView extends StatefulWidget {
List<String> datas;
Function(String) onSelected;
int defaultIndex=0;
SegmentBarView({@required this.datas, this.onSelected,this.defaultIndex});
@override
_SegmentBarViewState createState() => _SegmentBarViewState();
}
class _SegmentBarViewState extends State<SegmentBarView> {
List<String> sdkLists;
String selectItem;
@override
void initState() {
super.initState();
sdkLists = widget.datas;
selectItem=sdkLists[widget.defaultIndex];
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: Row(
children: _buildSegments(sdkLists),
),
),
);
}
_buildSegments(List list) {
if(list == null) {
return Container();
}
List<Widget> items = List();
list.forEach((item){
if(item != null) {
items.add(Container(
padding: EdgeInsets.only(top: 8,bottom: 8),
child: _buildItem(item),
));
}
});
return items;
}
_buildItem(String item) {
if(selectItem == item) {
return Container(
height: 34,
child: RaisedButton(
shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(15)
),
color: Color(0xFF00A6DE),
onPressed: (){
},
child: Text(item,style: TextStyle(color: Colors.white),),
),
);
}else {
return Container(
height: 34,
child: OutlineButton(
borderSide: BorderSide(color: Color(0xFFcccccc),width: 0.5),
onPressed: (){
updateGroupValue(item);
},
child: Text(item),
),
);
}
}
updateGroupValue(String item) {
if(item == selectItem) {
return;
}else {
selectItem = item;
widget.onSelected(selectItem);
setState(() {
});
}
}
}
使用的时候,只需要按照构造函数传入对应的参数即可。
自定义Radio
当然,开发中还可以遇到下面这种带圆角的按钮,效果如下。
对于这种效果怎么做呢,最简单的就是硬编码,用两个按钮,然后点击的时候去切换,代码如下:
//只能支持两个按钮单选
class RadioGroupWidget extends StatefulWidget {
List<String> datas ;
Function(String) onSelected;
double radioWidth=80;
double radioHeight=28;
RadioGroupWidget({@required this.datas,@required this.onSelected,this.radioWidth, this.radioHeight,});
@override
State<StatefulWidget> createState() {
return RadioGroupState();
}
}
class RadioGroupState extends State<RadioGroupWidget> {
var chooseStr;
int choosed=1;
Color choosedBgColor=Colors.blue;
Color choosedCornerColor=Colors.blue;
Color choosedTxtColor=Colors.white;
Color defaultBgColor=Colors.white;
Color defaultCornerColor=Colors.grey;
Color defaultTxtColor=Colors.grey;
@override
void initState() {
super.initState();
chooseStr=widget.datas[0];
}
@override
Widget build(BuildContext context) {
return Row(
children: [
GestureDetector(
onTap: (){
choosed=1;
chooseStr=widget.datas[0];
setState(() {});
widget.onSelected(chooseStr);
},
child: Container(
height: widget.radioHeight,
width: widget.radioWidth,
decoration: BoxDecoration(
color: choosed==1?choosedBgColor:defaultBgColor,
borderRadius: BorderRadius.only(topLeft: Radius.circular(15),bottomLeft: Radius.circular(15)),
border: Border.all(width: 1, color: choosed==1?choosedCornerColor:defaultCornerColor),
),
child: Center(child: Text(widget.datas[0],style: TextStyle(color: choosed==1?choosedTxtColor:defaultTxtColor,fontSize: 12))),
)
),
GestureDetector(
onTap: (){
choosed=2;
chooseStr=widget.datas[1];
setState(() {});
widget.onSelected(chooseStr);
},
child: Container(
height: widget.radioHeight,
width: widget.radioWidth,
decoration: BoxDecoration(
color: choosed==2?choosedBgColor:defaultBgColor,
borderRadius: BorderRadius.only(topRight: Radius.circular(15),bottomRight: Radius.circular(15)),
border: Border.all(width: 1, color: choosed==2?choosedCornerColor:defaultCornerColor),
),
child: Center(child: Text(widget.datas[1],style: TextStyle(color: choosed==2?choosedTxtColor:defaultTxtColor,fontSize: 12))),
)
)
],
);
}
}
实际使用时,传入参数即可。
```
List<String> lineRadios = ['实时流水', '累计流水'];
RadioGroupWidget(radioWidth:80,radioHeight:28,datas: lineRadios, onSelected: (value){
print('_buildChartTitle value: '+value.toString());
},)
```
一点题外话:
我们有《Android学习、面试;文档、视频资源免费获取》,可复制链接后用石墨文档 App 或小程序打开链接或者私信我资料领取
https://shimo.im/docs/TG8PDh9D96WGTT8W