Flutter 颤振:自定义单选按钮
如何在Flatter中创建这样的自定义单选按钮组您可以使用ListView和带有一个局部变量的列表项来创建它,以存储所选项目。您可以根据变量将选定的项目呈现到ListItem中 另外,如果您需要代码片段,请告诉我 [编辑] 正如您所要求的,下面是代码snipper,它将向您展示如何维护每个ListView项的状态 现在你可以玩它,让它成为你想要的方式。如果只需要一个选定项,则可以这样编写逻辑Flutter 颤振:自定义单选按钮,flutter,Flutter,如何在Flatter中创建这样的自定义单选按钮组您可以使用ListView和带有一个局部变量的列表项来创建它,以存储所选项目。您可以根据变量将选定的项目呈现到ListItem中 另外,如果您需要代码片段,请告诉我 [编辑] 正如您所要求的,下面是代码snipper,它将向您展示如何维护每个ListView项的状态 现在你可以玩它,让它成为你想要的方式。如果只需要一个选定项,则可以这样编写逻辑 void main() { runApp(new MaterialApp( home: ne
void main() {
runApp(new MaterialApp(
home: new ListItemDemo(),
));
}
class ListItemDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("ListItem"),
),
body: new ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return new MyListItem(
title: "Hello ${index + 1}",
);
}),
);
}
}
class MyListItem extends StatefulWidget {
final String title;
MyListItem({this.title});
@override
_MyListItemState createState() => new _MyListItemState();
}
class _MyListItemState extends State<MyListItem> {
bool isSelected;
@override
void initState() {
super.initState();
isSelected = false;
}
@override
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
new Text("${widget.title} ${isSelected ? "true" : "false"}"),
new RaisedButton(
onPressed: () {
if (isSelected) {
setState(() {
isSelected = false;
});
} else {
setState(() {
isSelected = true;
});
}
},
child: new Text("Select"),
)
],
);
}
}
void main(){
runApp(新材料)PP(
主页:新建ListItemDemo(),
));
}
类ListItemDemo扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“列表项”),
),
正文:新建ListView.builder(
物品计数:10,
itemBuilder:(构建上下文,int索引){
返回新的MyListItem(
标题:“你好${index+1}”,
);
}),
);
}
}
类MyListItem扩展了StatefulWidget{
最后的字符串标题;
MyListItem({this.title});
@凌驾
_MyListItemState createState()=>new_MyListItemState();
}
类_MyListItemState扩展了状态{
布尔当选;
@凌驾
void initState(){
super.initState();
isSelected=false;
}
@凌驾
小部件构建(构建上下文){
返回新行(
儿童:[
新文本(${widget.title}${isSelected?“true”:“false”}),
新升起的按钮(
已按下:(){
如果(当选){
设置状态(){
isSelected=false;
});
}否则{
设置状态(){
isSelected=true;
});
}
},
子项:新文本(“选择”),
)
],
);
}
}
以下是完整的代码
class CustomRadio extends StatefulWidget {
@override
createState() {
return new CustomRadioState();
}
}
class CustomRadioState extends State<CustomRadio> {
List<RadioModel> sampleData = new List<RadioModel>();
@override
void initState() {
// TODO: implement initState
super.initState();
sampleData.add(new RadioModel(false, 'A', 'April 18'));
sampleData.add(new RadioModel(false, 'B', 'April 17'));
sampleData.add(new RadioModel(false, 'C', 'April 16'));
sampleData.add(new RadioModel(false, 'D', 'April 15'));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("ListItem"),
),
body: new ListView.builder(
itemCount: sampleData.length,
itemBuilder: (BuildContext context, int index) {
return new InkWell(
//highlightColor: Colors.red,
splashColor: Colors.blueAccent,
onTap: () {
setState(() {
sampleData.forEach((element) => element.isSelected = false);
sampleData[index].isSelected = true;
});
},
child: new RadioItem(sampleData[index]),
);
},
),
);
}
}
class RadioItem extends StatelessWidget {
final RadioModel _item;
RadioItem(this._item);
@override
Widget build(BuildContext context) {
return new Container(
margin: new EdgeInsets.all(15.0),
child: new Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Container(
height: 50.0,
width: 50.0,
child: new Center(
child: new Text(_item.buttonText,
style: new TextStyle(
color:
_item.isSelected ? Colors.white : Colors.black,
//fontWeight: FontWeight.bold,
fontSize: 18.0)),
),
decoration: new BoxDecoration(
color: _item.isSelected
? Colors.blueAccent
: Colors.transparent,
border: new Border.all(
width: 1.0,
color: _item.isSelected
? Colors.blueAccent
: Colors.grey),
borderRadius: const BorderRadius.all(const Radius.circular(2.0)),
),
),
new Container(
margin: new EdgeInsets.only(left: 10.0),
child: new Text(_item.text),
)
],
),
);
}
}
class RadioModel {
bool isSelected;
final String buttonText;
final String text;
RadioModel(this.isSelected, this.buttonText, this.text);
}
截图:
我通过以下逻辑实现了这一点。 如果需要详细解释,请回复
导入“包装:颤振/材料.省道”;
类父级扩展StatefulWidget{
母公司({
关键点,
}):super(key:key);
@凌驾
_ParentState createState()=>\u ParentState();
}
类_ParentState扩展了状态{
int _selectedItem=0;
选择项目(索引){
设置状态(){
_selectedItem=索引;
打印(选择Item.toString());
});
}
@凌驾
小部件构建(构建上下文){
//…您的小部件树在这里
返回ListView.builder(
收缩膜:对,
物品计数:5,
itemBuilder:(上下文,索引){
返回自定义项(
selectItem,//回调函数,父级设置状态
索引:索引,,
isSelected:_selectedItem==索引?true:false,
标题:index.toString(),
);
},
);
}
}
类CustomItem扩展StatefulWidget{
最后的字符串标题;
最终整数指数;
最终选举产生;
功能(int)选择项;
自定义项(
此.selectItem{
关键点,
这个名字,
这个索引,,
这次选举,
}):super(key:key);
_CustomItemState createState()=>\u CustomItemState();
}
类_CustomItemState扩展状态{
@凌驾
小部件构建(构建上下文){
返回行(
儿童:[
文本(${widget.isSelected?“true”:“false”}),
升起的按钮(
已按下:(){
widget.selectItem(widget.index);
},
子项:文本(“${widget.title}”),
)
],
);
}
}
导入“包装:颤振/材料.飞镖”;
类CustomRadio扩展StatefulWidget{
@凌驾
createState(){
返回新的CustomRadioState();
}
}
类CustomRadioState扩展状态{
List sampleData=新列表();
@凌驾
void initState(){
//TODO:实现initState
super.initState();
添加(新的RadioModel(true'A',0xffe6194B));
添加(新的RadioModel(假'B',0xfff58231));
sampleData.add(新的RadioModel(false,'C',0xffffe119));
添加(新的RadioModel(假'D',0xffbfef45));
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“列表项”),
),
正文:新建ListView.builder(
itemCount:sampleData.length,
itemBuilder:(构建上下文,int索引){
返回新墨水池(
splashColor:Colors.blueAccent,
onTap:(){
设置状态(){
sampleData.forEach((element)=>element.isSelected=false);
sampleData[index].isSelected=true;
});
},
儿童:新的放射性透射电镜(样本数据[索引]),
);
},
),
);
}
}
类RadioItem扩展了无状态小部件{
最终无线电模型项目;
放射性透射电镜(本项目);
@凌驾
小部件构建(构建上下文){
退回新货柜(
边距:新边集。全部(15.0),
孩子:新的一排(
mainAxisSize:mainAxisSize.max,
儿童:[
新容器(
身高:25.0,
宽度:25.0,
对齐:对齐.center,
子:容器(
身高:15.0,
宽度:15.0,
装饰:新盒子装饰(
颜色:颜色(项目颜色代码),
边界半径:常数边界半径.all(常数半径.圆形(15)),
)
),
装饰:新盒子装饰(
颜色:颜色。透明,
边界:新边界(
宽度:3.0,
颜色:_item.isSelected
?颜色(项目颜色代码)
:颜色。透明),
边界半径:常数边界半径.all(常数半径.圆形(25)),
),
),
新容器(
页边距:仅限新边集(左:10.0)
void main() {
runApp(new MaterialApp(
home: new CustomRadio(),
));
}
import 'package:flutter/material.dart';
class Parent extends StatefulWidget {
Parent({
Key key,
}) : super(key: key);
@override
_ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent> {
int _selectedItem = 0;
selectItem(index) {
setState(() {
_selectedItem = index;
print(selectItem.toString());
});
}
@override
Widget build(BuildContext context) {
//...YOUR WIDGET TREE HERE
return ListView.builder(
shrinkWrap: true,
itemCount: 5,
itemBuilder: (context, index) {
return CustomItem(
selectItem, // callback function, setstate for parent
index: index,
isSelected: _selectedItem == index ? true : false,
title: index.toString(),
);
},
);
}
}
class CustomItem extends StatefulWidget {
final String title;
final int index;
final bool isSelected;
Function(int) selectItem;
CustomItem(
this.selectItem, {
Key key,
this.title,
this.index,
this.isSelected,
}) : super(key: key);
_CustomItemState createState() => _CustomItemState();
}
class _CustomItemState extends State<CustomItem> {
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Text("${widget.isSelected ? "true" : "false"}"),
RaisedButton(
onPressed: () {
widget.selectItem(widget.index);
},
child: Text("${widget.title}"),
)
],
);
}
}
import 'package:flutter/material.dart';
class CustomRadio extends StatefulWidget {
@override
createState() {
return new CustomRadioState();
}
}
class CustomRadioState extends State<CustomRadio> {
List<RadioModel> sampleData = new List<RadioModel>();
@override
void initState() {
// TODO: implement initState
super.initState();
sampleData.add(new RadioModel(true, 'A',0xffe6194B));
sampleData.add(new RadioModel(false, 'B',0xfff58231));
sampleData.add(new RadioModel(false, 'C',0xffffe119));
sampleData.add(new RadioModel(false, 'D',0xffbfef45));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("ListItem"),
),
body: new ListView.builder(
itemCount: sampleData.length,
itemBuilder: (BuildContext context, int index) {
return new InkWell(
splashColor: Colors.blueAccent,
onTap: () {
setState(() {
sampleData.forEach((element) => element.isSelected = false);
sampleData[index].isSelected = true;
});
},
child: new RadioItem(sampleData[index]),
);
},
),
);
}
}
class RadioItem extends StatelessWidget {
final RadioModel _item;
RadioItem(this._item);
@override
Widget build(BuildContext context) {
return new Container(
margin: new EdgeInsets.all(15.0),
child: new Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Container(
height: 25.0,
width: 25.0,
alignment: Alignment.center,
child:Container(
height: 15.0,
width: 15.0,
decoration: new BoxDecoration(
color:Color(_item.colorCode),
borderRadius: const BorderRadius.all(const Radius.circular(15)),
)
),
decoration: new BoxDecoration(
color: Colors.transparent,
border: new Border.all(
width: 3.0,
color: _item.isSelected
? Color(_item.colorCode)
: Colors.transparent),
borderRadius: const BorderRadius.all(const Radius.circular(25)),
),
),
new Container(
margin: new EdgeInsets.only(left: 10.0)
)
],
),
);
}
}
class RadioModel {
bool isSelected;
final String buttonText;
final int colorCode;
RadioModel(this.isSelected, this.buttonText,this.colorCode);
}
void main() {
runApp(new MaterialApp(
home: new CustomRadio(),
));
}
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class RadioButton<T> extends StatefulWidget {
RadioButton({
Key key,
@required this.value,
@required this.caption,
@required this.groupValue,
@required this.onChanged,
}) : assert(value != null),
assert(caption != null),
assert(groupValue != null),
assert(onChanged != null),
super(key: key);
final T value;
final T groupValue;
final String caption;
final Function onChanged;
@override
State<StatefulWidget> createState() => _RadioButtonState();
}
class _RadioButtonState extends State<RadioButton> {
@override
Widget build(BuildContext context) {
final bool selected = widget.value == widget.groupValue;
return GestureDetector(
onTap: () {
widget.onChanged(widget.value);
},
child: Container(
width: double.maxFinite,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: selected ? Colors.red : Colors.white),
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
widget.caption,
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: selected ? Colors.white : Colors.red),
),
),
),
);
}
}