I have a simple widget called a LineBox
that changes the background color of a Container
when the mouse hovers over it using a MouseRegion
. However, this appears to be very inefficient as it requires Flutter to rebuild this widget as well as each of its children whenever the hovered state is changed, which will be a problem in the future as I intend to have many of these together in a Column
. The main issue with this approach arises when I place another stateful widget inside of the LineBox
– everything resets its state if the mouse moves outside of the box. My code is below:
class LineBox extends StatefulWidget {
final Widget? child;
final double indent;
const LineBox({
super.key,
this.child,
this.indent = 0,
});
@override
State<LineBox> createState() => _LineBoxState();
}
class _LineBoxState extends State<LineBox> {
var _hovered = false;
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (event) => setState((){
_hovered = true;
}),
onExit: (event) => setState((){
_hovered = false;
}),
child: Container(
color: _hovered ? Colors.red : null,
height: 40.0,
padding: EdgeInsets.only(left: widget.indent),
child: widget.child,
),
);
}
}
So far, I’ve tried stacking the LineBox
below its child with a Stack
, but this means the MouseRegion
triggers the onExit
event whenever the mouse moves over the child. I also tried wrapping the child widget in a KeyedSubtree
with a UniqueKey
, which does nothing.
2
Answers
You can try to separate the background container from its children in this way:
I think, and it could be wrong, but there is just one case when
LineBox
will be rebuild and child not:As child is
const
, there will no rebuild for this child widget.