Changes WidgetInspector to use valuenotifier instead of a force rebuild for (#131634)

![](https://media.giphy.com/media/qriH9W51oLsL6/giphy.gif)
Fixes https://github.com/flutter/devtools/issues/6014

Change the forceRebuild behaviour of the WidgetInspector to use
ValueListenableBuilders instead. This should help resolve heavy rebuilds
when the widgetInspectorOverride value changes.
This commit is contained in:
Daniel Chevalier 2023-10-13 17:07:57 -04:00 committed by GitHub
parent be45c4ca41
commit ac095ed393
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 15 deletions

View file

@ -31,6 +31,7 @@ import 'shortcuts.dart';
import 'tap_region.dart';
import 'text.dart';
import 'title.dart';
import 'value_listenable_builder.dart';
import 'widget_inspector.dart';
export 'dart:ui' show Locale;
@ -1189,13 +1190,22 @@ class WidgetsApp extends StatefulWidget {
/// If true, forces the widget inspector to be visible.
///
/// Overrides the `debugShowWidgetInspector` value set in [WidgetsApp].
///
/// Used by the `debugShowWidgetInspector` debugging extension.
///
/// The inspector allows you to select a location on your device or emulator
/// The inspector allows the selection of a location on your device or emulator
/// and view what widgets and render objects associated with it. An outline of
/// the selected widget and some summary information is shown on device and
/// more detailed information is shown in the IDE or DevTools.
static bool debugShowWidgetInspectorOverride = false;
static bool get debugShowWidgetInspectorOverride {
return _debugShowWidgetInspectorOverrideNotifier.value;
}
static set debugShowWidgetInspectorOverride(bool value) {
_debugShowWidgetInspectorOverrideNotifier.value = value;
}
static final ValueNotifier<bool> _debugShowWidgetInspectorOverrideNotifier = ValueNotifier<bool>(false);
/// If false, prevents the debug banner from being visible.
///
@ -1743,12 +1753,19 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
}
assert(() {
if (widget.debugShowWidgetInspector || WidgetsApp.debugShowWidgetInspectorOverride) {
result = WidgetInspector(
selectButtonBuilder: widget.inspectorSelectButtonBuilder,
child: result,
);
}
result = ValueListenableBuilder<bool>(
valueListenable: WidgetsApp._debugShowWidgetInspectorOverrideNotifier,
builder: (BuildContext context, bool debugShowWidgetInspectorOverride, Widget? child) {
if (widget.debugShowWidgetInspector || debugShowWidgetInspectorOverride) {
return WidgetInspector(
selectButtonBuilder: widget.inspectorSelectButtonBuilder,
child: child!,
);
}
return child!;
},
child: result,
);
if (widget.debugShowCheckedModeBanner && WidgetsApp.debugAllowBannerOverride) {
result = CheckedModeBanner(
child: result,

View file

@ -1078,11 +1078,10 @@ mixin WidgetInspectorService {
name: WidgetInspectorServiceExtensions.show.name,
getter: () async => WidgetsApp.debugShowWidgetInspectorOverride,
setter: (bool value) {
if (WidgetsApp.debugShowWidgetInspectorOverride == value) {
return Future<void>.value();
if (WidgetsApp.debugShowWidgetInspectorOverride != value) {
WidgetsApp.debugShowWidgetInspectorOverride = value;
}
WidgetsApp.debugShowWidgetInspectorOverride = value;
return forceRebuild();
return Future<void>.value();
},
registerExtension: registerExtension,
);

View file

@ -4115,6 +4115,28 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
testWidgetsWithLeakTracking('ext.flutter.inspector.show', (WidgetTester tester) async {
final Iterable<Map<Object, Object?>> extensionChangedEvents = service.getServiceExtensionStateChangedEvents('ext.flutter.inspector.show');
Map<Object, Object?> extensionChangedEvent;
int debugShowChangeCounter = 0;
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
WidgetsApp(
key: key,
builder: (BuildContext context, Widget? child) {
return const Placeholder();
},
color: const Color(0xFF123456),
),
);
final ValueListenableBuilder<bool> valueListenableBuilderWidget = tester.widget(
find.byType(ValueListenableBuilder<bool>),
);
void debugShowWidgetInspectorOverrideCallback() {
debugShowChangeCounter++;
}
WidgetsApp.debugShowWidgetInspectorOverride = false;
valueListenableBuilderWidget.valueListenable.addListener(debugShowWidgetInspectorOverrideCallback);
service.rebuildCount = 0;
expect(extensionChangedEvents, isEmpty);
@ -4129,7 +4151,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], equals('ext.flutter.inspector.show'));
expect(extensionChangedEvent['value'], isTrue);
expect(service.rebuildCount, equals(1));
expect(service.rebuildCount, equals(0)); // Should not be force rebuilt.
expect(debugShowChangeCounter, equals(1));
expect(
await service.testBoolExtension(
WidgetInspectorServiceExtensions.show.name,
@ -4139,6 +4162,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
);
expect(WidgetsApp.debugShowWidgetInspectorOverride, isTrue);
expect(extensionChangedEvents.length, equals(1));
expect(service.rebuildCount, equals(0)); // Should not be force rebuilt.
expect(debugShowChangeCounter, equals(1));
expect(
await service.testBoolExtension(
WidgetInspectorServiceExtensions.show.name,
@ -4150,7 +4175,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], equals('ext.flutter.inspector.show'));
expect(extensionChangedEvent['value'], isTrue);
expect(service.rebuildCount, equals(1));
expect(service.rebuildCount, equals(0)); // Should not be force rebuilt.
expect(debugShowChangeCounter, equals(1));
expect(
await service.testBoolExtension(
WidgetInspectorServiceExtensions.show.name,
@ -4162,6 +4188,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
extensionChangedEvent = extensionChangedEvents.last;
expect(extensionChangedEvent['extension'], equals('ext.flutter.inspector.show'));
expect(extensionChangedEvent['value'], isFalse);
expect(service.rebuildCount, equals(0)); // Should not be force rebuilt.
expect(debugShowChangeCounter, equals(2));
expect(
await service.testBoolExtension(
WidgetInspectorServiceExtensions.show.name,
@ -4170,7 +4198,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
equals('false'),
);
expect(extensionChangedEvents.length, equals(3));
expect(service.rebuildCount, equals(2));
expect(service.rebuildCount, equals(0)); // Should not be force rebuilt.
expect(debugShowChangeCounter, equals(2));
expect(WidgetsApp.debugShowWidgetInspectorOverride, isFalse);
});