Skip to content

Commit f852a90

Browse files
authored
Merge pull request #368 from AhmedLSayed9/consider_border_radius_for_barrier_covers_button
Respect button/inputDecoration's borderRadius when barrierCoversButton is false
2 parents b03766c + 72f1525 commit f852a90

File tree

3 files changed

+80
-17
lines changed

3 files changed

+80
-17
lines changed

packages/dropdown_button2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
- Fix DropdownButtonFormField clips text when large text scale is used [Flutter core].
1616
- Fix DropdownButtonFormField padding when ButtonTheme.alignedDropdown is true [Flutter core].
1717
- Add barrierCoversButton to DropdownButtonFormField2.
18+
- Respect button's borderRadius when barrierCoversButton is false.
19+
- Respect inputDecoration's borderRadius when barrierCoversButton is false.
1820

1921
## 3.0.0-beta.21
2022

packages/dropdown_button2/lib/src/dropdown_button2.dart

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ class DropdownButton2<T> extends StatefulWidget {
127127
'Only one of valueListenable or multiValueListenable can be used.',
128128
),
129129
_inputDecoration = null,
130-
_isEmpty = false;
130+
_isEmpty = false,
131+
_hasError = false;
131132

132133
const DropdownButton2._formField({
133134
super.key,
@@ -161,9 +162,11 @@ class DropdownButton2<T> extends StatefulWidget {
161162
required this.openDropdownListenable,
162163
required InputDecoration inputDecoration,
163164
required bool isEmpty,
165+
required bool hasError,
164166
}) : underline = null,
165167
_inputDecoration = inputDecoration,
166-
_isEmpty = isEmpty;
168+
_isEmpty = isEmpty,
169+
_hasError = hasError;
167170

168171
/// The list of items the user can select.
169172
///
@@ -382,6 +385,8 @@ class DropdownButton2<T> extends StatefulWidget {
382385

383386
final bool _isEmpty;
384387

388+
final bool _hasError;
389+
385390
@override
386391
State<DropdownButton2<T>> createState() => _DropdownButton2State<T>();
387392
}
@@ -572,6 +577,30 @@ class _DropdownButton2State<T> extends State<DropdownButton2<T>> with WidgetsBin
572577
}
573578
}
574579

