Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

dart - ListTile single selection (Flutter)

For sure it's a simple solution fot this, but I can't figure out it - I quite new in flutter - still. What's the problem?

I have alert dialog with 4 list tiles which supposed to work as selectors for gps radius, however I have a problem with single selection. Now while one is selected - all are selected in same time. So i need to find a way how to make single selection for each of them (if one is selected rest should be unselected), and then pass it's value, eg. 10, 25 etc. while "Select" button is pressed.

class RadiusSelectorDialog extends StatefulWidget {
  RadiusSelectorDialog({Key key}) : super(key: key);

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

class _RadiusSelectorDialogState extends State<RadiusSelectorDialog>
    with TitleDescriptionTextMixin {
  bool selected = false;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      scrollable: true,
      contentPadding: EdgeInsets.all(4.0),
      title: Center(child: smallerBoldText('Select radius:', fontSize: 15.0)),
      content: Column(
        children: [
          Divider(
            color: Colors.grey,
            height: 2.0,
          ),
          CustomListTile(
            label: '10 km',
            selected: selected,
            onSelect: () => _onSelect(selected),
          ),
          CustomListTile(
            label: '25 km',
            selected: selected,
            onSelect: () => _onSelect(selected),
          ),
          CustomListTile(
            label: '50 km',
            selected: selected,
            onSelect: () => _onSelect(selected),
          ),
          CustomListTile(
            label: '75 km',
            selected: selected,
            onSelect: () => _onSelect(selected),
          ),
        ],
      ),
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(16.0))),
      actions: [
        FlatButton(
            child: Text('Select',
                style: TextStyle(
                    color: LegionColors.primaryRedHigh,
                    fontWeight: FontWeight.bold)),
            onPressed: () {
              Navigator.pop(context);
            })
      ],
    );
  }

  void _onSelect(bool value) {
    setState(() {
      if (selected == false) {
        selected = true;
      } else {
        selected = false;
      }
    });
  }
}

My custom listTile for selection.


class CustomListTile extends StatelessWidget {
  final String label;
  final bool selected;
  final Function onSelect;

  const CustomListTile(
      {Key key,
      @required this.selected,
      @required this.onSelect,
      @required this.label})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ListTile(
          title: Center(
              child: Text(label,
                  style: selected == false
                      ? TextStyle(color: Colors.black)
                      : TextStyle(
                          color: LegionColors.primaryRedHigh,
                          fontWeight: FontWeight.bold,
                        ))),
          selected: selected,
          onTap: onSelect,
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(16.0))),
        ),
        Divider(
          color: Colors.grey,
          height: 2.0,
        ),
      ],
    );
  }
}


question from:https://stackoverflow.com/questions/65916465/listtile-single-selection-flutter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are using the same variable selected to identify whether the item is selected for all the items. Here is what happens,

  1. One items is tapped
  2. setState -> selected -> true
  3. All the items update themselves to be selected

To avoid it

  1. you can move the identifier inside the CustomListTile and make it StatefulWidget.
  2. Or if you have to maintain the selection status in the parent, you can use a Map implementation
  HashMap<String, bool> selectedState = new HashMap();

  void updateSelectionStatus(String selectedTileId, bool status) {
    setState(() {
      selectedState[selectedTileId] = status;
    });
  }

And then you can use it like this

CustomListTile(
            label: '75 km',
            selected: selectedState['your-unique-id'],
            onSelect: () => updateSelectionStatus('your-unique-id', !selectedState['your-unique-id']),
          )

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...