代码之家  ›  专栏  ›  技术社区  ›  Marcelo Glasberg

在flutter中,如何定义无状态小部件的基线?

  •  3
  • Marcelo Glasberg  · 技术社区  · 7 年前

    我创建了一个无状态的小部件,我想定义一个 基线 因为它,所以我可以将它与基线小部件一起使用。( https://docs.flutter.io/flutter/widgets/Baseline-class.html )。

    我该怎么做?

    1 回复  |  直到 7 年前
        1
  •  4
  •   chemamolins    7 年前

    如果要定义基线,则不能直接在无状态小部件中进行定义。你需要把它相应的 RenderBox 需要执行 computeDistanceToActualBaseline() 方法。

    看看 ListTile 实施 here .你会看到 _RenderListTile renderbox实现上面的方法,返回标题小部件的基线。

      @override
      double computeDistanceToActualBaseline(TextBaseline baseline) {
        assert(title != null);
        final BoxParentData parentData = title.parentData;
        return parentData.offset.dy + title.getDistanceToActualBaseline(baseline);
      }
    

    在这种情况下,标题的基线是文本小部件的底部。

    所有这些都是必要的,因为 Baseline 小部件尝试获取子小部件的基线。如果您没有用上面的方法提供一个明确的基线,它只使用它的底部位置。

    您可以在下面找到一个 BaselineBox 您可以从顶部设置任意基线。

    import 'package:flutter/widgets.dart';
    import 'package:flutter/foundation.dart';
    import 'package:flutter/rendering.dart';
    
    class BaselineBox extends SingleChildRenderObjectWidget {
      const BaselineBox({Key key, @required this.baseline, Widget child})
          : assert(baseline != null),
            super(key: key, child: child);
    
      final double baseline;
    
      @override
      RenderBaselineBox createRenderObject(BuildContext context) =>
          new RenderBaselineBox(baseline: baseline);
    
      @override
      void updateRenderObject(
          BuildContext context, RenderBaselineBox renderObject) {
        renderObject.baseline = baseline;
      }
    
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(new DoubleProperty('baseline', baseline));
      }
    }
    
    class RenderBaselineBox extends RenderProxyBox {
      RenderBaselineBox({
        RenderBox child,
        @required double baseline,
      })  : assert(baseline != null),
            assert(baseline >= 0.0),
            assert(baseline.isFinite),
            _baseline = baseline,
            super(child);
    
      double get baseline => _baseline;
      double _baseline;
    
      set baseline(double value) {
        assert(value != null);
        assert(value >= 0.0);
        assert(value.isFinite);
        if (_baseline == value) return;
        _baseline = value;
        markNeedsLayout();
      }
    
      @override
      double computeDistanceToActualBaseline(TextBaseline baselineType) {
        return _baseline;
      }
    
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(new DoubleProperty('baseline', baseline));
      }
    }