Flutter 颤振:自定义单选按钮

Flutter 颤振:自定义单选按钮,flutter,Flutter,如何在Flatter中创建这样的自定义单选按钮组您可以使用ListView和带有一个局部变量的列表项来创建它,以存储所选项目。您可以根据变量将选定的项目呈现到ListItem中 另外,如果您需要代码片段,请告诉我 [编辑] 正如您所要求的,下面是代码snipper,它将向您展示如何维护每个ListView项的状态 现在你可以玩它,让它成为你想要的方式。如果只需要一个选定项,则可以这样编写逻辑 void main() { runApp(new MaterialApp( home: ne

如何在Flatter中创建这样的自定义单选按钮组

您可以使用ListView和带有一个局部变量的列表项来创建它,以存储所选项目。您可以根据变量将选定的项目呈现到ListItem中

另外,如果您需要代码片段,请告诉我

[编辑]

正如您所要求的,下面是代码snipper,它将向您展示如何维护每个ListView项的状态

现在你可以玩它,让它成为你想要的方式。如果只需要一个选定项,则可以这样编写逻辑

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