这显示了这篇文章中讨论的所有3个案例,并附有一个简单的例子。 How to use the constraints and sizes of other widgets during the build phase
注:
我知道这很奇怪
我知道如果使用不当,可能会创建从未绘制过的布局
仅仅阅读约束是不够的,因为有时约束不存在(就像在这种特殊情况下)
目标: 获取屏幕上绘制的内容,以便在0 ReBuilds(或1 build)之后稳定,而不是2 ReBuilds
当前流程:
when(“automaticReBuilding”== true)=>系统根据依赖的数量自动重建(这由您决定) [自动重建多次运行构建函数的事实是我现在和以前的帖子中提到的口吃问题]
when(“automaticReBuilding”== false)=>系统等待您手动重建事物
// --------------------------------------------- -----代码开始
import 'package:flutter/material.dart';
import 'dart:async';
//Desired Behavior on FIRST build (It should not take 3)
//CASE 1 (parent uses child size) : eye.width = vane.width * 10
//CASE 2 (child uses parent size) : pupil.width = iris.width / 2
//CASE 3: (child uses sibling size) : iris.width = vane.width * 5
//Desired Sizes (can be read from Render Tree in Flutter Inspector) [in original config of 4 letters]
//vane = 30
//pupil = 75
//iris = 150
//eye = 300
//NOTE: that vane width (aka size) is not determined until we see what is inside of it
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new StateFull();
}
}
class StateFull extends StatefulWidget {
@override
_StateFullState createState() => new _StateFullState();
}
var vaneKey = new GlobalKey();
var vaneWidth;
var irisKey = new GlobalKey();
var irisWidth;
class _StateFullState extends State<StateFull> {
//NOTE: change this to either run the rebuild in one shot or slowly see the progression
bool automaticReBuilding = false;
//NOTE: this starts here because the first build method isn't technically a rebuild
int timesReBuilt = -1;
//NOTE: this is set MANUALLY given the dependencies between your widgets
//In this particular case C relies on B which relies on A
//so (first) I get the size of A, (second) I use the size of A to get B, (third) i use the size of B to get C
//which comes down to 3 rebuilds
int requiredBuildsPerChange = 3;
int timesBuilt = 0;
rebuild(){
setState(() {
});
}
rebuildAsync() async{
await Future.delayed(Duration.zero);
setState(() {
});
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
timesReBuilt++;
if(automaticReBuilding){
timesBuilt++;
print("build #" + timesBuilt.toString());
if(timesBuilt < requiredBuildsPerChange)
rebuildAsync();
else
timesBuilt = 0;
}
var complexWidget = complexRelationshipWidget();
return new MaterialApp(
title: '3 Cases Test',
home: new Scaffold(
backgroundColor: Colors.brown,
body: new Stack(
children: <Widget>[
new Align(
alignment: Alignment.center,
child: complexWidget,
),
new Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.bottomRight,
child: new RaisedButton(
onPressed: () => (automaticReBuilding == false) ? rebuild() : null,
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.update),
new Text("Manual ReBuilds\nOR\nAutomatic Frame Stutter\n$timesReBuilt", textAlign: TextAlign.center,),
],
),
),
),
],
)
),
);
}
Container complexRelationshipWidget() {
vaneWidth = vaneKey?.currentContext?.findRenderObject()?.semanticBounds?.size?.width;
irisWidth = irisKey?.currentContext?.findRenderObject()?.semanticBounds?.size?.width;
return new Container( //-----EYE-----
decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.white),
width: vaneWidth == null ? null : vaneWidth * 10,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container( //-----VANE-----
key: vaneKey,
color: Colors.red,
child: new Text("vane"),
),
new Container( //-----IRIS-----
key: irisKey,
decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.blue),
width: vaneWidth == null ? null : vaneWidth * 5,
alignment: Alignment.center,
child: new Container( //-----PUPIL
decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.black),
width: irisWidth == null ? null : irisWidth / 2,
),
),
],
)
);
}
}
// --------------------------------------------- -----代码结束