// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Template: dev/snippets/config/templates/freeform.tmpl // // Comment lines marked with "▼▼▼" and "▲▲▲" are used for authoring // of samples, and may be ignored if you are just exploring the sample. // Flutter code sample for BuildOwner // //*************************************************************************** //* ▼▼▼▼▼▼▼▼ description ▼▼▼▼▼▼▼▼ (do not modify or remove section marker) // This example shows how to build an off-screen widget tree used to measure // the layout size of the rendered tree. For some use cases, the simpler // [Offstage] widget may be a better alternative to this approach. //* ▲▲▲▲▲▲▲▲ description ▲▲▲▲▲▲▲▲ (do not modify or remove section marker) //*************************************************************************** //**************************************************************************** //* ▼▼▼▼▼▼▼▼ code-imports ▼▼▼▼▼▼▼▼ (do not modify or remove section marker) import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; //* ▲▲▲▲▲▲▲▲ code-imports ▲▲▲▲▲▲▲▲ (do not modify or remove section marker) //**************************************************************************** //******************************************************************** //* ▼▼▼▼▼▼▼▼ code ▼▼▼▼▼▼▼▼ (do not modify or remove section marker) void main() { WidgetsFlutterBinding.ensureInitialized(); final Size size = measureWidget(const SizedBox(width: 640, height: 480)); // Just displays the size calculated above. runApp( WidgetsApp( title: 'BuildOwner Sample', color: const Color(0xff000000), builder: (BuildContext context, Widget? child) { return Scaffold( body: Center( child: Text(size.toString()), ), ); }, ), ); } Size measureWidget(Widget widget) { final PipelineOwner pipelineOwner = PipelineOwner(); final MeasurementView rootView = pipelineOwner.rootNode = MeasurementView(); final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager()); final RenderObjectToWidgetElement element = RenderObjectToWidgetAdapter( container: rootView, debugShortDescription: '[root]', child: widget, ).attachToRenderTree(buildOwner); try { rootView.scheduleInitialLayout(); pipelineOwner.flushLayout(); return rootView.size; } finally { // Clean up. element.update(RenderObjectToWidgetAdapter(container: rootView)); buildOwner.finalizeTree(); } } class MeasurementView extends RenderBox with RenderObjectWithChildMixin { @override void performLayout() { assert(child != null); child!.layout(const BoxConstraints(), parentUsesSize: true); size = child!.size; } @override void debugAssertDoesMeetConstraints() => true; } //* ▲▲▲▲▲▲▲▲ code ▲▲▲▲▲▲▲▲ (do not modify or remove section marker) //********************************************************************