I’m using themes with light and dark color schemas in Flutter mobile app. It works fine in all Widgets except a ListWiev.separated. My code:
ListView.separated(
itemCount: itemsList.length,
separatorBuilder: (BuildContext context, int index) =>
const SizedBox(
height: 4.0,
),
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
Provider.of<PlayerManager>(context, listen: false)
.play(index: index);
},
child: SizedBox(
height: 48,
child: Card(
color: index.isEven
? Theme.of(context).colorScheme.surfaceVariant
: null,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 6.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
itemsList[index]
.number
.toString()
.padLeft(3),
style: Theme.of(context)
.textTheme
.displaySmall!
.copyWith(
color: Theme.of(context)
.colorScheme
.onSurfaceVariant),
),
const SizedBox(
width: 16,
),
SizedBox(
width: 282,
child: Text(itemsList[index].name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: Theme.of(context)
.textTheme
.displaySmall!
.copyWith(
color: Theme.of(context)
.colorScheme
.onSurfaceVariant)),
),
const SizedBox(
width: 8,
),
],
),
),
Provider.of<PlayerManager>(context)
.buttonState ==
ButtonState.playing &&
Provider.of<PlayerManager>(context)
.currentItemIndex ==
index
? Padding(
padding:
const EdgeInsets.only(right: 2.0),
child: MyAnimatedIcon(
icon: Icons.play_circle,
color: Theme.of(context)
.colorScheme
.primary,
backgroundColor: Theme.of(context)
.colorScheme
.primary
.withOpacity(0.7),
iconSize: 28,
animationMagnifier: 1.14,
),
)
: Padding(
padding:
const EdgeInsets.only(right: 8.0),
child: Icon(
Icons.play_arrow,
size: 24,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
),
),
],
),
),
),
);
}),
So, I tried with Provider:
Provider.of<ProfileManager>(context).darkMode ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.secondary
In fact, I needed something that returned the same color scheme regardless of whether dark mod was enabled, but both variants didn’t work.
Interestingly, the above code worked when I abandoned the color scheme and used specific colors e.g.:
Provider.of<ProfileManager>(context).darkMode ? Colors.yellow : Colors.blue
But this means giving up all the advantages of Color Scheme. I finally found the best solution: extract all the code from ItemBuilder into a separate widget:
ListView.separated(
itemCount: itemsList.length,
separatorBuilder: (BuildContext context, int index) =>
const SizedBox(
height: 4.0,
),
itemBuilder: (BuildContext context, int index) {
return ListItem(
item: itemsList[index],
index: index,
);
}),
And now, in my widget ItemsList, everything works as expected. I can use ColorScheme, e.g.:
color: Theme.of(context).colorScheme.onSurfaceVariant),
and a color changes when I change the theme from dark to light. But why does it work this way? Why doesn’t ColorScheme work directly in ListView?