flutter RenderObject中parentUsesS

2020-03-03  本文已影响0人  liboxiang

测试代码

double SizeOne = 30;
double SizeTwo = 30;
Column(
          children: <Widget>[
            CustomConstrainedBox(
              child: StatefulBuilder(builder: (_, refresh) {
                return Tint(
                  color: Colors.yellow,
                  child: Container(
                    color: Colors.red,
                    width: SizeOne,
                    height: SizeOne,
                    child: MaterialButton(
                        child: Text('refresh'),
                        onPressed: () {
                          refresh(() {
                            SizeOne = SizeOne + 5;
                          });
                        }),
                  ),
                );
              }),
              constraints: BoxConstraints(),
            ),
            ConstrainedBox(
              child: StatefulBuilder(builder: (_, refresh) {
                return Tint(
                  color: Colors.yellow,
                  child: Container(
                    color: Colors.blue,
                    width: SizeTwo,
                    height: SizeTwo,
                    child: MaterialButton(
                        child: Text('refresh'),
                        onPressed: () {
                          refresh(() {
                            SizeTwo = SizeTwo + 5;
                          });
                        }),
                  ),
                );
              }),
              constraints: BoxConstraints(),
            ),
            Container(
              height: 30,
              color: Colors.yellow,
            ),
          ],
        )
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
//拷贝ConstrainedBox修改,不同之处为对应的RenderObject中
//child.layout(Constraints constraints, { bool parentUsesSize = false }) 
//parentUsesSize传值false,ConstrainedBox中对应的RenderObject的
//child.layou方法parentUsesSize传值true

class CustomConstrainedBox extends SingleChildRenderObjectWidget {
  /// Creates a widget that imposes additional constraints on its child.
  ///
  /// The [constraints] argument must not be null.
  CustomConstrainedBox({
    Key key,
    @required this.constraints,
    Widget child,
  })  : assert(constraints != null),
        assert(constraints.debugAssertIsValid()),
        super(key: key, child: child);

  /// The additional constraints to impose on the child.
  final BoxConstraints constraints;

  @override
  CustomRenderConstrainedBox createRenderObject(BuildContext context) {
    return CustomRenderConstrainedBox(additionalConstraints: constraints);
  }

  @override
  void updateRenderObject(
      BuildContext context, CustomRenderConstrainedBox renderObject) {
    renderObject.additionalConstraints = constraints;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<BoxConstraints>(
        'constraints', constraints,
        showName: false));
  }
}

class CustomRenderConstrainedBox extends RenderConstrainedBox {
  CustomRenderConstrainedBox({
    RenderBox child,
    @required BoxConstraints additionalConstraints,
  }) : assert(additionalConstraints != null),
       assert(additionalConstraints.debugAssertIsValid()),
       super(child:child,additionalConstraints:additionalConstraints);
  @override
  void performLayout() {
    if (child != null) {
      child.layout(additionalConstraints.enforce(constraints),
          parentUsesSize: false);
      size = Size.copy(child.size);
    } else {
      size = additionalConstraints.enforce(constraints).constrain(Size.zero);
    }
  }
}

class Tint extends SingleChildRenderObjectWidget {
  const Tint({
    Key key,
    @required this.color,
    Widget child,
  })  : assert(color != null),
        super(key: key, child: child);

  final Color color;

  @override
  RenderTint createRenderObject(BuildContext context) {
    return RenderTint(
      color: color,
    );
  }

  @override
  void updateRenderObject(BuildContext context, RenderTint renderObject) {
    renderObject
      ..color = color;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(ColorProperty('color', color));
  }
}

class RenderTint extends RenderProxyBox {
  RenderTint({
    Color color = Colors.transparent,
    RenderBox child,
  })  : assert(color != null),
        _color = color,
        super(child);

  Color get color => _color;
  Color _color;
  set color(Color color) {
    assert(color != null);
    if (_color == color) return;
    _color = color;
    markNeedsPaint();
    markNeedsSemanticsUpdate();
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    if (child != null) {
      context.paintChild(child, offset);
    }
    // context.canvas.drawColor(color, BlendMode.srcOver);
  }

  @override
  // TODO: implement debugDoingThisResize
  bool get debugDoingThisResize => false;
  @override
  // TODO: implement debugDoingThisLayout
  bool get debugDoingThisLayout => true;

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(ColorProperty('color', color));
  }
}

效果图如下:

WeChateaa1f2a9cf4d061c90b1eda1e9ecb7fe.png

两个颜色块都点击放大之后如下图所示:


WeChat4a5b28586330ad5804a3b5f8eaec3244.png

结论

上一篇下一篇

猜你喜欢

热点阅读