Skip to content

Instantly share code, notes, and snippets.

@aklehm
Created October 24, 2023 07:21
Show Gist options
  • Select an option

  • Save aklehm/cd2eb6462f85f6fabd07e660bd5f0ce1 to your computer and use it in GitHub Desktop.

Select an option

Save aklehm/cd2eb6462f85f6fabd07e660bd5f0ce1 to your computer and use it in GitHub Desktop.
Util to measure the size of a flutter widget before build.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
/// Small utility to measure a widget before actually putting it on screen.
///
/// This can be helpful e.g. for positioning context menus based on the size they will take up.
///
/// NOTE: Use sparingly, since this takes a complete layout and sizing pass for the subtree you
/// want to measure.
///
/// Compare https://api.flutter.dev/flutter/widgets/BuildOwner-class.html
/// Original code from https://stackoverflow.com/a/74701386/13869584
/// The measured widget must be a [Directionality] widget.
class MeasureUtil {
static Size measureWidget(Widget widget, [BoxConstraints constraints = const BoxConstraints()]) {
final PipelineOwner pipelineOwner = PipelineOwner();
final _MeasurementView rootView = pipelineOwner.rootNode = _MeasurementView(constraints);
final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());
final RenderObjectToWidgetElement<RenderBox> element = RenderObjectToWidgetAdapter<RenderBox>(
container: rootView,
debugShortDescription: '[root]',
child: widget,
).attachToRenderTree(buildOwner);
try {
rootView.scheduleInitialLayout();
pipelineOwner.flushLayout();
return rootView.size;
} finally {
// Clean up.
element.update(RenderObjectToWidgetAdapter<RenderBox>(container: rootView));
buildOwner.finalizeTree();
}
}
}
class _MeasurementView extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
final BoxConstraints boxConstraints;
_MeasurementView(this.boxConstraints);
@override
void performLayout() {
assert(child != null);
child!.layout(boxConstraints, parentUsesSize: true);
size = child!.size;
}
@override
void debugAssertDoesMeetConstraints() => true;
}
@GameDevGero
Copy link
Copy Markdown

Thank you so much man this is genius!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment