Refactor bottom sheet & related widgets (#159257)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> This PR refactors Material's bottom sheet & related widgets. It also replaces internal usage of deprecated types such as `MaterialState` with `WidgetState`. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
85632156c5
commit
0896292e35
@ -15,17 +15,16 @@ import 'bottom_sheet_theme.dart';
|
||||
import 'color_scheme.dart';
|
||||
import 'colors.dart';
|
||||
import 'constants.dart';
|
||||
import 'curves.dart';
|
||||
import 'debug.dart';
|
||||
import 'material.dart';
|
||||
import 'material_localizations.dart';
|
||||
import 'material_state.dart';
|
||||
import 'motion.dart';
|
||||
import 'scaffold.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
const Duration _bottomSheetEnterDuration = Duration(milliseconds: 250);
|
||||
const Duration _bottomSheetExitDuration = Duration(milliseconds: 200);
|
||||
const Curve _modalBottomSheetCurve = decelerateEasing;
|
||||
const Curve _modalBottomSheetCurve = Easing.legacyDecelerate;
|
||||
const double _minFlingVelocity = 700.0;
|
||||
const double _closeProgressThreshold = 0.5;
|
||||
const double _defaultScrollControlDisabledMaxHeightRatio = 9.0 / 16.0;
|
||||
@ -266,11 +265,11 @@ class _BottomSheetState extends State<BottomSheet> {
|
||||
|
||||
bool get _dismissUnderway => widget.animationController!.status == AnimationStatus.reverse;
|
||||
|
||||
Set<MaterialState> dragHandleMaterialState = <MaterialState>{};
|
||||
Set<WidgetState> dragHandleStates = <WidgetState>{};
|
||||
|
||||
void _handleDragStart(DragStartDetails details) {
|
||||
setState(() {
|
||||
dragHandleMaterialState.add(MaterialState.dragged);
|
||||
dragHandleStates.add(WidgetState.dragged);
|
||||
});
|
||||
widget.onDragStart?.call(details);
|
||||
}
|
||||
@ -297,7 +296,7 @@ class _BottomSheetState extends State<BottomSheet> {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
dragHandleMaterialState.remove(MaterialState.dragged);
|
||||
dragHandleStates.remove(WidgetState.dragged);
|
||||
});
|
||||
bool isClosing = false;
|
||||
if (details.velocity.pixelsPerSecond.dy > _minFlingVelocity) {
|
||||
@ -335,12 +334,12 @@ class _BottomSheetState extends State<BottomSheet> {
|
||||
}
|
||||
|
||||
void _handleDragHandleHover(bool hovering) {
|
||||
if (hovering != dragHandleMaterialState.contains(MaterialState.hovered)) {
|
||||
if (hovering != dragHandleStates.contains(WidgetState.hovered)) {
|
||||
setState(() {
|
||||
if (hovering){
|
||||
dragHandleMaterialState.add(MaterialState.hovered);
|
||||
dragHandleStates.add(WidgetState.hovered);
|
||||
} else {
|
||||
dragHandleMaterialState.remove(MaterialState.hovered);
|
||||
dragHandleStates.remove(WidgetState.hovered);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -361,11 +360,11 @@ class _BottomSheetState extends State<BottomSheet> {
|
||||
final bool showDragHandle = widget.showDragHandle ?? (widget.enableDrag && (bottomSheetTheme.showDragHandle ?? false));
|
||||
|
||||
Widget? dragHandle;
|
||||
if (showDragHandle){
|
||||
if (showDragHandle) {
|
||||
dragHandle = _DragHandle(
|
||||
onSemanticsTap: widget.onClosing,
|
||||
handleHover: _handleDragHandleHover,
|
||||
materialState: dragHandleMaterialState,
|
||||
states: dragHandleStates,
|
||||
dragHandleColor: widget.dragHandleColor,
|
||||
dragHandleSize: widget.dragHandleSize,
|
||||
);
|
||||
@ -431,20 +430,18 @@ class _BottomSheetState extends State<BottomSheet> {
|
||||
|
||||
// See scaffold.dart
|
||||
|
||||
typedef _SizeChangeCallback<Size> = void Function(Size size);
|
||||
|
||||
class _DragHandle extends StatelessWidget {
|
||||
const _DragHandle({
|
||||
required this.onSemanticsTap,
|
||||
required this.handleHover,
|
||||
required this.materialState,
|
||||
required this.states,
|
||||
this.dragHandleColor,
|
||||
this.dragHandleSize,
|
||||
});
|
||||
|
||||
final VoidCallback? onSemanticsTap;
|
||||
final ValueChanged<bool> handleHover;
|
||||
final Set<MaterialState> materialState;
|
||||
final Set<WidgetState> states;
|
||||
final Color? dragHandleColor;
|
||||
final Size? dragHandleSize;
|
||||
|
||||
@ -470,8 +467,8 @@ class _DragHandle extends StatelessWidget {
|
||||
width: handleSize.width,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(handleSize.height/2),
|
||||
color: MaterialStateProperty.resolveAs<Color?>(dragHandleColor, materialState)
|
||||
?? MaterialStateProperty.resolveAs<Color?>(bottomSheetTheme.dragHandleColor, materialState)
|
||||
color: WidgetStateProperty.resolveAs<Color?>(dragHandleColor, states)
|
||||
?? WidgetStateProperty.resolveAs<Color?>(bottomSheetTheme.dragHandleColor, states)
|
||||
?? m3Defaults.dragHandleColor,
|
||||
),
|
||||
),
|
||||
@ -491,7 +488,7 @@ class _BottomSheetLayoutWithSizeListener extends SingleChildRenderObjectWidget {
|
||||
super.child,
|
||||
});
|
||||
|
||||
final _SizeChangeCallback<Size> onChildSizeChanged;
|
||||
final ValueChanged<Size> onChildSizeChanged;
|
||||
final double animationValue;
|
||||
final bool isScrollControlled;
|
||||
final double scrollControlDisabledMaxHeightRatio;
|
||||
@ -518,7 +515,7 @@ class _BottomSheetLayoutWithSizeListener extends SingleChildRenderObjectWidget {
|
||||
class _RenderBottomSheetLayoutWithSizeListener extends RenderShiftedBox {
|
||||
_RenderBottomSheetLayoutWithSizeListener({
|
||||
RenderBox? child,
|
||||
required _SizeChangeCallback<Size> onChildSizeChanged,
|
||||
required ValueChanged<Size> onChildSizeChanged,
|
||||
required double animationValue,
|
||||
required bool isScrollControlled,
|
||||
required double scrollControlDisabledMaxHeightRatio,
|
||||
@ -530,9 +527,9 @@ class _RenderBottomSheetLayoutWithSizeListener extends RenderShiftedBox {
|
||||
|
||||
Size _lastSize = Size.zero;
|
||||
|
||||
_SizeChangeCallback<Size> get onChildSizeChanged => _onChildSizeChanged;
|
||||
_SizeChangeCallback<Size> _onChildSizeChanged;
|
||||
set onChildSizeChanged(_SizeChangeCallback<Size> newCallback) {
|
||||
ValueChanged<Size> get onChildSizeChanged => _onChildSizeChanged;
|
||||
ValueChanged<Size> _onChildSizeChanged;
|
||||
set onChildSizeChanged(ValueChanged<Size> newCallback) {
|
||||
if (_onChildSizeChanged == newCallback) {
|
||||
return;
|
||||
}
|
||||
@ -574,50 +571,20 @@ class _RenderBottomSheetLayoutWithSizeListener extends RenderShiftedBox {
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
Size _getSize(BoxConstraints constraints) {
|
||||
return constraints.constrain(constraints.biggest);
|
||||
}
|
||||
@override
|
||||
double computeMinIntrinsicWidth(double height) => 0.0;
|
||||
|
||||
@override
|
||||
double computeMinIntrinsicWidth(double height) {
|
||||
final double width = _getSize(BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite) {
|
||||
return width;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
double computeMaxIntrinsicWidth(double height) => 0.0;
|
||||
|
||||
@override
|
||||
double computeMaxIntrinsicWidth(double height) {
|
||||
final double width = _getSize(BoxConstraints.tightForFinite(height: height)).width;
|
||||
if (width.isFinite) {
|
||||
return width;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
double computeMinIntrinsicHeight(double width) => 0.0;
|
||||
|
||||
@override
|
||||
double computeMinIntrinsicHeight(double width) {
|
||||
final double height = _getSize(BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite) {
|
||||
return height;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
double computeMaxIntrinsicHeight(double width) => 0.0;
|
||||
|
||||
@override
|
||||
double computeMaxIntrinsicHeight(double width) {
|
||||
final double height = _getSize(BoxConstraints.tightForFinite(width: width)).height;
|
||||
if (height.isFinite) {
|
||||
return height;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
Size computeDryLayout(BoxConstraints constraints) {
|
||||
return _getSize(constraints);
|
||||
}
|
||||
Size computeDryLayout(BoxConstraints constraints) => constraints.biggest;
|
||||
|
||||
@override
|
||||
double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) {
|
||||
@ -631,7 +598,7 @@ class _RenderBottomSheetLayoutWithSizeListener extends RenderShiftedBox {
|
||||
return null;
|
||||
}
|
||||
final Size childSize = childConstraints.isTight ? childConstraints.smallest : child.getDryLayout(childConstraints);
|
||||
return result + _getPositionForChild(_getSize(constraints), childSize).dy;
|
||||
return result + _getPositionForChild(constraints.biggest, childSize).dy;
|
||||
}
|
||||
|
||||
BoxConstraints _getConstraintsForChild(BoxConstraints constraints) {
|
||||
@ -650,7 +617,7 @@ class _RenderBottomSheetLayoutWithSizeListener extends RenderShiftedBox {
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
size = _getSize(constraints);
|
||||
size = constraints.biggest;
|
||||
final RenderBox? child = this.child;
|
||||
if (child == null) {
|
||||
return;
|
||||
@ -1137,11 +1104,11 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
||||
|
||||
@override
|
||||
Widget buildModalBarrier() {
|
||||
if (barrierColor.alpha != 0 && !offstage) { // changedInternalState is called if barrierColor or offstage updates
|
||||
assert(barrierColor != barrierColor.withOpacity(0.0));
|
||||
if (barrierColor.a != 0 && !offstage) { // changedInternalState is called if barrierColor or offstage updates
|
||||
assert(barrierColor != barrierColor.withValues(alpha: 0.0));
|
||||
final Animation<Color?> color = animation!.drive(
|
||||
ColorTween(
|
||||
begin: barrierColor.withOpacity(0.0),
|
||||
begin: barrierColor.withValues(alpha: 0.0),
|
||||
end: barrierColor, // changedInternalState is called if barrierColor updates
|
||||
).chain(CurveTween(curve: barrierCurve)), // changedInternalState is called if barrierCurve updates
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user