580+
Set<WidgetState> _materialState(InputDecoration decoration) => <WidgetState>{
581+
if (!decoration.enabled) WidgetState.disabled,
582+
if (_isFocused) WidgetState.focused,
583+
if (_isHovering) WidgetState.hovered,
584+
if (widget._hasError) WidgetState.error,
585+
};
586+
587+
BorderRadius? _getInputDecorationBorderRadius(InputDecoration decoration) {
588+
InputBorder? border;
589+
if (!decoration.enabled) {
590+
border = widget._hasError ? decoration.errorBorder : decoration.disabledBorder;
591+
} else if (_isFocused) {
592+
border = widget._hasError ? decoration.focusedErrorBorder : decoration.focusedBorder;
593+
} else {
594+
border = widget._hasError ? decoration.errorBorder : decoration.enabledBorder;
595+
}
596+
border ??= WidgetStateProperty.resolveAs(decoration.border, _materialState(decoration));
597+
598+
if (border is OutlineInputBorder) {
599+
return border.borderRadius;
600+
}
601+
return null;
602+
}
603+
575604
EdgeInsetsGeometry _buttonAdditionalHPadding() {
576605
final TextDirection? textDirection = Directionality.maybeOf(context);
577606

@@ -602,6 +631,9 @@ class _DropdownButton2State<T> extends State<DropdownButton2<T>> with WidgetsBin
602631
_dropdownRoute = _DropdownRoute<T>(
603632
items: items,
604633
buttonRect: _buttonRect,
634+
buttonBorderRadius: widget._inputDecoration != null
635+
? _getInputDecorationBorderRadius(widget._inputDecoration!)
636+
: _getButtonBorderRadius(context),
605637
selectedIndex: _selectedIndex ?? 0,
606638
isNoSelectedItem: _selectedIndex == null,
607639
onChanged: widget.onChanged,
@@ -1026,6 +1058,10 @@ class DropdownButtonFormField2<T> extends FormField<T> {
10261058
: effectiveHint != null || effectiveDisabledHint != null;
10271059
final bool isEmpty = !showSelectedItem && !isHintOrDisabledHintAvailable;
10281060

1061+
final bool hasError = field.hasError ||
1062+
effectiveDecoration.errorText != null ||
1063+
effectiveDecoration.error != null;
1064+
10291065
// An unFocusable Focus widget so that this widget can detect if its
10301066
// descendants have focus or not.
10311067
return Focus(
@@ -1067,6 +1103,7 @@ class DropdownButtonFormField2<T> extends FormField<T> {
10671103
hintText: effectiveDecoration.hintText != null ? '' : null,
10681104
),
10691105
isEmpty: isEmpty,
1106+
hasError: hasError,
10701107
),
10711108
),
10721109
);

packages/dropdown_button2/lib/src/dropdown_route.dart

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
44
_DropdownRoute({
55
required this.items,
66
required this.buttonRect,
7+
required this.buttonBorderRadius,
78
required this.selectedIndex,
89
required this.isNoSelectedItem,
910
required this.onChanged,
@@ -25,6 +26,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
2526

2627
final List<DropdownItem<T>> items;
2728
final ValueNotifier<Rect?> buttonRect;
29+
final BorderRadius? buttonBorderRadius;
2830
final int selectedIndex;
2931
final bool isNoSelectedItem;
3032
final ValueChanged<T?>? onChanged;
@@ -89,10 +91,11 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
8991
return barrierCoversButton
9092
? routePage
9193
: _CustomModalBarrier(
92-
animation: animation,
9394
barrierColor: _altBarrierColor,
95+
animation: animation,
9496
barrierCurve: barrierCurve,
9597
buttonRect: rect,
98+
buttonBorderRadius: buttonBorderRadius ?? BorderRadius.zero,
9699
child: routePage,
97100
);
98101
},
@@ -458,18 +461,20 @@ class _DropdownRouteResult<T> {
458461
/// It's used instead of the route barrier when `barrierCoversButton` is set to false.
459462
class _CustomModalBarrier extends StatefulWidget {
460463
const _CustomModalBarrier({
461-
this.animation,
462-
this.barrierColor,
464+
required this.barrierColor,
465+
required this.animation,
463466
required this.barrierCurve,
467+
required this.buttonRect,
468+
required this.buttonBorderRadius,
464469
required this.child,
465-
this.buttonRect,
466470
});
467471

468-
final Animation<double>? animation;
469472
final Color? barrierColor;
473+
final Animation<double>? animation;
470474
final Curve barrierCurve;
475+
final Rect buttonRect;
476+
final BorderRadius buttonBorderRadius;
471477
final Widget child;
472-
final Rect? buttonRect;
473478

474479
@override
475480
State<_CustomModalBarrier> createState() => _CustomModalBarrierState();
@@ -503,8 +508,9 @@ class _CustomModalBarrierState extends State<_CustomModalBarrier> {
503508
builder: (BuildContext context, Color? value, Widget? child) {
504509
return CustomPaint(
505510
painter: _DropdownBarrierPainter(
506-
buttonRect: widget.buttonRect,
507511
barrierColor: value,
512+
buttonRect: widget.buttonRect,
513+
buttonBorderRadius: widget.buttonBorderRadius,
508514
pageSize: size,
509515
),
510516
);
@@ -518,29 +524,47 @@ class _CustomModalBarrierState extends State<_CustomModalBarrier> {
518524

519525
class _DropdownBarrierPainter extends CustomPainter {
520526
const _DropdownBarrierPainter({
521-
this.buttonRect,
522-
this.barrierColor,
527+
required this.barrierColor,
528+
required this.buttonRect,
529+
required this.buttonBorderRadius,
523530
required this.pageSize,
524531
});
525532

526-
final Rect? buttonRect;
527533
final Color? barrierColor;
534+
final Rect buttonRect;
535+
final BorderRadius buttonBorderRadius;
528536
final Size pageSize;
529537

530538
@override
531539
void paint(Canvas canvas, Size size) {
532-
if (barrierColor != null && buttonRect != null) {
533-
final Rect rect =
534-
Rect.fromLTRB(-buttonRect!.left, -buttonRect!.top, pageSize.width, pageSize.height);
540+
if (barrierColor != null) {
541+
final Rect rect = Rect.fromLTRB(
542+
-buttonRect.left,
543+
-buttonRect.top,
544+
pageSize.width,
545+
pageSize.height,
546+
);
547+
535548
canvas.saveLayer(rect, Paint());
536549
canvas.drawRect(rect, Paint()..color = barrierColor!);
537-
canvas.drawRect(buttonRect!, Paint()..blendMode = BlendMode.clear);
550+
551+
final RRect buttonRRect = RRect.fromRectAndCorners(
552+
buttonRect,
553+
topLeft: buttonBorderRadius.topLeft,
554+
topRight: buttonBorderRadius.topRight,
555+
bottomLeft: buttonBorderRadius.bottomLeft,
556+
bottomRight: buttonBorderRadius.bottomRight,
557+
);
558+
559+
canvas.drawRRect(buttonRRect, Paint()..blendMode = BlendMode.clear);
538560
canvas.restore();
539561
}
540562
}
541563

542564
@override
543565
bool shouldRepaint(_DropdownBarrierPainter oldPainter) {
544-
return oldPainter.buttonRect != buttonRect || oldPainter.barrierColor != barrierColor;
566+
return oldPainter.buttonRect != buttonRect ||
567+
oldPainter.barrierColor != barrierColor ||
568+
oldPainter.buttonBorderRadius != buttonBorderRadius;
545569
}
546570
}

0 commit comments

Comments
 (0)