| // 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. |
| |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/rendering.dart'; |
| |
| import '../rendering/src/solid_color_box.dart'; |
| |
| // Solid color, RenderObject version |
| void addFlexChildSolidColor(RenderFlex parent, Color backgroundColor, { int flex = 0 }) { |
| final RenderSolidColorBox child = RenderSolidColorBox(backgroundColor); |
| parent.add(child); |
| final FlexParentData childParentData = child.parentData! as FlexParentData; |
| childParentData.flex = flex; |
| } |
| |
| // Solid color, Widget version |
| class Rectangle extends StatelessWidget { |
| const Rectangle(this.color, { super.key }); |
| |
| final Color color; |
| |
| @override |
| Widget build(BuildContext context) { |
| return Expanded( |
| child: Container( |
| color: color, |
| ), |
| ); |
| } |
| } |
| |
| double? value; |
| RenderObjectToWidgetElement<RenderBox>? element; |
| void attachWidgetTreeToRenderTree(RenderProxyBox container) { |
| element = RenderObjectToWidgetAdapter<RenderBox>( |
| container: container, |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: SizedBox( |
| height: 300.0, |
| child: Column( |
| mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| children: <Widget>[ |
| const Rectangle(Color(0xFF00FFFF)), |
| Material( |
| child: Container( |
| padding: const EdgeInsets.all(10.0), |
| margin: const EdgeInsets.all(10.0), |
| child: Row( |
| mainAxisAlignment: MainAxisAlignment.spaceAround, |
| children: <Widget>[ |
| ElevatedButton( |
| child: Row( |
| children: <Widget>[ |
| Image.network('https://flutter.dev/images/favicon.png'), |
| const Text('PRESS ME'), |
| ], |
| ), |
| onPressed: () { |
| value = value == null ? 0.1 : (value! + 0.1) % 1.0; |
| attachWidgetTreeToRenderTree(container); |
| }, |
| ), |
| CircularProgressIndicator(value: value), |
| ], |
| ), |
| ), |
| ), |
| const Rectangle(Color(0xFFFFFF00)), |
| ], |
| ), |
| ), |
| ), |
| ).attachToRenderTree(WidgetsBinding.instance.buildOwner!, element); |
| } |
| |
| Duration? timeBase; |
| late RenderTransform transformBox; |
| |
| void rotate(Duration timeStamp) { |
| timeBase ??= timeStamp; |
| final double delta = (timeStamp - timeBase!).inMicroseconds.toDouble() / Duration.microsecondsPerSecond; // radians |
| |
| transformBox.setIdentity(); |
| transformBox.rotateZ(delta); |
| |
| WidgetsBinding.instance.buildOwner!.buildScope(element!); |
| } |
| |
| void main() { |
| final WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized(); |
| final RenderProxyBox proxy = RenderProxyBox(); |
| attachWidgetTreeToRenderTree(proxy); |
| |
| final RenderFlex flexRoot = RenderFlex(direction: Axis.vertical); |
| addFlexChildSolidColor(flexRoot, const Color(0xFFFF00FF), flex: 1); |
| flexRoot.add(proxy); |
| addFlexChildSolidColor(flexRoot, const Color(0xFF0000FF), flex: 1); |
| |
| transformBox = RenderTransform(child: flexRoot, transform: Matrix4.identity(), alignment: Alignment.center); |
| final RenderPadding root = RenderPadding(padding: const EdgeInsets.all(80.0), child: transformBox); |
| |
| binding.renderView.child = root; |
| binding.addPersistentFrameCallback(rotate); |
| } |