Created
February 2, 2025 23:25
-
-
Save callmephil/c859dbdff6b5c886eb7310a0995ce561 to your computer and use it in GitHub Desktop.
widget_rebuild_evaluation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter/rendering.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatefulWidget { | |
const MyApp({super.key}); | |
@override | |
State<MyApp> createState() => _MyAppState(); | |
} | |
class _MyAppState extends State<MyApp> { | |
int buildIndex = 0; | |
ColoredBox2 get colorboxConst { | |
print('method const: $hashCode'); | |
return const ColoredBox2(key: ValueKey('method const'), color: Colors.red); | |
} | |
ColoredBox2 get colorboxConst2 { | |
print('method not const: $hashCode'); | |
return ColoredBox2(key: ValueKey('method not const'), color: Colors.red); | |
} | |
@override | |
Widget build(BuildContext context) { | |
print('========= $buildIndex =========='); | |
print('Parent: $hashCode'); | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Column(children: [ | |
colorboxConst, | |
colorboxConst2, | |
ColoredBox2(key: ValueKey('not const'), color: Colors.red), | |
const ColoredBox2(key: ValueKey('const'), color: Colors.red), | |
RepaintBoundary( | |
child: TextButton( | |
onPressed: () { | |
setState(() { | |
buildIndex = buildIndex + 1; | |
}); | |
}, | |
child: Text('Update'), | |
), | |
), | |
]), | |
), | |
); | |
} | |
} | |
class ColoredBox2 extends SingleChildRenderObjectWidget { | |
/// Creates a widget that paints its area with the specified [Color]. | |
const ColoredBox2({required this.color, super.child, super.key}); | |
/// The color to paint the background area with. | |
final Color color; | |
@override | |
RenderObject createRenderObject(BuildContext context) { | |
print('Create $key ${context.widget.hashCode}'); | |
return _RenderColoredBox(color: color); | |
} | |
@override | |
void updateRenderObject(BuildContext context, RenderObject renderObject) { | |
print('update $key ${context.widget.hashCode}'); | |
(renderObject as _RenderColoredBox).color = color; | |
} | |
@override | |
void debugFillProperties(DiagnosticPropertiesBuilder properties) { | |
super.debugFillProperties(properties); | |
properties.add(DiagnosticsProperty<Color>('color', color)); | |
} | |
} | |
class _RenderColoredBox extends RenderProxyBoxWithHitTestBehavior { | |
_RenderColoredBox({required Color color}) | |
: _color = color, | |
super(behavior: HitTestBehavior.opaque); | |
/// The fill color for this render object. | |
Color get color => _color; | |
Color _color; | |
set color(Color value) { | |
if (value == _color) { | |
return; | |
} | |
_color = value; | |
markNeedsPaint(); | |
} | |
@override | |
void paint(PaintingContext context, Offset offset) { | |
print('paint: ${context.hashCode}'); | |
// It's tempting to want to optimize out this `drawRect()` call if the | |
// color is transparent (alpha==0), but doing so would be incorrect. See | |
// https://github.com/flutter/flutter/pull/72526#issuecomment-749185938 for | |
// a good description of why. | |
if (size > Size.zero) { | |
context.canvas.drawRect(offset & size, Paint()..color = color); | |
} | |
if (child != null) { | |
context.paintChild(child!, offset); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment