Change background color of ListTile upon selection in Flutter
FlutterDartListviewFlutter LayoutBackground ColorFlutter Problem Overview
I've made a ListView
in Flutter, but now I have some ListTiles
in this ListView
that can be selected. Upon selection, I want the background color to change to a color of my choice. I don't know how to do that.
In the docs they mention that a ListTile
has a property style
. However, when I try to add that (as in third last line in the code below), this style
property gets a squiggly red line underneath and the compiler tells me that The named parameter 'style' isn't defined
.
Widget _buildRow(String string){
return new ListTile(
title: new Text(string),
onTap: () => setState(() => toggleSelection(string)),
selected: selectedFriends.contains(string),
style: new ListTileTheme(selectedColor: Colors.white,),
);
}
Flutter Solutions
Solution 1 - Flutter
I was able to change the background color of the ListTile using a BoxDecoration inside Container:
ListView (
children: <Widget>[
new Container (
decoration: new BoxDecoration (
color: Colors.red
),
child: new ListTile (
leading: const Icon(Icons.euro_symbol),
title: Text('250,00')
)
)
]
)
Solution 2 - Flutter
Screenshot:
Short answer:
ListTile(
tileColor: isSelected ? Colors.blue : null,
)
Full Code:
// You can also use `Map` but for the sake of simplicity I'm using two separate `List`.
final List<int> _list = List.generate(20, (i) => i);
final List<bool> _selected = List.generate(20, (i) => false); // Fill it with false initially
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemBuilder: (_, i) {
return ListTile(
tileColor: _selected[i] ? Colors.blue : null, // If current item is selected show blue color
title: Text('Item ${_list[i]}'),
onTap: () => setState(() => _selected[i] = !_selected[i]), // Reverse bool value
);
},
),
);
}
Solution 3 - Flutter
If you also need an onTap
listener with a ripple effect, you can use Ink
:
ListView(
children: [
Ink(
color: Colors.lightGreen,
child: ListTile(
title: Text('With lightGreen background'),
onTap() { },
),
),
],
);
Solution 4 - Flutter
It's not ListTile
that has the style
property. But ListTileTheme
.
ListTileTheme
is an inheritedWidget. And like others, it's used to pass down data (such as theme here).
To use it, you have to wrap any widget above your ListTile with a ListTileTheme
containing the desired values.
ListTile
will then theme itself depending on the closest ListTileTheme
instance.
Solution 5 - Flutter
Wrap ListTile
in an Ink
.
Ink(
color: isSelected ? Colors.blue : Colors.transparent,
child: ListTile(title: Text('hello')),
)
Solution 6 - Flutter
This is no more pain!
Now you can use tileColor
and selectedTileColor
property of ListTile
widget to achieve it.
Have a look at this Issue #61347 which got merged into master.
Solution 7 - Flutter
An easy way would be to store the initial index in a variable and then change the state of that variable whenever tapped.
ListView.builder(
shrinkWrap: true,
itemCount: 4,
itemBuilder: (context, index) {
return Container( //I have used container for this example. [not mandatory]
color: tappedIndex == index ? Colors.blue : Colors.grey,
child: ListTile(
title: Center(
child: Text('${index + 1}'),
),onTap:(){
setState((){
tappedIndex=index;
});
}));
})
full code:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyWidget(),
);
}
}
class MyWidget extends StatefulWidget {
@override
MyWidgetState createState() => MyWidgetState();
}
class MyWidgetState extends State<MyWidget> {
late int tappedIndex;
@override
void initState() {
super.initState();
tappedIndex = 0;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ListView.builder(
shrinkWrap: true,
itemCount: 4,
itemBuilder: (context, index) {
return Container(
color: tappedIndex == index ? Colors.blue : Colors.grey,
child: ListTile(
title: Center(
child: Text('${index + 1}'),
),onTap:(){
setState((){
tappedIndex=index;
});
}));
})
]));
}
}
Dartpad link: https://dartpad.dev/250ff453b97cc79225e8a9c657dffc8a
Solution 8 - Flutter
I know that the original question has been answered, but I wanted to add how to set the color of ListTile
while the tile is being pressed. The property you are looking for is called highlight color
and it can be set by wrapping the ListTile
in a Theme
widget, like this:
Theme(
data: ThemeData(
highlightColor: Colors.red,
),
child: ListTile(...),
)
);
Note: if the Theme
widget resets the font of text elements inside the ListTile
, just set its fontFamily
property to the same value You used in other places in your app.
Solution 9 - Flutter
Unfortunately, ListTile doesn't have background-color property. Hence, we have to simply wrap the ListTile widget into a Container/Card widget and then we can use its color property. Further, We have to provide SizedBox widget with some height to separate the same colored ListTiles.
I am sharing that worked for me :)
I hope it will definitely help you.
Screenshot: see how it works
return
ListView(
children: snapshot.data.documents.map((doc) {
return Column(children: [
Card(
color: Colors.grey[200],
child: ListTile(
leading: Icon(Icons.person),
title: Text(doc.data['coursename'], style: TextStyle(fontSize: 22),),
subtitle: Text('Price: ${doc.data['price']}'),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () async {
await Firestore.instance
.collection('courselist')
.document(doc.documentID)
.delete();
},
),
),
),
SizedBox(height: 2,)
],);
}).toList(),[enter image description here][1]
);
Solution 10 - Flutter
I have used as
ListTile(
title: Text('Receipts'),
leading: Icon(Icons.point_of_sale),
tileColor: Colors.blue,
),
Solution 11 - Flutter
There are two props: tileColor and selectedTileColor.
tileColor
- when the tile/row is Not selected;
selectedTileColor
- when the tile/row is selected
ListTile(
selected: _isSelected,
tileColor: Colors.blue,
selectedTileColor: Colors.greenAccent,
)
Solution 12 - Flutter
I was able to change the Background Color of ListTile by making it a child of Container Widget and adding color to the Container Widget.
Here drawerItem is the model class which holds the isSelected value. Color of background depends on isSelected value.
Note: For unselected items keep the color Transparent so you will still get the ripple effect.
for (var i = 0; i < drawerItems.length; i++) {
var drawerItem = drawerItems[i];
drawerOptions.add(new Container(
color: drawerItem.isSelected
? Colors.orangeAccent
: Colors.transparent,
child: new ListTile(
title: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[Text(drawerItem.title), drawerItem.count],
),
leading: SvgPicture.asset(
drawerItem.icon,
width: 34,
height: 34,
),
onTap: () {
_handleNavigation(i);
},
selected: drawerItem.isSelected,
),
));
}
Solution 13 - Flutter
Your answer has been answered in Github.
Card(
color: Colors.white,
shape: ContinuousRectangleBorder(
borderRadius: BorderRadius.zero,
),
borderOnForeground: true,
elevation: 0,
margin: EdgeInsets.fromLTRB(0,0,0,0),
child: ListTile(
// ...
),
)
Solution 14 - Flutter
enter image description here>Make variable
int slectedIndex;
>on tap
onTap:(){
setState(() {
selectedIndex=index;
})
>Tile property
color:selectedIndex==index?Colors.red :Colors.white,
>Same As in List View Builder
ListView.builder(
itemCount: 10,
scrollDirection:Axis.vertical,
itemBuilder: (context,index)=>GestureDetector(
onTap:(){
setState(() {
selectedIndex=index;
});
} ,
child: Container(
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color:selectedIndex==index?Colors.red :Colors.white,
),)