There is a Wrap widget in the app with a list of ElevatedButtons, the autofocus on the first one is set to true. All the buttons have the same overlayColor. The autofocus doest seem to work. I’ve verified this by adding a listener to the FocusManager.
[log] focus: FocusNode#b5f2b([PRIMARY FOCUS])(context: Focus, PRIMARY FOCUS)
[log] focus: FocusNode#e4580([PRIMARY FOCUS])(context: Focus, PRIMARY FOCUS)
[log] focus: FocusNode#b5f2b([PRIMARY FOCUS])(context: Focus, PRIMARY FOCUS)
The first focus event is the autofocus, but the widget has no overlayColor or any focus effect. Going, right and then left brings the focus back to the only autofocus widget and this time with all focus effects.
Internally, the overlayEffect comes from the WidgetStateProperty<Color?> object. I setup a custom implementation to track the state changes.
@immutable
class StateDependentColor extends WidgetStateProperty<Color?> {
StateDependentColor(this.color);
final Color color;
@override
Color? resolve(Set<WidgetState> states) {
if (states.contains(WidgetState.pressed)) {
return color.withOpacity(0.1);
}
if (states.contains(WidgetState.hovered)) {
return color.withOpacity(0.08);
}
if (states.contains(WidgetState.focused)) {
return color.withOpacity(0.5);
}
return null;
}
}
This is applied to the button like.
child: ElevatedButton(
autofocus: true,
style: ElevatedButton.styleFrom(
alignment: Alignment.center,
backgroundColor: Colors.red,
foregroundColor: Colors.white,
).copyWith(
overlayColor: StateDependentColor(Colors.white),
),
onPressed: () {},
child: Text("Click")
)
The resolve method is not getting called at startup. Some people have recommended using a focusNode instead of autofocus. Tried that and TBH it worked just once (strange), Never got it to work again.
I’m really out of ideas at this point. Any help/hints would be very helpful.
2
Answers
It turns out the issue is related to the highlight strategy used by flutter. First the fix:
The root cause can be traced to this method in
flutter/lib/src/widgets/focus_manager.dart
It turns out by default the highlight mode is assumed to be touch, which doesnt hightlight anything. Once an interaction takes place, TAB/Arrow keys the mode is adjusted to traditional. In traditional mode all focus effects are visible.
Now, I think, the code for
_defaultModeForPlatform
should include a way to determine Android TV platform, which it doesnt do right now.The fix is for the application to do it itself. Here is the working snippet
Hope this helps anyone else down the rabbit hole.
Try overlaycolor like below… Hope it helps