在Flutter中如何将Widget限制到另外两个Widget?

4sup72z8  于 2023-03-13  发布在  Flutter
关注(0)|答案(1)|浏览(160)

如何使一个Widget对同一容器中的另外两个Column具有约束(Column/Row)?
这是设计列表项时非常常见的情况。UI应该是可伸缩的(例如当最终用户手动增加字体大小时)。

我不接受任何硬编码数字的答案。只是逻辑链接。我也不接受任何第三方解决方案的答案。

以下是UI规范:

因此,要求如下:

  • Text可缩放小部件是主小部件,Icon通过将其垂直居中而受到约束
  • 同时,底部文本的起始左边缘被约束为Text左边缘

这是非常简单的解决与ConstraintLayout在Android.

vzgqcmou

vzgqcmou1#

在@pskink的帮助下,我尝试使用CustomMultiChildLayout。这不是一个简单的API,因为它直接与Size一起工作。因此,为了补偿文本可能增加高度(或跨越多行)的事实,我起草了以下解决方案:
(The Bottom Text已替换为Button Bar,但在布局同级Widget方面的要求相同)
文本大于图标时的结果:

文本小于图标时的结果:

下面是代码:

CustomMultiChildLayout(
          children: [
            LayoutId(
              id: _ICON,
              child: CustomIcon(),
            ),
            LayoutId(
              id: _TEXT,
              child: Text("<SOME_DYNAMIC_TEXT>"),
            ),
            LayoutId(
              id: _BUTTON_BAR,
              child: CustomButtonBar(),
            )
          ],
          delegate: _LayoutDelegate(),
        ),

识别号:

const int _ICON = 1;
const int _TEXT = 2;
const int _BUTTON_BAR = 3;

LayoutDelegate

class _LayoutDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    final Size iconSize = layoutChild(_ICON, BoxConstraints());
    // AppTheme.largeSpacing is predefined to 24.0
    final double iconPlusPaddingWidth = iconSize.width + AppTheme.largeSpacing;
    final Size textSize = layoutChild(
      _TEXT,
      BoxConstraints.tightFor(width: size.width - iconPlusPaddingWidth),
    );
    final Size buttonBarSize = layoutChild(_BUTTON_BAR, BoxConstraints());

    final double height = iconSize.height > textSize.height
        ? iconSize.height / 2
        : textSize.height / 2;

    final double startX = iconSize.width + AppTheme.largeSpacing;

    positionChild(
      _ICON,
      Offset(0, height - iconSize.height / 2),
    );
    positionChild(
      _TEXT,
      Offset(
        startX,
        height - textSize.height / 2,
      ),
    );
    positionChild(
      _BUTTON_BAR,
      Offset(
        startX,
        textSize.height + AppTheme.largeSpacing,
      ),
    );
  }

  @override
  bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) => false;
}

最后一点-当开发人员仍然需要通过变量计算大小并使用它们进行定位时,它并不是一个简单的API。

相关问题