IgnoreBaseline widget (#131220)
Fixes https://github.com/flutter/flutter/issues/7037
This commit is contained in:
parent
2240649358
commit
48f08e3db2
@ -916,7 +916,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
while (child != null) {
|
||||
assert(() {
|
||||
if (textBaseline == null) {
|
||||
throw FlutterError('To use FlexAlignItems.baseline, you must also specify which baseline to use using the "baseline" argument.');
|
||||
throw FlutterError('To use CrossAxisAlignment.baseline, you must also specify which baseline to use using the "textBaseline" argument.');
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
|
@ -842,6 +842,19 @@ class RenderIntrinsicHeight extends RenderProxyBox {
|
||||
}
|
||||
}
|
||||
|
||||
/// Excludes the child from baseline computations in the parent.
|
||||
class RenderIgnoreBaseline extends RenderProxyBox {
|
||||
/// Create a render object that causes the parent to ignore the child for baseline computations.
|
||||
RenderIgnoreBaseline({
|
||||
RenderBox? child,
|
||||
}) : super(child);
|
||||
|
||||
@override
|
||||
double? computeDistanceToActualBaseline(TextBaseline baseline) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Makes its child partially transparent.
|
||||
///
|
||||
/// This class paints its child into an intermediate buffer and then blends the
|
||||
|
@ -1266,6 +1266,7 @@ class PhysicalShape extends SingleChildRenderObjectWidget {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// POSITIONING AND SIZING NODES
|
||||
|
||||
/// A widget that applies a transformation before painting its child.
|
||||
@ -3548,8 +3549,6 @@ class IntrinsicHeight extends SingleChildRenderObjectWidget {
|
||||
/// * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
|
||||
class Baseline extends SingleChildRenderObjectWidget {
|
||||
/// Creates a widget that positions its child according to the child's baseline.
|
||||
///
|
||||
/// The [baseline] and [baselineType] arguments must not be null.
|
||||
const Baseline({
|
||||
super.key,
|
||||
required this.baseline,
|
||||
@ -3577,6 +3576,25 @@ class Baseline extends SingleChildRenderObjectWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// A widget that causes the parent to ignore the [child] for the purposes
|
||||
/// of baseline alignment.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Baseline], a widget that positions a child relative to a baseline.
|
||||
class IgnoreBaseline extends SingleChildRenderObjectWidget {
|
||||
/// Creates a widget that ignores the child for baseline alignment purposes.
|
||||
const IgnoreBaseline({
|
||||
super.key,
|
||||
super.child,
|
||||
});
|
||||
|
||||
@override
|
||||
RenderIgnoreBaseline createRenderObject(BuildContext context) {
|
||||
return RenderIgnoreBaseline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SLIVERS
|
||||
|
||||
|
@ -52,4 +52,56 @@ void main() {
|
||||
expect(childParentData.offset.dy, equals(10.0));
|
||||
expect(parent.size, equals(const Size(100.0, 110.0)));
|
||||
});
|
||||
|
||||
test('RenderFlex and RenderIgnoreBaseline (control test -- with baseline)', () {
|
||||
final RenderBox a, b;
|
||||
final RenderBox root = RenderFlex(
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <RenderBox>[
|
||||
a = RenderParagraph(
|
||||
const TextSpan(text: 'a', style: TextStyle(fontSize: 128.0, fontFamily: 'FlutterTest')), // places baseline at y=96
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
b = RenderParagraph(
|
||||
const TextSpan(text: 'b', style: TextStyle(fontSize: 32.0, fontFamily: 'FlutterTest')), // 24 above baseline, 8 below baseline
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
);
|
||||
layout(root);
|
||||
|
||||
final Offset aPos = a.localToGlobal(Offset.zero);
|
||||
final Offset bPos = b.localToGlobal(Offset.zero);
|
||||
expect(aPos.dy, 0.0);
|
||||
expect(bPos.dy, 96.0 - 24.0);
|
||||
});
|
||||
|
||||
test('RenderFlex and RenderIgnoreBaseline (with ignored baseline)', () {
|
||||
final RenderBox a, b;
|
||||
final RenderBox root = RenderFlex(
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <RenderBox>[
|
||||
RenderIgnoreBaseline(
|
||||
child: a = RenderParagraph(
|
||||
const TextSpan(text: 'a', style: TextStyle(fontSize: 128.0, fontFamily: 'FlutterTest')),
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
),
|
||||
b = RenderParagraph(
|
||||
const TextSpan(text: 'b', style: TextStyle(fontSize: 32.0, fontFamily: 'FlutterTest')),
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
);
|
||||
layout(root);
|
||||
|
||||
final Offset aPos = a.localToGlobal(Offset.zero);
|
||||
final Offset bPos = b.localToGlobal(Offset.zero);
|
||||
expect(aPos.dy, 0.0);
|
||||
expect(bPos.dy, 0.0);
|
||||
});
|
||||
}
|
||||
|
@ -1135,6 +1135,62 @@ void main() {
|
||||
contains('verticalDirection: up'),
|
||||
]));
|
||||
});
|
||||
|
||||
testWidgets('Row and IgnoreBaseline (control -- with baseline)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'a',
|
||||
textDirection: TextDirection.ltr,
|
||||
style: TextStyle(fontSize: 128.0, fontFamily: 'FlutterTest'), // places baseline at y=96
|
||||
),
|
||||
Text(
|
||||
'b',
|
||||
textDirection: TextDirection.ltr,
|
||||
style: TextStyle(fontSize: 32.0, fontFamily: 'FlutterTest'), // 24 above baseline, 8 below baseline
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
final Offset aPos = tester.getTopLeft(find.text('a'));
|
||||
final Offset bPos = tester.getTopLeft(find.text('b'));
|
||||
expect(aPos.dy, 0.0);
|
||||
expect(bPos.dy, 96.0 - 24.0);
|
||||
});
|
||||
|
||||
testWidgets('Row and IgnoreBaseline (with ignored baseline)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
IgnoreBaseline(
|
||||
child: Text(
|
||||
'a',
|
||||
textDirection: TextDirection.ltr,
|
||||
style: TextStyle(fontSize: 128.0, fontFamily: 'FlutterTest'), // places baseline at y=96
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'b',
|
||||
textDirection: TextDirection.ltr,
|
||||
style: TextStyle(fontSize: 32.0, fontFamily: 'FlutterTest'), // 24 above baseline, 8 below baseline
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
final Offset aPos = tester.getTopLeft(find.text('a'));
|
||||
final Offset bPos = tester.getTopLeft(find.text('b'));
|
||||
expect(aPos.dy, 0.0);
|
||||
expect(bPos.dy, 0.0);
|
||||
});
|
||||
}
|
||||
|
||||
HitsRenderBox hits(RenderBox renderBox) => HitsRenderBox(renderBox);
|
||||
|
Loading…
x
Reference in New Issue
Block a user