Unverified Commit c7d982eb authored by Hans Muller's avatar Hans Muller Committed by GitHub

Updated appearance of filled TextFields - added UnderlineInputBorder.borderRadius (#16272)

parent 24bfbeb2
...@@ -116,7 +116,8 @@ class _NoInputBorder extends InputBorder { ...@@ -116,7 +116,8 @@ class _NoInputBorder extends InputBorder {
} }
} }
/// Draws a horizontal line at the bottom of an [InputDecorator]'s container. /// Draws a horizontal line at the bottom of an [InputDecorator]'s container and
/// defines the container's shape.
/// ///
/// The input decorator's "container" is the optionally filled area above the /// The input decorator's "container" is the optionally filled area above the
/// decorator's helper, error, and counter. /// decorator's helper, error, and counter.
...@@ -133,16 +134,39 @@ class UnderlineInputBorder extends InputBorder { ...@@ -133,16 +134,39 @@ class UnderlineInputBorder extends InputBorder {
/// null). Applications typically do not specify a [borderSide] parameter /// null). Applications typically do not specify a [borderSide] parameter
/// because the input decorator substitutes its own, using [copyWith], based /// because the input decorator substitutes its own, using [copyWith], based
/// on the current theme and [InputDecorator.isFocused]. /// on the current theme and [InputDecorator.isFocused].
///
/// The [borderRadius] parameter defaults to a value where the top left
/// and right corners have a circular radius of 4.0. The [borderRadius]
/// parameter must not be null.
const UnderlineInputBorder({ const UnderlineInputBorder({
BorderSide borderSide: BorderSide.none, BorderSide borderSide: BorderSide.none,
}) : super(borderSide: borderSide); this.borderRadius: const BorderRadius.only(
topLeft: const Radius.circular(4.0),
topRight: const Radius.circular(4.0),
),
}) : assert(borderRadius != null),
super(borderSide: borderSide);
/// The radii of the border's rounded rectangle corners.
///
/// When this border is used with a filled input decorator, see
/// [InputDecoration.filled], the border radius defines the shape
/// of the background fill as well as the bottom left and right
/// edges of the underline itself.
///
/// By default the top right and top left corners have a circular radius
/// of 4.0.
final BorderRadius borderRadius;
@override @override
bool get isOutline => false; bool get isOutline => false;
@override @override
UnderlineInputBorder copyWith({ BorderSide borderSide }) { UnderlineInputBorder copyWith({ BorderSide borderSide, BorderRadius borderRadius }) {
return new UnderlineInputBorder(borderSide: borderSide ?? this.borderSide); return new UnderlineInputBorder(
borderSide: borderSide ?? this.borderSide,
borderRadius: borderRadius ?? this.borderRadius,
);
} }
@override @override
...@@ -163,7 +187,7 @@ class UnderlineInputBorder extends InputBorder { ...@@ -163,7 +187,7 @@ class UnderlineInputBorder extends InputBorder {
@override @override
Path getOuterPath(Rect rect, { TextDirection textDirection }) { Path getOuterPath(Rect rect, { TextDirection textDirection }) {
return new Path()..addRect(rect); return new Path()..addRRect(borderRadius.resolve(textDirection).toRRect(rect));
} }
@override @override
...@@ -197,6 +221,8 @@ class UnderlineInputBorder extends InputBorder { ...@@ -197,6 +221,8 @@ class UnderlineInputBorder extends InputBorder {
double gapPercentage: 0.0, double gapPercentage: 0.0,
TextDirection textDirection, TextDirection textDirection,
}) { }) {
if (borderRadius.bottomLeft != Radius.zero || borderRadius.bottomRight != Radius.zero)
canvas.clipPath(getOuterPath(rect, textDirection: textDirection));
canvas.drawLine(rect.bottomLeft, rect.bottomRight, borderSide.toPaint()); canvas.drawLine(rect.bottomLeft, rect.bottomRight, borderSide.toPaint());
} }
...@@ -235,9 +261,10 @@ class OutlineInputBorder extends InputBorder { ...@@ -235,9 +261,10 @@ class OutlineInputBorder extends InputBorder {
/// because the input decorator substitutes its own, using [copyWith], based /// because the input decorator substitutes its own, using [copyWith], based
/// on the current theme and [InputDecorator.isFocused]. /// on the current theme and [InputDecorator.isFocused].
/// ///
/// If [borderRadius] is null (the default) then the border's corners /// The [borderRadius] parameter defaults to a value where all four
/// are drawn with a radius of 4 logical pixels. The corner radii must be /// corners have a circular radius of 4.0. The [borderRadius] parameter
/// circular, i.e. their [Radius.x] and [Radius.y] values must be the same. /// must not be null and the corner radii must be circular, i.e. their
/// [Radius.x] and [Radius.y] values must be the same.
const OutlineInputBorder({ const OutlineInputBorder({
BorderSide borderSide: BorderSide.none, BorderSide borderSide: BorderSide.none,
this.borderRadius: const BorderRadius.all(const Radius.circular(4.0)), this.borderRadius: const BorderRadius.all(const Radius.circular(4.0)),
......
...@@ -1217,7 +1217,7 @@ void main() { ...@@ -1217,7 +1217,7 @@ void main() {
expect(decoration.border, const OutlineInputBorder()); expect(decoration.border, const OutlineInputBorder());
}); });
testWidgets('InputDecorator fillColor is clipped by border', (WidgetTester tester) async { testWidgets('InputDecorator OutlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/15742 // This is a regression test for https://github.com/flutter/flutter/issues/15742
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1256,4 +1256,36 @@ void main() { ...@@ -1256,4 +1256,36 @@ void main() {
rrect: new RRect.fromLTRBR(0.5, 0.5, 799.5, 55.5, const Radius.circular(11.5)), rrect: new RRect.fromLTRBR(0.5, 0.5, 799.5, 55.5, const Radius.circular(11.5)),
)); ));
}); });
testWidgets('InputDecorator UnderlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
filled: true,
fillColor: const Color(0xFF00FF00),
border: const UnderlineInputBorder(
borderRadius: const BorderRadius.only(
bottomLeft: const Radius.circular(12.0),
bottomRight: const Radius.circular(12.0),
),
),
),
),
);
final RenderBox box = tester.renderObject(find.byType(InputDecorator));
// Fill is the border's outer path, a rounded rectangle
expect(box, paints..path(
style: PaintingStyle.fill,
color: const Color(0xFF00FF00),
includes: <Offset>[const Offset(800.0/2.0, 56/2.0)],
excludes: <Offset>[
const Offset(1.0, 56.0 - 6.0), // bottom left
const Offset(800 - 1.0, 56.0 - 6.0), // bottom right
],
));
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment