在 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());
},)