在Flutter 应用开发中,经常会遇到各种单选效果,虽然官方提供了Radio组件,但是并不能满足我们实际的开发需求,所以往往还需要自定义控件才能满足平时的开发需求。下面就平时开发中用到的单选进行介绍:
自定义SegmentBar
对于分段组件大家肯定不会陌生,主要是实现多个分段,实现单选功能,效果如下图。
话不多说,直接上代码:
class SegmentBarView extends StatefulWidget {List datas;Function(String) onSelected;int defaultIndex=0;SegmentBarView({@required this.datas, this.onSelected,this.defaultIndex});@override_SegmentBarViewState createState() => _SegmentBarViewState();
}class _SegmentBarViewState extends State {List sdkLists;String selectItem;@overridevoid initState() {super.initState();sdkLists = widget.datas;selectItem=sdkLists[widget.defaultIndex];}@overrideWidget 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 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 datas ;Function(String) onSelected;double radioWidth=80;double radioHeight=28;RadioGroupWidget({@required this.datas,@required this.onSelected,this.radioWidth, this.radioHeight,});@overrideState createState() {return RadioGroupState();}
}class RadioGroupState extends State {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;@overridevoid initState() {super.initState();chooseStr=widget.datas[0];}@overrideWidget 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 lineRadios = ['实时流水', '累计流水'];
RadioGroupWidget(radioWidth:80,radioHeight:28,datas: lineRadios, onSelected: (value){print('_buildChartTitle value: '+value.toString());},)