Visitar URL original
add shorthands for scroll physics subclasses in framework (#193082) · suryaKommana2662/flutter@2710ade · GitHub
Skip to content

Commit 2710ade

Browse files
navaronbrackesuryaKommana2662
authored andcommitted
add shorthands for scroll physics subclasses in framework (flutter#193082)
This PR adds dot shorthands via redirecting factories for `ScrollPhysics`, so you can do ```dart ListView.builder( physics: const .alwaysScrollable(), ) ``` I did not add one for `CarouselPhysics`, since that belongs in material_ui, which prevents adding a shorthand for it. Fixes flutter#192989 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [x] 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. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines [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 [flutter/website]: https://github.com/flutter/website [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
1 parent 44f6c5e commit 2710ade

2 files changed

Lines changed: 124 additions & 6 deletions

File tree

‎packages/flutter/lib/src/widgets/scroll_physics.dart‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,29 @@ class ScrollPhysics {
8989
/// Creates an object with the default scroll physics.
9090
const ScrollPhysics({this.parent});
9191

92+
/// Creates an [AlwaysScrollableScrollPhysics] instance.
93+
const factory ScrollPhysics.alwaysScrollable({ScrollPhysics? parent}) =
94+
AlwaysScrollableScrollPhysics;
95+
96+
/// Creates a [BouncingScrollPhysics] instance.
97+
///
98+
/// The [decelerationRate] defaults to [ScrollDecelerationRate.normal].
99+
const factory ScrollPhysics.bouncing({
100+
ScrollPhysics? parent,
101+
ScrollDecelerationRate decelerationRate,
102+
}) = BouncingScrollPhysics;
103+
104+
/// Creates a [ClampingScrollPhysics] instance.
105+
const factory ScrollPhysics.clamping({ScrollPhysics? parent}) = ClampingScrollPhysics;
106+
107+
/// Creates a [NeverScrollableScrollPhysics] instance.
108+
const factory ScrollPhysics.neverScrollable({ScrollPhysics? parent}) =
109+
NeverScrollableScrollPhysics;
110+
111+
/// Creates a [RangeMaintainingScrollPhysics] instance.
112+
const factory ScrollPhysics.rangeMaintaining({ScrollPhysics? parent}) =
113+
RangeMaintainingScrollPhysics;
114+
92115
/// If non-null, determines the default behavior for each method.
93116
///
94117
/// If a subclass of [ScrollPhysics] does not override a method, that subclass
@@ -612,6 +635,7 @@ class ScrollPhysics {
612635
/// if any, and then clamped to the new range.
613636
class RangeMaintainingScrollPhysics extends ScrollPhysics {
614637
/// Creates scroll physics that maintain the scroll position in range.
638+
// Any parameters that are added here should also be forwarded by `ScrollPhysics.rangeMaintaining`.
615639
const RangeMaintainingScrollPhysics({super.parent});
616640

617641
@override
@@ -723,6 +747,9 @@ class RangeMaintainingScrollPhysics extends ScrollPhysics {
723747
/// of different types to get the desired scroll physics.
724748
class BouncingScrollPhysics extends ScrollPhysics {
725749
/// Creates scroll physics that bounce back from the edge.
750+
///
751+
/// The [decelerationRate] defaults to [ScrollDecelerationRate.normal].
752+
// Any parameters that are added here should also be forwarded by `ScrollPhysics.bouncing`.
726753
const BouncingScrollPhysics({
727754
this.decelerationRate = ScrollDecelerationRate.normal,
728755
super.parent,
@@ -937,6 +964,7 @@ class BouncingScrollPhysics extends ScrollPhysics {
937964
class ClampingScrollPhysics extends ScrollPhysics {
938965
/// Creates scroll physics that prevent the scroll offset from exceeding the
939966
/// bounds of the content.
967+
// Any parameters that are added here should also be forwarded by `ScrollPhysics.clamping`.
940968
const ClampingScrollPhysics({super.parent});
941969

942970
@override
@@ -1046,6 +1074,7 @@ class ClampingScrollPhysics extends ScrollPhysics {
10461074
/// found on Android.
10471075
class AlwaysScrollableScrollPhysics extends ScrollPhysics {
10481076
/// Creates scroll physics that always lets the user scroll.
1077+
// Any parameters that are added here should also be forwarded by `ScrollPhysics.alwaysScrollable`.
10491078
const AlwaysScrollableScrollPhysics({super.parent});
10501079

10511080
@override
@@ -1069,6 +1098,7 @@ class AlwaysScrollableScrollPhysics extends ScrollPhysics {
10691098
/// found on Android.
10701099
class NeverScrollableScrollPhysics extends ScrollPhysics {
10711100
/// Creates scroll physics that does not let the user scroll.
1101+
// Any parameters that are added here should also be forwarded by `ScrollPhysics.neverScrollable`.
10721102
const NeverScrollableScrollPhysics({super.parent});
10731103

10741104
@override

‎packages/flutter/test/widgets/scroll_physics_test.dart‎

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -497,17 +497,25 @@ FlutterError
497497
ScrollableState scrollable = tester.state<ScrollableState>(find.byType(Scrollable));
498498
final ScrollPosition firstPosition = scrollable.position;
499499
expect(
500-
(firstPosition.physics as BouncingScrollPhysics).decelerationRate,
501-
ScrollDecelerationRate.normal,
500+
firstPosition.physics,
501+
isA<BouncingScrollPhysics>().having(
502+
(BouncingScrollPhysics bouncingPhysics) => bouncingPhysics.decelerationRate,
503+
'decelerationRate',
504+
ScrollDecelerationRate.normal,
505+
),
502506
);
503507

504508
// Identical configuration should not recreate ScrollPosition.
505509
await tester.pumpWidget(buildScrollable());
506510
scrollable = tester.state<ScrollableState>(find.byType(Scrollable));
507511
expect(scrollable.position, same(firstPosition));
508512
expect(
509-
(scrollable.position.physics as BouncingScrollPhysics).decelerationRate,
510-
ScrollDecelerationRate.normal,
513+
scrollable.position.physics,
514+
isA<BouncingScrollPhysics>().having(
515+
(BouncingScrollPhysics bouncingPhysics) => bouncingPhysics.decelerationRate,
516+
'decelerationRate',
517+
ScrollDecelerationRate.normal,
518+
),
511519
);
512520

513521
// Different decelerationRate should recreate ScrollPosition.
@@ -518,8 +526,12 @@ FlutterError
518526
final ScrollPosition secondPosition = scrollable.position;
519527
expect(secondPosition, isNot(same(firstPosition)));
520528
expect(
521-
(secondPosition.physics as BouncingScrollPhysics).decelerationRate,
522-
ScrollDecelerationRate.fast,
529+
secondPosition.physics,
530+
isA<BouncingScrollPhysics>().having(
531+
(BouncingScrollPhysics bouncingPhysics) => bouncingPhysics.decelerationRate,
532+
'decelerationRate',
533+
ScrollDecelerationRate.fast,
534+
),
523535
);
524536
});
525537

@@ -577,6 +589,82 @@ FlutterError
577589
expect(identical(physicsB1, physicsC2), isTrue);
578590
expect(physicsB1.shouldUpdate(physicsC2), isFalse);
579591
});
592+
593+
test('ScrollPhysics supports shorthands for AlwaysScrollableScrollPhysics', () {
594+
ScrollPhysics physics = const .alwaysScrollable();
595+
596+
expect(physics, isA<AlwaysScrollableScrollPhysics>());
597+
expect(physics.parent, isNull);
598+
599+
physics = const .alwaysScrollable(parent: ClampingScrollPhysics());
600+
601+
expect(physics, isA<AlwaysScrollableScrollPhysics>());
602+
expect(physics.parent, isA<ClampingScrollPhysics>());
603+
});
604+
605+
test('ScrollPhysics supports shorthands for BouncingScrollPhysics', () {
606+
const ScrollPhysics physics = .bouncing();
607+
608+
expect(physics.parent, isNull);
609+
expect(
610+
physics,
611+
isA<BouncingScrollPhysics>().having(
612+
(BouncingScrollPhysics bouncingPhysics) => bouncingPhysics.decelerationRate,
613+
'decelerationRate',
614+
ScrollDecelerationRate.normal,
615+
),
616+
);
617+
618+
const ScrollPhysics physics2 = .bouncing(
619+
parent: ClampingScrollPhysics(),
620+
decelerationRate: ScrollDecelerationRate.fast,
621+
);
622+
expect(
623+
physics2,
624+
isA<BouncingScrollPhysics>().having(
625+
(BouncingScrollPhysics bouncingPhysics) => bouncingPhysics.decelerationRate,
626+
'decelerationRate',
627+
ScrollDecelerationRate.fast,
628+
),
629+
);
630+
expect(physics2.parent, isA<ClampingScrollPhysics>());
631+
});
632+
633+
test('ScrollPhysics supports shorthands for ClampingScrollPhysics', () {
634+
ScrollPhysics physics = const .clamping();
635+
636+
expect(physics, isA<ClampingScrollPhysics>());
637+
expect(physics.parent, isNull);
638+
639+
physics = const .clamping(parent: AlwaysScrollableScrollPhysics());
640+
641+
expect(physics, isA<ClampingScrollPhysics>());
642+
expect(physics.parent, isA<AlwaysScrollableScrollPhysics>());
643+
});
644+
645+
test('ScrollPhysics supports shorthands for NeverScrollableScrollPhysics', () {
646+
ScrollPhysics physics = const .neverScrollable();
647+
648+
expect(physics, isA<NeverScrollableScrollPhysics>());
649+
expect(physics.parent, isNull);
650+
651+
physics = const .neverScrollable(parent: ClampingScrollPhysics());
652+
653+
expect(physics, isA<NeverScrollableScrollPhysics>());
654+
expect(physics.parent, isA<ClampingScrollPhysics>());
655+
});
656+
657+
test('ScrollPhysics supports shorthands for RangeMaintainingScrollPhysics', () {
658+
ScrollPhysics physics = const .rangeMaintaining();
659+
660+
expect(physics, isA<RangeMaintainingScrollPhysics>());
661+
expect(physics.parent, isNull);
662+
663+
physics = const .rangeMaintaining(parent: ClampingScrollPhysics());
664+
665+
expect(physics, isA<RangeMaintainingScrollPhysics>());
666+
expect(physics.parent, isA<ClampingScrollPhysics>());
667+
});
580668
}
581669

582670
class ReactiveScrollPhysics extends ScrollPhysics {

0 commit comments

Comments
 (0)