Reputation: 105
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
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(),
),
);
}
Upvotes: 1
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