mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Correct Badge interpretation of its alignment parameter (#119853)
This commit is contained in:
parent
d8154fde7a
commit
75ca31b0e4
@ -16,7 +16,7 @@ class _${blockName}DefaultsM3 extends BadgeThemeData {
|
||||
smallSize: ${tokens["md.comp.badge.size"]},
|
||||
largeSize: ${tokens["md.comp.badge.large.size"]},
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
alignment: const AlignmentDirectional(12, -4),
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
);
|
||||
|
||||
final BuildContext context;
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'badge_theme.dart';
|
||||
@ -35,6 +36,7 @@ class Badge extends StatelessWidget {
|
||||
this.textStyle,
|
||||
this.padding,
|
||||
this.alignment,
|
||||
this.offset,
|
||||
this.label,
|
||||
this.isLabelVisible = true,
|
||||
this.child,
|
||||
@ -54,6 +56,7 @@ class Badge extends StatelessWidget {
|
||||
this.textStyle,
|
||||
this.padding,
|
||||
this.alignment,
|
||||
this.offset,
|
||||
required int count,
|
||||
this.isLabelVisible = true,
|
||||
this.child,
|
||||
@ -106,13 +109,29 @@ class Badge extends StatelessWidget {
|
||||
/// left and right if the theme's value is null.
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
/// The location of the [label] relative to the [child].
|
||||
/// Combined with [offset] to determine the location of the [label]
|
||||
/// relative to the [child].
|
||||
///
|
||||
/// The alignment positions the label in the same way a child of an
|
||||
/// [Align] widget is positioned, except that, the alignment is
|
||||
/// resolved as if the label was a [largeSize] square and [offset]
|
||||
/// is added to the result.
|
||||
///
|
||||
/// This value is only used if [label] is non-null.
|
||||
///
|
||||
/// Defaults to the [BadgeTheme]'s alignment, or `start = 12`
|
||||
/// and `top = -4` if the theme's value is null.
|
||||
final AlignmentDirectional? alignment;
|
||||
/// Defaults to the [BadgeTheme]'s alignment, or
|
||||
/// [AlignmentDirectional.topEnd] if the theme's value is null.
|
||||
final AlignmentGeometry? alignment;
|
||||
|
||||
/// Combined with [alignment] to determine the location of the [label]
|
||||
/// relative to the [child].
|
||||
///
|
||||
/// This value is only used if [label] is non-null.
|
||||
///
|
||||
/// Defaults to the [BadgeTheme]'s offset, or
|
||||
/// if the theme's value is null then `Offset(4, -4)` for
|
||||
/// [TextDirection.ltr] or `Offset(-4, -4)` for [TextDirection.rtl].
|
||||
final Offset? offset;
|
||||
|
||||
/// The badge's content, typically a [Text] widget that contains 1 to 4
|
||||
/// characters.
|
||||
@ -168,24 +187,99 @@ class Badge extends StatelessWidget {
|
||||
return badge;
|
||||
}
|
||||
|
||||
final AlignmentDirectional effectiveAlignment = alignment ?? badgeTheme.alignment ?? defaults.alignment!;
|
||||
final AlignmentGeometry effectiveAlignment = alignment ?? badgeTheme.alignment ?? defaults.alignment!;
|
||||
final TextDirection textDirection = Directionality.of(context);
|
||||
final Offset defaultOffset = textDirection == TextDirection.ltr ? const Offset(4, -4) : const Offset(-4, -4);
|
||||
final Offset effectiveOffset = offset ?? badgeTheme.offset ?? defaultOffset;
|
||||
|
||||
return
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: <Widget>[
|
||||
child!,
|
||||
Positioned.directional(
|
||||
textDirection: Directionality.of(context),
|
||||
start: label == null ? null : effectiveAlignment.start,
|
||||
end: label == null ? 0 : null,
|
||||
top: label == null ? 0 : effectiveAlignment.y,
|
||||
Positioned.fill(
|
||||
child: _Badge(
|
||||
alignment: effectiveAlignment,
|
||||
offset: label == null ? Offset.zero : effectiveOffset,
|
||||
textDirection: textDirection,
|
||||
child: badge,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Badge extends SingleChildRenderObjectWidget {
|
||||
const _Badge({
|
||||
required this.alignment,
|
||||
required this.offset,
|
||||
required this.textDirection,
|
||||
super.child, // the badge
|
||||
});
|
||||
|
||||
final AlignmentGeometry alignment;
|
||||
final Offset offset;
|
||||
final TextDirection textDirection;
|
||||
|
||||
@override
|
||||
_RenderBadge createRenderObject(BuildContext context) {
|
||||
return _RenderBadge(
|
||||
alignment: alignment,
|
||||
offset: offset,
|
||||
textDirection: Directionality.maybeOf(context),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, _RenderBadge renderObject) {
|
||||
renderObject
|
||||
..alignment = alignment
|
||||
..offset = offset
|
||||
..textDirection = Directionality.maybeOf(context);
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
|
||||
properties.add(DiagnosticsProperty<Offset>('offset', offset));
|
||||
}
|
||||
}
|
||||
|
||||
class _RenderBadge extends RenderAligningShiftedBox {
|
||||
_RenderBadge({
|
||||
super.textDirection,
|
||||
super.alignment,
|
||||
required Offset offset,
|
||||
}) : _offset = offset;
|
||||
|
||||
Offset get offset => _offset;
|
||||
Offset _offset;
|
||||
set offset(Offset value) {
|
||||
if (_offset == value) {
|
||||
return;
|
||||
}
|
||||
_offset = value;
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
final BoxConstraints constraints = this.constraints;
|
||||
assert(constraints.hasBoundedWidth);
|
||||
assert(constraints.hasBoundedHeight);
|
||||
size = constraints.biggest;
|
||||
|
||||
child!.layout(const BoxConstraints(), parentUsesSize: true);
|
||||
final double badgeSize = child!.size.height;
|
||||
final Alignment resolvedAlignment = alignment.resolve(textDirection);
|
||||
final BoxParentData childParentData = child!.parentData! as BoxParentData;
|
||||
childParentData.offset = offset + resolvedAlignment.alongOffset(Offset(size.width - badgeSize, size.height - badgeSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BEGIN GENERATED TOKEN PROPERTIES - Badge
|
||||
|
||||
// Do not edit by hand. The code between the "BEGIN GENERATED" and
|
||||
@ -200,7 +294,7 @@ class _BadgeDefaultsM3 extends BadgeThemeData {
|
||||
smallSize: 6.0,
|
||||
largeSize: 16.0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
alignment: const AlignmentDirectional(12, -4),
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
);
|
||||
|
||||
final BuildContext context;
|
||||
|
@ -41,6 +41,7 @@ class BadgeThemeData with Diagnosticable {
|
||||
this.textStyle,
|
||||
this.padding,
|
||||
this.alignment,
|
||||
this.offset,
|
||||
});
|
||||
|
||||
/// Overrides the default value for [Badge.backgroundColor].
|
||||
@ -62,7 +63,10 @@ class BadgeThemeData with Diagnosticable {
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
/// Overrides the default value for [Badge.alignment].
|
||||
final AlignmentDirectional? alignment;
|
||||
final AlignmentGeometry? alignment;
|
||||
|
||||
/// Overrides the default value for [Badge.offset].
|
||||
final Offset? offset;
|
||||
|
||||
/// Creates a copy of this object but with the given fields replaced with the
|
||||
/// new values.
|
||||
@ -73,7 +77,8 @@ class BadgeThemeData with Diagnosticable {
|
||||
double? largeSize,
|
||||
TextStyle? textStyle,
|
||||
EdgeInsetsGeometry? padding,
|
||||
AlignmentDirectional? alignment,
|
||||
AlignmentGeometry? alignment,
|
||||
Offset? offset,
|
||||
}) {
|
||||
return BadgeThemeData(
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
@ -83,6 +88,7 @@ class BadgeThemeData with Diagnosticable {
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
padding: padding ?? this.padding,
|
||||
alignment: alignment ?? this.alignment,
|
||||
offset: offset ?? this.offset,
|
||||
);
|
||||
}
|
||||
|
||||
@ -95,7 +101,8 @@ class BadgeThemeData with Diagnosticable {
|
||||
largeSize: lerpDouble(a?.largeSize, b?.largeSize, t),
|
||||
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
|
||||
padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t),
|
||||
alignment: AlignmentDirectional.lerp(a?.alignment, b?.alignment, t),
|
||||
alignment: AlignmentGeometry.lerp(a?.alignment, b?.alignment, t),
|
||||
offset: Offset.lerp(a?.offset, b?.offset, t),
|
||||
);
|
||||
}
|
||||
|
||||
@ -108,6 +115,7 @@ class BadgeThemeData with Diagnosticable {
|
||||
textStyle,
|
||||
padding,
|
||||
alignment,
|
||||
offset,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -125,7 +133,8 @@ class BadgeThemeData with Diagnosticable {
|
||||
&& other.largeSize == largeSize
|
||||
&& other.textStyle == textStyle
|
||||
&& other.padding == padding
|
||||
&& other.alignment == alignment;
|
||||
&& other.alignment == alignment
|
||||
&& other.offset == offset;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -137,7 +146,8 @@ class BadgeThemeData with Diagnosticable {
|
||||
properties.add(DoubleProperty('largeSize', largeSize, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('textStyle', textStyle, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<AlignmentDirectional>('alignment', alignment, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<Offset>('offset', offset, defaultValue: null));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,8 @@ void main() {
|
||||
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
|
||||
);
|
||||
|
||||
// default badge alignment = AlignmentDirectional(12, -4)
|
||||
// default badge alignment = AlignmentDirection.topEnd
|
||||
// default offset for LTR = Offset(4, -4)
|
||||
// default padding = EdgeInsets.symmetric(horizontal: 4)
|
||||
// default largeSize = 16
|
||||
// '0'.width = 12
|
||||
@ -46,16 +47,9 @@ void main() {
|
||||
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
||||
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
||||
|
||||
// x = alignment.start + padding.left
|
||||
// y = alignment.top
|
||||
expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
|
||||
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
// '0'.width = 12
|
||||
// L = alignment.start
|
||||
// T = alignment.top
|
||||
// R = L + '0'.width + padding.width
|
||||
// B = T + largeSize, R = largeSize/2
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(12, -4, 32, 12, const Radius.circular(8)), color: theme.colorScheme.error));
|
||||
});
|
||||
|
||||
@ -89,26 +83,13 @@ void main() {
|
||||
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
|
||||
);
|
||||
|
||||
// default badge alignment = AlignmentDirectional(12, -4)
|
||||
// default padding = EdgeInsets.symmetric(horizontal: 4)
|
||||
// default largeSize = 16
|
||||
// '0'.width = 12
|
||||
// icon.width = 24
|
||||
|
||||
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
||||
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
||||
|
||||
// x = icon.width - alignment.start - '0'.width - padding.right
|
||||
// y = alignment.top
|
||||
expect(tester.getTopLeft(find.text('0')), const Offset(-4, -4));
|
||||
expect(tester.getTopLeft(find.text('0')), const Offset(0, -4));
|
||||
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
// L = icon.width - alignment.start - '0.width' - padding.width
|
||||
// T = alignment.top
|
||||
// R = L + '0.width' + padding.width
|
||||
// B = T + largeSize
|
||||
// R = largeSize/2
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(-8, -4, 12, 12, const Radius.circular(8)), color: theme.colorScheme.error));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(-4, -4, 16, 12, const Radius.circular(8)), color: theme.colorScheme.error));
|
||||
});
|
||||
|
||||
// Essentially the same as 'Large Badge defaults'
|
||||
@ -282,4 +263,153 @@ void main() {
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
expect(box, isNot(paints..rrect()));
|
||||
});
|
||||
|
||||
testWidgets('Large Badge alignment', (WidgetTester tester) async {
|
||||
const Radius badgeRadius = Radius.circular(8);
|
||||
|
||||
Widget buildFrame(Alignment alignment, [Offset offset = Offset.zero]) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData.light(useMaterial3: true),
|
||||
home: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Badge(
|
||||
// Default largeSize = 16, badge with label is "large".
|
||||
label: Container(width: 8, height: 8, color: Colors.blue),
|
||||
alignment: alignment,
|
||||
offset: offset,
|
||||
child: Container(
|
||||
color: const Color(0xFF00FF00),
|
||||
width: 200,
|
||||
height: 200,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topLeft));
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 16, 16, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topCenter));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 0, 100 + 8, 16, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topRight));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 0, 200, 16, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerLeft));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100 - 8, 16, 100 + 8, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerRight));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 100 - 8, 200, 100 + 8, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomLeft));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200 - 16, 16, 200, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomCenter));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 200 - 16, 100 + 8, 200, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomRight));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 200 - 16, 200, 200, badgeRadius)));
|
||||
|
||||
const Offset offset = Offset(5, 10);
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topLeft, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 16, 16, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topCenter, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 0, 100 + 8, 16, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topRight, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 0, 200, 16, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerLeft, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100 - 8, 16, 100 + 8, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerRight, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 100 - 8, 200, 100 + 8, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomLeft, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200 - 16, 16, 200, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomCenter, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 8, 200 - 16, 100 + 8, 200, badgeRadius).shift(offset)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomRight, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 16, 200 - 16, 200, 200, badgeRadius).shift(offset)));
|
||||
});
|
||||
|
||||
testWidgets('Small Badge alignment', (WidgetTester tester) async {
|
||||
const Radius badgeRadius = Radius.circular(3);
|
||||
|
||||
Widget buildFrame(Alignment alignment, [Offset offset = Offset.zero]) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData.light(useMaterial3: true),
|
||||
home: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Badge(
|
||||
// Default smallSize = 6, badge without label is "small".
|
||||
alignment: alignment,
|
||||
offset: offset, // Not used for smallSize badges.
|
||||
child: Container(
|
||||
color: const Color(0xFF00FF00),
|
||||
width: 200,
|
||||
height: 200,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topLeft));
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 6, 6, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topCenter));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 0, 100 + 3, 6, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topRight));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 0, 200, 6, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerLeft));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100 - 3, 6, 100 + 3, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerRight));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 100 - 3, 200, 100 + 3, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomLeft));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200 - 6, 6, 200, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomCenter));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 200 - 6, 100 + 3, 200, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomRight));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 200 - 6, 200, 200, badgeRadius)));
|
||||
|
||||
const Offset offset = Offset(5, 10); // Not used for smallSize Badges.
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topLeft, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 6, 6, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topCenter, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 0, 100 + 3, 6, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.topRight, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 0, 200, 6, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerLeft, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 100 - 3, 6, 100 + 3, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.centerRight, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 100 - 3, 200, 100 + 3, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomLeft, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 200 - 6, 6, 200, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomCenter, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(100 - 3, 200 - 6, 100 + 3, 200, badgeRadius)));
|
||||
|
||||
await tester.pumpWidget(buildFrame(Alignment.bottomRight, offset));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(200 - 6, 200 - 6, 200, 200, badgeRadius)));
|
||||
});
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ void main() {
|
||||
expect(themeData.textStyle, null);
|
||||
expect(themeData.padding, null);
|
||||
expect(themeData.alignment, null);
|
||||
expect(themeData.offset, null);
|
||||
});
|
||||
|
||||
testWidgets('Default BadgeThemeData debugFillProperties', (WidgetTester tester) async {
|
||||
@ -47,6 +48,7 @@ void main() {
|
||||
textStyle: TextStyle(fontSize: 4),
|
||||
padding: EdgeInsets.all(5),
|
||||
alignment: AlignmentDirectional(6, 7),
|
||||
offset: Offset.zero,
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
@ -61,7 +63,8 @@ void main() {
|
||||
'largeSize: 2.0',
|
||||
'textStyle: TextStyle(inherit: true, size: 4.0)',
|
||||
'padding: EdgeInsets.all(5.0)',
|
||||
'alignment: AlignmentDirectional(6.0, 7.0)'
|
||||
'alignment: AlignmentDirectional(6.0, 7.0)',
|
||||
'offset: Offset(0.0, 0.0)'
|
||||
]);
|
||||
});
|
||||
|
||||
@ -75,7 +78,8 @@ void main() {
|
||||
largeSize: 20,
|
||||
textStyle: TextStyle(fontSize: 12),
|
||||
padding: EdgeInsets.symmetric(horizontal: 5),
|
||||
alignment: AlignmentDirectional(24, 0),
|
||||
alignment: Alignment.topRight,
|
||||
offset: Offset(24, 0),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -95,8 +99,7 @@ void main() {
|
||||
// text width = 48 = fontSize * 4, text height = fontSize
|
||||
expect(tester.getSize(find.text('1234')), const Size(48, 12));
|
||||
|
||||
// x = 29 = alignment.start + padding.left, y = 4 = (largeSize - fontSize) / 2
|
||||
expect(tester.getTopLeft(find.text('1234')), const Offset(29, 4));
|
||||
expect(tester.getTopLeft(find.text('1234')), const Offset(33, 4));
|
||||
|
||||
|
||||
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
||||
@ -107,8 +110,7 @@ void main() {
|
||||
expect(textStyle.color, black);
|
||||
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
// L = alignment.start, T = alignment.top, R = L + fontSize * 4 + padding.width, B = largeSize R = largeSize/2
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(24, 0, 82, 20, const Radius.circular(10)), color: green));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(28, 0, 86, 20, const Radius.circular(10)), color: green));
|
||||
});
|
||||
|
||||
|
||||
@ -125,7 +127,8 @@ void main() {
|
||||
largeSize: 20,
|
||||
textStyle: TextStyle(fontSize: 12),
|
||||
padding: EdgeInsets.symmetric(horizontal: 5),
|
||||
alignment: AlignmentDirectional(24, 0),
|
||||
alignment: Alignment.topRight,
|
||||
offset: Offset(24, 0),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -143,13 +146,13 @@ void main() {
|
||||
);
|
||||
|
||||
expect(tester.getSize(find.text('1234')), const Size(48, 12));
|
||||
expect(tester.getTopLeft(find.text('1234')), const Offset(29, 4));
|
||||
expect(tester.getTopLeft(find.text('1234')), const Offset(33, 4));
|
||||
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
|
||||
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
|
||||
final TextStyle textStyle = tester.renderObject<RenderParagraph>(find.text('1234')).text.style!;
|
||||
expect(textStyle.fontSize, 12);
|
||||
expect(textStyle.color, black);
|
||||
final RenderBox box = tester.renderObject(find.byType(Badge));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(24, 0, 82, 20, const Radius.circular(10)), color: green));
|
||||
expect(box, paints..rrect(rrect: RRect.fromLTRBR(28, 0, 86, 20, const Radius.circular(10)), color: green));
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user