DropdownButton route
Aoi-hosizora opened this issue · 6 comments
Aoi-hosizora commented
void _handleTap() {
final RenderBox itemBox = context.findRenderObject()! as RenderBox;
final Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size;
final TextDirection? textDirection = Directionality.of(context);
final EdgeInsetsGeometry menuMargin = ButtonTheme.of(context).alignedDropdown
? _kAlignedMenuMargin
: _kUnalignedMenuMargin;
final List<_MenuItem<T>> menuItems = <_MenuItem<T>>[
for (int index = 0; index < widget.items!.length; index += 1)
_MenuItem<T>(
item: widget.items![index],
onLayout: (Size size) {
// If [_dropdownRoute] is null and onLayout is called, this means
// that performLayout was called on a _DropdownRoute that has not
// left the widget tree but is already on its way out.
//
// Since onLayout is used primarily to collect the desired heights
// of each menu item before laying them out, not having the _DropdownRoute
// collect each item's height to lay out is fine since the route is
// already on its way out.
if (_dropdownRoute == null)
return;
_dropdownRoute!.itemHeights[index] = size.height;
},
)
];
assert(_dropdownRoute == null);
_dropdownRoute = _DropdownRoute<T>(
items: menuItems,
buttonRect: menuMargin.resolve(textDirection).inflateRect(itemRect),
padding: _kMenuItemPadding.resolve(textDirection),
selectedIndex: _selectedIndex ?? 0,
elevation: widget.elevation,
theme: Theme.of(context, shadowThemeOnly: true),
style: _textStyle!,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
itemHeight: widget.itemHeight,
dropdownColor: widget.dropdownColor,
);
Navigator.push(context, _dropdownRoute!).then<void>((_DropdownRouteResult<T>? newValue) {
_removeDropdownRoute();
if (!mounted || newValue == null)
return;
if (widget.onChanged != null)
widget.onChanged!(newValue.result);
});
if (widget.onTap != null) {
widget.onTap!();
}
}
``
Aoi-hosizora commented
// class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>>
@override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return _DropdownRoutePage<T>(
route: this,
constraints: constraints,
items: items,
padding: padding,
buttonRect: buttonRect,
selectedIndex: selectedIndex,
elevation: elevation,
theme: theme,
style: style,
dropdownColor: dropdownColor,
);
}
);
}
Aoi-hosizora commented
// class _DropdownRoutePage<T> extends StatelessWidget
@override
Widget build(BuildContext context) {
assert(debugCheckHasDirectionality(context));
// Computing the initialScrollOffset now, before the items have been laid
// out. This only works if the item heights are effectively fixed, i.e. either
// DropdownButton.itemHeight is specified or DropdownButton.itemHeight is null
// and all of the items' intrinsic heights are less than kMinInteractiveDimension.
// Otherwise the initialScrollOffset is just a rough approximation based on
// treating the items as if their heights were all equal to kMinInteractveDimension.
if (route.scrollController == null) {
final _MenuLimits menuLimits = route.getMenuLimits(buttonRect, constraints.maxHeight, selectedIndex);
route.scrollController = ScrollController(initialScrollOffset: menuLimits.scrollOffset);
}
final TextDirection? textDirection = Directionality.of(context);
Widget menu = _DropdownMenu<T>(
route: route,
padding: padding.resolve(textDirection),
buttonRect: buttonRect,
constraints: constraints,
dropdownColor: dropdownColor,
);
if (theme != null)
menu = Theme(data: theme!, child: menu);
return MediaQuery.removePadding(
context: context,
removeTop: true,
removeBottom: true,
removeLeft: true,
removeRight: true,
child: Builder(
builder: (BuildContext context) {
return CustomSingleChildLayout(
delegate: _DropdownMenuRouteLayout<T>(
buttonRect: buttonRect,
route: route,
textDirection: textDirection,
),
child: menu,
);
},
),
);
}
Aoi-hosizora commented
Aoi-hosizora commented
Animation related: https://flutter.dev/docs/development/ui/animations
Aoi-hosizora commented
Container(
margin: EdgeInsets.only(top: 20),
height: 400,
width: 400,
child: Stack(
children: [
Positioned.fill(
child: GestureDetector(
onTap: () => print(DateTime.now().toString()),
),
),
Positioned(
right: 0,
top: -6,
child: OutlineButton(
child: Text(
'test',
style: TextStyle(color: Colors.white),
),
onPressed: () {
_show = !_show;
if (mounted) setState(() {});
},
),
),
AnimatedPositioned(
left: _show ? 5 : -18,
top: 120,
child: AnimatedOpacity(
opacity: _show ? 1 : 0,
child: Text(
'测\n试\n文\n字',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
duration: Duration(milliseconds: 500),
),
duration: Duration(milliseconds: 500),
curve: Flash(showWhenZero: _show),
),
],
),
color: Colors.black,
)
Aoi-hosizora commented
Done.