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,),
);
}
ListTile(
tileColor: isSelected ? Colors.blue : null,
)
// 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
);
},
),
);
}
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')
)
)
]
)
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.
Wrap ListTile
in an Ink
.
Ink(
color: isSelected ? Colors.blue : Colors.transparent,
child: ListTile(title: Text('hello')),
)
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.
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
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.
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]
);
I have used as
ListTile(
title: Text('Receipts'),
leading: Icon(Icons.point_of_sale),
tileColor: Colors.blue,
),
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,
)
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,
),
));
}
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(
// ...
),
)
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,
),)
Use the Material widget with InkWell Widget then put inside it the ListTile as shown here in this example:
return Material(
color: Colors.white,
child: ListTile(
hoverColor: Colors.greenAccent,
onLongPress: longPressCallback,
title: Text(
'$taskTitle',
style: TextStyle(
decoration: isChecked
? TextDecoration.lineThrough
: TextDecoration.none),
),
trailing: Checkbox(
activeColor: Colors.lightBlueAccent,
value: isChecked,
onChanged: checkboxCallback)),
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.