Positioning/Sizing a widget depending of the position/size of another widget

4,061

To answer your original layout question, you can accomplish this layout using the IntrinsicHeight widget together with CrossAxisAlignment.stretch. It looks like this:

screenshot

Here's the code:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Padding(
        padding: new EdgeInsets.all(10.0),
        child: new IntrinsicHeight(
          child: new Container(
            color: Colors.grey,
            padding: new EdgeInsets.all(4.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                new Container(
                  padding: new EdgeInsets.all(5.0),
                  margin: new EdgeInsets.only(right: 5.0),
                  color: Colors.grey[200],
                  child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      new Text('dynamic height'),
                      new Text('dynamic width'),
                      new Text('fat'),
                      new Text('super fat'),
                    ],
                  ),
                ),
                new Container(
                  padding: new EdgeInsets.all(5.0),
                  color: Colors.grey[200],
                  child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      new Text('dynamic width'),
                      new Text('dynamic height'),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

To implement your more advanced animation examples, I would recommend using CustomMultiChildLayout to position the boxes. See the Gallery's animation demo for an example of advanced animation using this class:

screenshot

Share:
4,061
Rémi Rousselet
Author by

Rémi Rousselet

Dart makes my heart Flutter Some interesting Flutter topics: https://medium.com/@darky12s/flutter-reducing-widgets-boilerplate-3e635f10685e Custom width/height property for a widget are ignored Controlling State from outside of a StatefulWidget What are Keys in the Stateless widgets class? What is the difference between functions and classes to create widgets? How to deal with unwanted widget build? Understanding Flutter Render Engine Navigator operation requested with a context that does not include a Navigator What is the relation between stateful and stateless widgets in Flutter? Passing Data to a Stateful Widget

Updated on December 03, 2022

Comments

  • Rémi Rousselet
    Rémi Rousselet over 1 year

    I faced a few times already a quite big wall in Flutter. Animating or building widgets, that depends on other widgets to get their size/position.

    A few examples of what could be my worst nightmares in a flutter : Snaping widgets next to each other dynamically. In css we'd have this :

    .root {
        display: flex;
        background: grey;
        padding: 4px;
    }
    .root > div {
      background: lightgrey;
      margin-right: 5px;
      padding: 5px;
    }
    <div class="root">
        <div>
             dynamic height
             <br/>
             dynamic width
             <br/>
             fat
             <br/>
             super fat
        </div>
        <div>
             dynamic width
             <br/>
             dynamic height
        </div>
    </div>
    • the parent takes the full width (not important).
    • the parent takes the height of the biggest children.
    • children with a smaller height stretch to fit the parent
    • children are positioned right next to each other

    In flutter, I don't think we can have all 4 points at once.

    And now what if we have 2 of this list and an animation where one element goes from one list to the other one? example

    enter image description here enter image description here

    Another example. What if we wanted to have a SlideTransition that finish vertically aligned with another widget that has nothing in common? Like this :

    enter image description here

    These are totally random examples. I don't need to reproduce the same thing. The real question here is: Is there a generic way to do something similar (get the screen size/position)? Something that will not be specific for this use case and will be easily maintainable later?

  • Rémi Rousselet
    Rémi Rousselet over 6 years
    Ah cool, didn't know you could use IntrinsicHeight like that. On the other hand, for the animations I showed, CustomChildLayout won't work. Not only CustomChildLayout's size can't depdends on children ; but it still won't solve the problem of accessing world position/size of a global widget.
  • Collin Jackson
    Collin Jackson over 6 years
    You are asking a lot of questions and I think you should probably consider splitting them into their own Stack Overflow questions. If you're using MultiChildLayoutDelegate the size of your widget is provided to you in performLayout. You can determine the size of your children by calling layoutChild. If you want to get the global coordinates of your renderObject you can use localToGlobal although if you're doing this you're probably violating encapsulation and should implement the custom layout at a higher level
  • Collin Jackson
    Collin Jackson over 6 years
    Note that for simple use cases, your can use LayoutBuilder to get the size constraints surrounding a widget. You won't need this if you're implementing MultiChildLayoutDelegate, though.
  • Rémi Rousselet
    Rémi Rousselet over 6 years
    Thanks but like I said, MultiChildLayout (aka CustomChildlayout) won't work. While you can get the children size inside performLayout, you won't be able to access to their size inside getSize.
  • Rémi Rousselet
    Rémi Rousselet over 6 years
    It is a violation of encapsulation. But there are no other solution for some animation, such as a Hero like. Let's say you want to translate visually an image inside the Scaffold body, to a cart icon inside the Scaffold AppBar. You don't have the choice.
  • Collin Jackson
    Collin Jackson over 6 years
    I would wrap the Scaffold in a Stack if you want to achieve that effect. That way you have full control over the positioning of the elements that appear on top of the Scaffold.
  • Collin Jackson
    Collin Jackson over 6 years
    If you run up against limitations of what you can do with existing box and sliver widgets, another option is to pop down a layer and implement custom logic at the render tree level. This will involve writing more code but it will give you more fine grained control over things.
  • Rémi Rousselet
    Rémi Rousselet over 6 years