Flutter 自定义布局控件使用总结

667 阅读1分钟

CustomSingleChildLayout

 Container(
        child: CustomSingleChildLayout(
          delegate: ChildLayoutDelegate(),
          child: Text("hello world"),
        ),
      )
      
      
///这个效果是居中的效果
class ChildLayoutDelegate extends SingleChildLayoutDelegate {
    ///
    ///[size] 父容器的尺寸
    ///[childSize] 自身的尺寸
    ///
    /// 默认返回的的是 [Offset.zero]
    ///
  @override
  Offset getPositionForChild(Size size, Size childSize) {
    var dx = (size.width - childSize.width) / 2;
    var dy = (size.height - childSize.height) / 2;
    return Offset(dx, dy);
  }

  @override
  bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) {
    return oldDelegate != this;
  }
}

CustomMultiChildLayout

Container(
        child: CustomMultiChildLayout(
          delegate: MutilChildDelegate(),
          children: <Widget>[
            LayoutId(id: "topId", child: Text("top text")),
            LayoutId(
              id: "bottomId",
              child: Text("bottom text"),
            )
          ],
        ),
      )
      
      class MutilChildDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    //判断是否存在目标id
    Size topSize;
    Size bottomSize;
    if (hasChild("topId")) {
      //测量child的尺寸;给一个限制的控件
      topSize = layoutChild("topId", BoxConstraints.loose(size));
    }
    if (hasChild("bottomId")) {
      bottomSize = layoutChild("bottomId", BoxConstraints.loose(size));
    }
    if (topSize != null && bottomSize != null) {
      var totalHeight = topSize.height + bottomSize.height;
      var tdy = (size.height - totalHeight) / 2;
      var tdx = (size.width - topSize.width) / 2;
      //设置孩子的位置
      positionChild("topId", Offset(tdx, tdy));
      var bdy = tdy + topSize.height;
      var bdx = (size.width - bottomSize.width) / 2;
      positionChild("bottomId", Offset(bdx, bdy));
      return;
    }

    if (topSize != null) {
      _positionCenter(size, topSize, "topId");
    }

    if (bottomSize != null) {
      _positionCenter(size, bottomSize, "bottomId");
    }
  }

  _positionCenter(Size size, Size childSize, String id) {
    var dx = (size.width - childSize.width) / 2;
    var dy = (size.height - childSize.height) / 2;
    positionChild(id, Offset(dx, dy));
  }

  @override
  bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) {
    return oldDelegate != this;
  }
}

Flow

Container(
        child: Flow(
          delegate: FlowLayoutDelegate(),
          children: <Widget>[
            Text("hello world 1"),
            Text("hello world 2"),
            Text("hello world 3"),
            Text("hello world 4")
          ],
        ),
      )
      
class FlowLayoutDelegate extends FlowDelegate {
  @override
  void paintChildren(FlowPaintingContext context) {
  //获取child的数量
    var childCount = context.childCount;
    Offset position = Offset.zero;
    for (int i = 0; i < childCount; i++) {
    //获取child的大小
      Size size = context.getChildSize(i);
      //绘制child到相应的位置
      context.paintChild(i,
          transform: Matrix4.translationValues(position.dx, position.dy, 0));
      position += Offset(size.width, size.height);
    }
  }

  @override
  bool shouldRepaint(FlowDelegate oldDelegate) {
    return oldDelegate != this;
  }
}