根据另一个小部件的位置/大小来定位/调整小部件

根据另一个小部件的位置/大小来定位/调整小部件

问题描述:

我在Flutter中已经遇到了几次相当大的障碍。 动画或构建小部件,这取决于其他小部件以获得其大小/位置。根据另一个小部件的位置/大小来定位/调整小部件

几个例子可能是我最糟糕的噩梦: 动态显示彼此相邻的小部件。 在CSS中,我们不得不这样:

.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>

  • 父采用全宽(并不重要)。
  • 父母需要最大的孩子的高度。
  • 儿童用较小的高度拉伸以适应父
  • 儿童positionned紧挨彼此

在颤,我不认为我们可以同时把所有的4分。

现在如果我们有2个这样的列表和一个元素从一个列表移动到另一个列表的动画呢? 例如

enter image description hereenter image description here

又如。如果我们想要一个SlideTransition完成与另一个没有任何共同点的小部件垂直对齐,该怎么办? 像这样:

enter image description here

这些是完全随机的例子。我不需要重现完全一样的东西。 这里真正的问题是:是否有通用方式做类似的事情(获取屏幕大小/位置)?有些东西会而不是是特定于这个用例,并且以后会很容易维护吗?

要回答您的原始布局问题,您可以使用IntrinsicHeight小工具和CrossAxisAlignment.stretch一起完成此布局。它看起来像这样:

screenshot

下面的代码:

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'), 
        ], 
       ), 
       ), 
       ], 
      ), 
     ), 
     ), 
    ), 
    ); 
    } 
} 

要实现你的更先进的动画的例子,我会建议使用CustomMultiChildLayout来定位框。见画廊的animation demo使用这个类的一个先进的动画例如:

screenshot

+0

阿凉,不知道你可以使用'IntrinsicHeight'这样。另一方面,对于我展示的动画,“CustomChildLayout”将不起作用。不仅CustomChildLayout的大小不能在子节点上放置;但它仍然无法解决访问全球小部件的世界位置/大小的问题。 – Darky

+0

你在问很多问题,我想你应该考虑把它们分解成自己的Stack Overflow问题。如果你使用'MultiChildLayoutDelegate',你的小部件的大小将在'performLayout'中提供给你。你可以通过调用'layoutChild'来确定你的孩子的大小。如果你想获得'renderObject'的全局坐标,你可以使用['localToGlobal'](https://docs.flutter.io/flutter/rendering/RenderBox/localToGlobal.html),但如果你这样做, '可能违反了封装并且应该在更高级别实现自定义布局 –

+0

请注意,对于简单的使用情况,您可以使用'LayoutBuilder'来获取围绕窗口小部件的大小约束。不过,如果你实现'MultiChildLayoutDelegate',你不需要这个。 –