Skip to content

Instantly share code, notes, and snippets.

@b-cancel
Last active July 8, 2018 06:50
Show Gist options
  • Save b-cancel/86caf699eb87d39aa18bab90ffee7e8b to your computer and use it in GitHub Desktop.
Save b-cancel/86caf699eb87d39aa18bab90ffee7e8b to your computer and use it in GitHub Desktop.
FLUTTER => Using Widget Sizes to calculate the Sizes of other widgets Automatically Or Manually
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,
),
),
],
)
);
}
}
@b-cancel
Copy link
Author

b-cancel commented Jul 3, 2018

Working Example (manual setting)

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