InputDecorator should clip fill color to its border (#15795)
This commit is contained in:
@@ -68,6 +68,7 @@ class _InputBorderPainter extends CustomPainter {
|
||||
this.gapAnimation,
|
||||
this.gap,
|
||||
this.textDirection,
|
||||
this.fillColor,
|
||||
}) : super(repaint: repaint);
|
||||
|
||||
final Animation<double> borderAnimation;
|
||||
@@ -75,12 +76,25 @@ class _InputBorderPainter extends CustomPainter {
|
||||
final Animation<double> gapAnimation;
|
||||
final _InputBorderGap gap;
|
||||
final TextDirection textDirection;
|
||||
final Color fillColor;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
border.evaluate(borderAnimation).paint(
|
||||
final InputBorder borderValue = border.evaluate(borderAnimation);
|
||||
final Rect canvasRect = Offset.zero & size;
|
||||
|
||||
if (fillColor.alpha > 0) {
|
||||
canvas.drawPath(
|
||||
borderValue.getOuterPath(canvasRect, textDirection: textDirection),
|
||||
new Paint()
|
||||
..color = fillColor
|
||||
..style = PaintingStyle.fill,
|
||||
);
|
||||
}
|
||||
|
||||
borderValue.paint(
|
||||
canvas,
|
||||
Offset.zero & size,
|
||||
canvasRect,
|
||||
gapStart: gap.start,
|
||||
gapExtent: gap.extent,
|
||||
gapPercentage: gapAnimation.value,
|
||||
@@ -108,14 +122,17 @@ class _BorderContainer extends StatefulWidget {
|
||||
@required this.border,
|
||||
@required this.gap,
|
||||
@required this.gapAnimation,
|
||||
@required this.fillColor,
|
||||
this.child,
|
||||
}) : assert(border != null),
|
||||
assert(gap != null),
|
||||
assert(fillColor != null),
|
||||
super(key: key);
|
||||
|
||||
final InputBorder border;
|
||||
final _InputBorderGap gap;
|
||||
final Animation<double> gapAnimation;
|
||||
final Color fillColor;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
@@ -174,6 +191,7 @@ class _BorderContainerState extends State<_BorderContainer> with SingleTickerPro
|
||||
gapAnimation: widget.gapAnimation,
|
||||
gap: widget.gap,
|
||||
textDirection: Directionality.of(context),
|
||||
fillColor: widget.fillColor,
|
||||
),
|
||||
child: widget.child,
|
||||
);
|
||||
@@ -1518,15 +1536,16 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
),
|
||||
);
|
||||
|
||||
final Widget containerFill = new DecoratedBox(
|
||||
decoration: new BoxDecoration(color: _getFillColor(themeData)),
|
||||
);
|
||||
final Widget container = border == null ? containerFill : new _BorderContainer(
|
||||
border: border,
|
||||
gap: _borderGap,
|
||||
gapAnimation: _floatingLabelController.view,
|
||||
child: containerFill,
|
||||
);
|
||||
final Widget container = border == null
|
||||
? new DecoratedBox(
|
||||
decoration: new BoxDecoration(color: _getFillColor(themeData))
|
||||
)
|
||||
: new _BorderContainer(
|
||||
border: border,
|
||||
gap: _borderGap,
|
||||
gapAnimation: _floatingLabelController.view,
|
||||
fillColor: _getFillColor(themeData),
|
||||
);
|
||||
|
||||
final TextStyle inlineLabelStyle = inlineStyle.merge(decoration.labelStyle);
|
||||
final Widget label = decoration.labelText == null ? null : new _Shaker(
|
||||
|
||||
@@ -6,6 +6,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
|
||||
Widget buildInputDecorator({
|
||||
InputDecoration decoration: const InputDecoration(),
|
||||
InputDecorationTheme inputDecorationTheme,
|
||||
@@ -1188,4 +1190,44 @@ void main() {
|
||||
expect(decoration.fillColor, Colors.blue);
|
||||
expect(decoration.border, const OutlineInputBorder());
|
||||
});
|
||||
|
||||
testWidgets('InputDecorator fillColor is clipped by border', (WidgetTester tester) async {
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/15742
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildInputDecorator(
|
||||
// isEmpty: false (default)
|
||||
// isFocused: false (default)
|
||||
decoration: new InputDecoration(
|
||||
filled: true,
|
||||
fillColor: const Color(0xFF00FF00),
|
||||
border: new OutlineInputBorder(
|
||||
borderRadius: new BorderRadius.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, 6.0), // outside the rounded corner, top left
|
||||
const Offset(800.0 - 1.0, 6.0), // top right
|
||||
const Offset(1.0, 56.0 - 6.0), // bottom left
|
||||
const Offset(800 - 1.0, 56.0 - 6.0), // bottom right
|
||||
],
|
||||
));
|
||||
|
||||
// Border outline. The rrect is the -center- of the 1.0 stroked outline.
|
||||
expect(box, paints..rrect(
|
||||
style: PaintingStyle.stroke,
|
||||
strokeWidth: 1.0,
|
||||
rrect: new RRect.fromLTRBR(0.5, 0.5, 799.5, 55.5, const Radius.circular(11.5)),
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user