堆栈:用顶部孩子覆盖底部孩子

Posted

技术标签:

【中文标题】堆栈:用顶部孩子覆盖底部孩子【英文标题】:Stack: cover bottom child with top child 【发布时间】:2020-12-21 08:29:04 【问题描述】:

我想在底部小部件上覆盖一个小部件以隐藏它。因此我使用堆栈。我不知道底部小部件的大小,所以我不能给顶部小部件固定大小。

我有什么:

我想要达到的目标:

Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      Text(
        'Winner: ',
        style: TextStyle(fontSize: 34),
      ),
      Stack(
        children: [
          Text('YOU!!!', style: TextStyle(fontSize: 34)),
          Container(
            color: Colors.amber,
          )
        ],
      ),
    ],
  ),

这是我想要实现的简化版本。我必须使用 Row 并假设 Texts 是任何大小的任何小部件。

堆栈根据从父级接收到的约束来调整其子级的大小,而不是基于子级的大小。

如何用底部小部件的确切尺寸覆盖顶部小部件?

【问题讨论】:

this 有帮助吗? 我想我必须编写自定义 RenderObject 来根据底部孩子计算顶部孩子的大小 【参考方案1】:

要知道widget 的大小并根据此应用事物,您可以像GlobalKey key; 这样使用 GlobalKey。在你的 initSate 中初始化它并听它的大小

GlobalKey key;
double yourWidgetWidth;
double yourWidgetHeight;

@override
initState() 
   // .... other stuffs
   
   key = GlobalKey();

   WidgetsBinding.instance.addPostFrameCallback((_) 
      if (mounted) 
         yourWidgetWidth = containerKey.currentContext.size.width;
         yourWidgetHeight = containerKey.currentContext.size.height;
      
   );

通过yourWidgetWidthyourWidgetHeight,你可以实现你想要的

编辑 这是我试图解释的概念

// In variable declaration scope
GlobalKey youTextKey = GlobalKey();
ValueNotifier widthNotifier = ValueNotifier(0);
ValueNotifier heightNotifier = ValueNotifier(0);

// In initState
WidgetsBinding.instance.addPostFrameCallback((_) 
  if (mounted) 
    widthNotifier.value = youTextKey.currentContext.size.width - 1.0;
    heightNotifier.value = youTextKey.currentContext.size.height - 5.0;
  
);

// Your row
Row(
  crossAxisAlignment: CrossAxisAlignment.start,
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    Text(
      'Winner: ',
      style: TextStyle(fontSize: 34),
    ),
    Stack(
      children: [
        Text('YOU!!!', style: TextStyle(fontSize: 34), key: youTextKey,),
        ValueListenableBuilder(
          valueListenable: widthNotifier,
          builder: (context, width, _) 
            return ValueListenableBuilder(
              valueListenable: heightNotifier,
              builder: (context, height, _) 
                return Container(
                  width: width,
                  height: height,
                  color: Colors.amber,
                );
              ,
            );
          ,
        ),
      ],
    ),
  ],
)

【讨论】:

我必须对小部件进行布局才能知道它们的大小。所以它没有帮助。此外,我正在寻找声明性方式而不是命令式方式。 我过去遇到过这种事情。也许你可以检查我的新编辑 感谢贡献,看答案【参考方案2】:

使用Positioned.Fill 解决了这个问题:

Positioned.Fill 创建一个定位对象,将 [left]、[top]、[right] 和 [bottom] 设置为 0.0,除非传递了它们的值。 所以定位的孩子会被拉伸到堆栈最大孩子的边缘。

Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      Text(
        'Winner: ',
        style: TextStyle(fontSize: 34),
      ),
      Stack(
        children: [
          Text('YOU!!!', style: TextStyle(fontSize: 34)),
          Positioned.fill(
            child: Container(
              color: Colors.amber,
            ),
          )
        ],
      ),
    ],
  ),

【讨论】:

确实这样更有效率!

以上是关于堆栈:用顶部孩子覆盖底部孩子的主要内容,如果未能解决你的问题,请参考以下文章

孩子与其父母之间的边距顶部[重复]

为啥容器在侧面同时从顶部和底部调整大小,以及同时向左和向右调整?

android 如何让UI顶部和底部固定

Flutter Container 不需要的顶部和底部填充

如何使用 SwiftUI 将 Stacks 固定在顶部和底部

如何将 UILabel 文本顶部和底部空间居中