在Flutter中点击另一个项目ListView后,如何取消选择已选择的项目? [英] How to deselect the already selected item after tap on another item ListView in Flutter?

查看:680
本文介绍了在Flutter中点击另一个项目ListView后,如何取消选择已选择的项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想允许用户从列表中仅选择一个选项,如果他一个接一个地选择,则应仅选择最后一个选项.

I would like to allow user to select only one option from the list, if he select one after another, then only last option should be considered as selected.

在当前代码中,用户可以从列表中选择我要避免的多个选项.

In current code, user can select multiple option from the list which i want to avoid.

尝试的代码:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Test App',
      theme: new ThemeData(
        primarySwatch: Colors.red,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<int> indexList = new List();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Selected ${indexList.length}  ' + indexList.toString()),
      ),
      body: new ListView.builder(
        itemCount: 3,    
        itemBuilder: (context, index) {
          return new CustomWidget(  
            index: index,
            callback: () {
              if (indexList.isNotEmpty) {
                indexList.clear();
              } 

            },
          );
        },
      ),
    );
  }
}

class CustomWidget extends StatefulWidget {
  final int index;
  final VoidCallback callback;

  const CustomWidget({Key key, this.index, this.callback}) : super(key: key);

  @override
  _CustomWidgetState createState() => new _CustomWidgetState();
}


class _CustomWidgetState extends State<CustomWidget> {
  bool selected = false;
  CustomWidget lastSelectedWidget;

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: () {
          setState(() {
            lastSelectedWidget = widget;
            print(lastSelectedWidget.key);
            selected = !selected;
          });
          widget.callback();
      },
      child: new Container(
        margin: new EdgeInsets.all(5.0),
        child: new ListTile(
          title: new Text("Title ${widget.index}"),
          subtitle: new Text("Description ${widget.index}"),
        ),
        decoration: selected
            ? new BoxDecoration(color: Colors.black38, border: new Border.all(color: Colors.black))
            : new BoxDecoration(),
      ),
    );
  }
}

我正在以列表样式实现单选按钮.

I am implementing kind of radio button in list style.

推荐答案

您不能将定义选择哪个CustomWidget的责任分配给自己的CustomWidget. CustomWidget不能不知道其他CustomWidget的存在,也不能知道它们所拥有的信息.

You cannot assign the responsibility of defining which CustomWidget is selected to the own CustomWidget. A CustomWidget must not know about the existence of other CustomWidgets, neither anything about the information they hold.

鉴于此,您的CustomWidget应该是这样的:

Given that, your CustomWidget should be something like this:

class CustomWidget extends StatefulWidget {
  final int index;
  final bool isSelected;
  final VoidCallback onSelect;

  const CustomWidget({
    Key key,
    @required this.index,
    @required this.isSelected,
    @required this.onSelect,
  })  : assert(index != null),
        assert(isSelected != null),
        assert(onSelect != null),
        super(key: key);

  @override
  _CustomWidgetState createState() => _CustomWidgetState();
}

class _CustomWidgetState extends State<CustomWidget> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: widget.onSelect,
      child: Container(
        margin: EdgeInsets.all(5.0),
        child: ListTile(
          title: Text("Title ${widget.index}"),
          subtitle: Text("Description ${widget.index}"),
        ),
        decoration: widget.isSelected
            ? BoxDecoration(color: Colors.black38, border: Border.all(color: Colors.black))
            : BoxDecoration(),
      ),
    );
  }
}

以及使用CustomWidget的小部件:

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int currentSelectedIndex;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Selected index is $currentSelectedIndex'),
      ),
      body: ListView.builder(
        itemCount: 3,
        itemBuilder: (context, index) {
          return CustomWidget(
            index: index,
            isSelected: currentSelectedIndex == index,
            onSelect: () {
              setState(() {
                currentSelectedIndex = index;
              });
            },
          );
        },
      ),
    );
  }
}

这篇关于在Flutter中点击另一个项目ListView后,如何取消选择已选择的项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