В Flutter, как я могу определить базовую линию для виджета без сохранения состояния? - PullRequest
0 голосов
/ 01 июля 2018

Я создал виджет без сохранения состояния и хочу определить для него baseline , чтобы я мог использовать его с виджетом Baseline (https://docs.flutter.io/flutter/widgets/Baseline-class.html).

Как я могу это сделать?

1 Ответ

0 голосов
/ 01 июля 2018

Если вы хотите определить базовую линию, вы не можете сделать это непосредственно в виджете без состояния. Вам нужно возиться с соответствующим RenderBox, который должен реализовать метод computeDistanceToActualBaseline().

Посмотрите на реализацию ListTile здесь . Вы увидите, что _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));
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...