Flutter 布局: SizedOverflowBox、Transform、CustomSingleChildLayout

SizedOverflowBox(控制大小和超出父view的盒子布局)

SizedOverflowBox主要的布局行为有两点:

  • 尺寸部分。通过将自身的固定尺寸,传递给child,来达到控制child尺寸的目的;
  • 超出部分。可以突破父节点尺寸的限制,超出部分也可以被渲染显示,与OverflowBox类似。

-属性

const SizedOverflowBox({
  Key key,
  @required this.size,//固定尺寸
  this.alignment = Alignment.center//对齐方式,
  Widget child,
})
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'TableView',
      theme: new ThemeData(
        primaryColor: Colors.green,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('首页'),
        ),
        body: new Container(
        color: Colors.green,
        alignment: Alignment.topRight,
        width: 200.0,
        height: 200.0,
        child: SizedOverflowBox(
            size: Size(100.0, 300.0),
            child: Container(color: Colors.red, width: 200.0, height: 100.0,),
          ),
        ),
      ),
    );
  }
}

Transform(矩阵变换布局)

矩阵变换,可以对child做平移、旋转、缩放等操作。

  const Transform({
    Key key,
    @required this.transform,//一个4x4的矩阵。
    this.origin,//旋转点,相对于左上角顶点的偏移。默认旋转点事左上角顶点。
    this.alignment,//对齐方式
    this.transformHitTests = true,//点击区域是否也做相应的改变。默认为YES
    Widget child,
  })

Transform可参考


void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'TableView',
      theme: new ThemeData(
        primaryColor: Colors.green,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('首页'),
        ),
        body: Center(
          child: Transform(
          transform: Matrix4.rotationZ(0.3),
          child: Container(
              color: Colors.blue,
              width: 100.0,
              height: 100.0,
            ),
          ),
        ),
      ),
    );
  }
}

CustomSingleChildLayout

一个自定义的拥有单个子widget的布局widget

CustomSingleChildLayout提供了一个控制child布局的delegate,这个delegate可以控制这些因素:

  • 可以控制child的布局constraints;
  • 可以控制child的位置;
  • 在parent的尺寸不依赖于child的情况下,可以决定parent的尺寸。
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'TableView',
      theme: new ThemeData(
        primaryColor: Colors.green,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('首页'),
        ),
        body: Center(
          child:Container(
          color: Colors.blue,
          padding: const EdgeInsets.all(1.0),
          child: CustomSingleChildLayout(
          delegate: FixedSizeLayoutDelegate(Size(200.0, 200.0)),
          child: Container(
            color: Colors.red,
            width: 100.0,
            height: 300.0,
          ),
  ),
),
        ),
      ),
    );
  }
}

class FixedSizeLayoutDelegate extends SingleChildLayoutDelegate {
  FixedSizeLayoutDelegate(this.size);

  final Size size;

  @override
  Size getSize(BoxConstraints constraints) => size;

  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
    return new BoxConstraints.tight(size);
  }

  @override
  bool shouldRelayout(FixedSizeLayoutDelegate oldDelegate) {
    return size != oldDelegate.size;
  }
}

由于SingleChildLayoutDelegate是一个抽象类,我们需要单独写一个继承自它的delegate,来进行相关的布局操作。上面例子中是一个固定尺寸的布局。
参考
继承SingleChildLayoutDelegate必须实现的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值