Skip to content

Commit 5cee565

Browse files
committed
Support BorderRadiusDirectional for dropdown menu
1 parent f852a90 commit 5cee565

File tree

4 files changed

+62
-46
lines changed

4 files changed

+62
-46
lines changed

packages/dropdown_button2/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- Add barrierCoversButton to DropdownButtonFormField2.
1818
- Respect button's borderRadius when barrierCoversButton is false.
1919
- Respect inputDecoration's borderRadius when barrierCoversButton is false.
20+
- Support BorderRadiusDirectional for dropdown menu.
2021

2122
## 3.0.0-beta.21
2223

packages/dropdown_button2/lib/src/dropdown_button2.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ class _DropdownButton2State<T> extends State<DropdownButton2<T>> with WidgetsBin
622622
void _handleTap() {
623623
final NavigatorState navigator = Navigator.of(context,
624624
rootNavigator: _dropdownStyle.isFullScreen ?? _dropdownStyle.useRootNavigator);
625+
final TextDirection? textDirection = Directionality.maybeOf(context);
625626

626627
final items = widget.items!;
627628
final separator = widget.dropdownSeparator;
@@ -646,6 +647,7 @@ class _DropdownButton2State<T> extends State<DropdownButton2<T>> with WidgetsBin
646647
barrierCoversButton: widget.barrierCoversButton,
647648
parentFocusNode: _focusNode,
648649
enableFeedback: widget.enableFeedback ?? true,
650+
textDirection: textDirection,
649651
dropdownStyle: _dropdownStyle,
650652
menuItemStyle: _menuItemStyle,
651653
inputDecorationPadding: _getInputDecorationPadding(),

packages/dropdown_button2/lib/src/dropdown_menu.dart

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
242242
resize: _resize,
243243
itemHeight: items[0].height,
244244
dropdownDecoration: dropdownStyle.decoration,
245+
textDirection: widget.textDirection,
245246
),
246247
child: Semantics(
247248
scopesRoute: true,
@@ -263,12 +264,13 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
263264

264265
class _DropdownMenuPainter extends CustomPainter {
265266
_DropdownMenuPainter({
266-
this.color,
267-
this.elevation,
268-
this.selectedIndex,
267+
required this.color,
268+
required this.elevation,
269+
required this.selectedIndex,
269270
required this.resize,
270271
required this.itemHeight,
271-
this.dropdownDecoration,
272+
required this.dropdownDecoration,
273+
required this.textDirection,
272274
}) : _painter = dropdownDecoration
273275
?.copyWith(
274276
color: dropdownDecoration.color ?? color,
@@ -291,6 +293,7 @@ class _DropdownMenuPainter extends CustomPainter {
291293
final Animation<double> resize;
292294
final double itemHeight;
293295
final BoxDecoration? dropdownDecoration;
296+
final TextDirection? textDirection;
294297

295298
final BoxPainter _painter;
296299

@@ -310,16 +313,21 @@ class _DropdownMenuPainter extends CustomPainter {
310313

311314
final Rect rect = Rect.fromLTRB(0.0, top.evaluate(resize), size.width, bottom.evaluate(resize));
312315

313-
_painter.paint(canvas, rect.topLeft, ImageConfiguration(size: rect.size));
316+
_painter.paint(
317+
canvas,
318+
rect.topLeft,
319+
ImageConfiguration(size: rect.size, textDirection: textDirection),
320+
);
314321
}
315322

316323
@override
317324
bool shouldRepaint(_DropdownMenuPainter oldPainter) {
318325
return oldPainter.color != color ||
319326
oldPainter.elevation != elevation ||
320327
oldPainter.selectedIndex != selectedIndex ||
321-
oldPainter.dropdownDecoration != dropdownDecoration ||
322328
oldPainter.itemHeight != itemHeight ||
329+
oldPainter.dropdownDecoration != dropdownDecoration ||
330+
oldPainter.textDirection != textDirection ||
323331
oldPainter.resize != resize;
324332
}
325333
}

packages/dropdown_button2/lib/src/dropdown_route.dart

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
1616
required this.barrierCoversButton,
1717
required this.parentFocusNode,
1818
required this.enableFeedback,
19+
required this.textDirection,
1920
required this.dropdownStyle,
2021
required this.menuItemStyle,
2122
required this.inputDecorationPadding,
@@ -34,6 +35,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
3435
final TextStyle style;
3536
final FocusNode parentFocusNode;
3637
final bool enableFeedback;
38+
final TextDirection? textDirection;
3739
final DropdownStyleData dropdownStyle;
3840
final MenuItemStyleData menuItemStyle;
3941
final EdgeInsets? inputDecorationPadding;
@@ -61,46 +63,49 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
6163

6264
@override
6365
Widget buildPage(BuildContext context, _, __) {
64-
return FocusScope.withExternalFocusNode(
65-
focusScopeNode: _childNode,
66-
parentNode: parentFocusNode,
67-
child: LayoutBuilder(
68-
builder: (BuildContext ctx, BoxConstraints constraints) {
69-
//Exclude BottomInset from maxHeight to avoid overlapping menu items
70-
//with keyboard when using searchable dropdown.
71-
//This will ensure menu is drawn in the actual available height.
72-
final padding = MediaQuery.paddingOf(context);
73-
final viewInsets = MediaQuery.viewInsetsOf(context);
74-
final BoxConstraints actualConstraints =
75-
constraints.copyWith(maxHeight: constraints.maxHeight - viewInsets.bottom);
76-
final EdgeInsets mediaQueryPadding =
77-
dropdownStyle.useSafeArea ? padding : EdgeInsets.zero;
78-
return ValueListenableBuilder<Rect?>(
79-
valueListenable: buttonRect,
80-
builder: (BuildContext context, Rect? rect, _) {
81-
final routePage = _DropdownRoutePage<T>(
82-
route: this,
83-
constraints: actualConstraints,
84-
mediaQueryPadding: mediaQueryPadding,
85-
buttonRect: rect!,
86-
selectedIndex: selectedIndex,
87-
capturedThemes: capturedThemes,
88-
style: style,
89-
enableFeedback: enableFeedback,
90-
);
91-
return barrierCoversButton
92-
? routePage
93-
: _CustomModalBarrier(
94-
barrierColor: _altBarrierColor,
95-
animation: animation,
96-
barrierCurve: barrierCurve,
97-
buttonRect: rect,
98-
buttonBorderRadius: buttonBorderRadius ?? BorderRadius.zero,
99-
child: routePage,
100-
);
101-
},
102-
);
103-
},
66+
return Directionality(
67+
textDirection: textDirection ?? Directionality.of(context),
68+
child: FocusScope.withExternalFocusNode(
69+
focusScopeNode: _childNode,
70+
parentNode: parentFocusNode,
71+
child: LayoutBuilder(
72+
builder: (BuildContext ctx, BoxConstraints constraints) {
73+
//Exclude BottomInset from maxHeight to avoid overlapping menu items
74+
//with keyboard when using searchable dropdown.
75+
//This will ensure menu is drawn in the actual available height.
76+
final padding = MediaQuery.paddingOf(context);
77+
final viewInsets = MediaQuery.viewInsetsOf(context);
78+
final BoxConstraints actualConstraints =
79+
constraints.copyWith(maxHeight: constraints.maxHeight - viewInsets.bottom);
80+
final EdgeInsets mediaQueryPadding =
81+
dropdownStyle.useSafeArea ? padding : EdgeInsets.zero;
82+
return ValueListenableBuilder<Rect?>(
83+
valueListenable: buttonRect,
84+
builder: (BuildContext context, Rect? rect, _) {
85+
final routePage = _DropdownRoutePage<T>(
86+
route: this,
87+
constraints: actualConstraints,
88+
mediaQueryPadding: mediaQueryPadding,
89+
buttonRect: rect!,
90+
selectedIndex: selectedIndex,
91+
capturedThemes: capturedThemes,
92+
style: style,
93+
enableFeedback: enableFeedback,
94+
);
95+
return barrierCoversButton
96+
? routePage
97+
: _CustomModalBarrier(
98+
barrierColor: _altBarrierColor,
99+
animation: animation,
100+
barrierCurve: barrierCurve,
101+
buttonRect: rect,
102+
buttonBorderRadius: buttonBorderRadius ?? BorderRadius.zero,
103+
child: routePage,
104+
);
105+
},
106+
);
107+
},
108+
),
104109
),
105110
);
106111
}

0 commit comments

Comments
 (0)