rh2o
rh2o

Reputation: 105

How to change just one element of the list view in Flutter

I have a listView that returns some Items from Firestore and I want to change the color of just one container when I press over it and change it back when I press again.

How can I do this?

I tried to make a bool and change its value, but that changing the whole items

This is my code:

return ListView(

  children: snapshot.data.docs.map<Widget>((DocumentSnapshot document) {
   return Container( child:Text('Hello')

  }).toList();
)

Upvotes: 0

Views: 3375

Answers (2)

wpazio
wpazio

Reputation: 471

You should create Stateful Widget with your logic. Click on item should change widget state. In this case widget has property like title and isSelected these properties are wrapped into ListItem class. The only logic that you need is basically
widget._listItem.isSelected = !_isSelected; in GestureDetector. Below example should give you and idea of widget states.

class SelectableListItemWidget extends StatefulWidget {
  final ListItem _listItem;

  const SelectableListItemWidget(this._listItem);

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

class _SelectableListItemWidgetState extends State<SelectableListItemWidget> {
  String get _title => widget._listItem.title;

  bool get _isSelected => widget._listItem.isSelected;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          print('element: $_title has been clicked');
          widget._listItem.isSelected = !_isSelected;
        });
      },
      child: Container(
          color: _isSelected ? Colors.red : Colors.green,
          padding: const EdgeInsets.all(16),
          child: Text(
            _title,
            style: TextStyle(fontSize: 18),
          )),
    );
  }
}

class ListItem {
  String title;
  bool isSelected;

  ListItem(this.title, {this.isSelected = false});
}

New created widget can be used

  var items = [
    "Apple",
    "Cherimoya",
    "Grapefruit",
    "Jostaberry",
    "Plumcot",
    "Pomegranate",
    "Quince",
    "Kiwi",
    "Kiwano",
    "Huckleberry",
    "Marionberry",
    "Mango",
    "Strawberry",
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: items
            .map((item) => SelectableListItemWidget(ListItem(item)))
            .toList(),
      ),
    );
  }

flutter selectable listView

Upvotes: 1

asd asd
asd asd

Reputation: 146

You can call the function listWidget on your list of data.

List<int> selected = [];
List<Widget> listWidget(List listItems) {
  List<Widget> listWidget = [];

  for (var i = 0; i < listItems.length; i++) {
    var iSeleted = selected.contains(i);
    var temp = GestureDetector(
      onTap: () {
        setState(() {
          if (iSeleted)
            selected.remove(i);
          else
            selected.add(i);
        });
      },
      child: Container(
        color: iSeleted ? sColor : nsColor,
        child: Text('Hello'),
      ),
    );
    listWidget.add(temp);
  }
  return listWidget;
}

Here you can set the sColor to the colour you want for selected widget and nsColor for not selected widget.

List selected will contain the indexes of all the selected items.

Upvotes: 0

Related Questions