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

时间:2018-07-01 18:04:54

标签: dart flutter flutter-layout baseline

我已经创建了一个无状态的小部件,并且我想为其定义一个基线,以便可以将其与“基线”小部件(https://docs.flutter.io/flutter/widgets/Baseline-class.html)一起使用。

我该怎么做?

1 个答案:

答案 0 :(得分:3)

如果要定义基线,则不能直接在无状态窗口小部件中进行操作。您需要弄乱需要实现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));
  }
}