Unverified Commit 7d19f97d authored by LongCatIsLooong's avatar LongCatIsLooong Committed by GitHub

Fix refresh control in the gallery demo, update comments (#30129)

- Fixed the bug where CupertinoRefreshControl doesn't work in the gallery demo on Android.
- Updated documentation on CupertinoRefreshControl
- Added comments to the gallery demo
- Added concrete examples to ScrollPhysics
parent e57d0ff7
......@@ -48,6 +48,15 @@ class _CupertinoRefreshControlDemoState extends State<CupertinoRefreshControlDem
: CupertinoColors.darkBackgroundGray,
),
child: CustomScrollView(
// If left unspecified, the [CustomScrollView] appends an
// [AlwaysScrollableScrollPhysics]. Behind the scene, the ScrollableState
// will attach that [AlwaysScrollableScrollPhysics] to the output of
// [ScrollConfiguration.of] which will be a [ClampingScrollPhysics]
// on Android.
// To demonstrate the iOS behavior in this demo and to ensure that the list
// always scrolls, we specifically use a [BouncingScrollPhysics] combined
// with a [AlwaysScrollableScrollPhysics]
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
slivers: <Widget>[
CupertinoSliverNavigationBar(
largeTitle: const Text('Refresh'),
......
......@@ -82,6 +82,9 @@ Future<void> smokeDemo(WidgetTester tester, GalleryDemo demo) async {
verifyToStringOutput('debugDumpLayerTree', routeName, RendererBinding.instance?.renderView?.debugLayer?.toStringDeep());
// Scroll the demo around a bit more.
await tester.flingFrom(const Offset(400.0, 300.0), const Offset(0.0, 400.0), 1000.0);
await tester.pump();
await tester.pump(const Duration(milliseconds: 400));
await tester.flingFrom(const Offset(400.0, 300.0), const Offset(-200.0, 0.0), 500.0);
await tester.pump();
await tester.pump(const Duration(milliseconds: 50));
......@@ -90,9 +93,6 @@ Future<void> smokeDemo(WidgetTester tester, GalleryDemo demo) async {
await tester.flingFrom(const Offset(400.0, 300.0), const Offset(100.0, 0.0), 500.0);
await tester.pump();
await tester.pump(const Duration(milliseconds: 400));
await tester.flingFrom(const Offset(400.0, 300.0), const Offset(0.0, 400.0), 1000.0);
await tester.pump();
await tester.pump(const Duration(milliseconds: 400));
// Go back
await tester.pageBack();
......
......@@ -248,8 +248,17 @@ typedef RefreshCallback = Future<void> Function();
/// and the indicator sliver has retracted at least 90% of the way back.
///
/// Can only be used in downward-scrolling vertical lists that overscrolls. In
/// other words, refreshes can't be triggered with lists using
/// [ClampingScrollPhysics].
/// other words, refreshes can't be triggered with [Scrollable]s using
/// [ClampingScrollPhysics] which is the default on Android. To allow overscroll
/// on Android, use an overscrolling physics such as [BouncingScrollPhysics].
/// This can be done via:
///
/// * Providing a [BouncingScrollPhysics] (possibly in combination with a
/// [AlwaysScrollableScrollPhysics]) while constructing the scrollable.
/// * By inserting a [ScrollConfiguration] with [BouncingScrollPhysics] above
/// the scrollable.
/// * By using [CupertinoApp], which always uses a [ScrollConfiguration]
/// with [BouncingScrollPhysics] regardless of platform.
///
/// In a typical application, this sliver should be inserted between the app bar
/// sliver such as [CupertinoSliverNavigationBar] and your main scrollable
......
......@@ -15,6 +15,14 @@ import 'scroll_simulation.dart';
export 'package:flutter/physics.dart' show Simulation, ScrollSpringSimulation, Tolerance;
// Examples can assume:
// class FooScrollPhysics extends ScrollPhysics {
// const FooScrollPhysics({ ScrollPhysics parent }): super(parent: parent);
// }
// class BarScrollPhysics extends ScrollPhysics {
// const BarScrollPhysics({ ScrollPhysics parent }): super(parent: parent);
// }
/// Determines the physics of a [Scrollable] widget.
///
/// For example, determines how the [Scrollable] will behave when the user
......@@ -24,6 +32,9 @@ export 'package:flutter/physics.dart' show Simulation, ScrollSpringSimulation, T
/// velocity are used as the initial conditions for the particle in the
/// simulation. The movement of the particle in the simulation is then used to
/// determine the scroll position for the widget.
///
/// Instead of creating your own subclasses, [parent] can be used to combine
/// [ScrollPhysics] objects of different types to get the desired scroll physics.
@immutable
class ScrollPhysics {
/// Creates an object with the default scroll physics.
......@@ -34,7 +45,16 @@ class ScrollPhysics {
/// If a subclass of [ScrollPhysics] does not override a method, that subclass
/// will inherit an implementation from this base class that defers to
/// [parent]. This mechanism lets you assemble novel combinations of
/// [ScrollPhysics] subclasses at runtime.
/// [ScrollPhysics] subclasses at runtime. For example:
///
/// ```dart
/// BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics())
///
/// ```
/// will result in a [ScrollPhysics] that has the combined behavior
/// of [BouncingScrollPhysics] and [AlwaysScrollableScrollPhysics]:
/// behaviors that are not specified in [BouncingScrollPhysics]
/// (e.g. [shouldAcceptUserOffset]) will defer to [AlwaysScrollableScrollPhysics].
final ScrollPhysics parent;
/// If [parent] is null then return ancestor, otherwise recursively build a
......@@ -60,6 +80,18 @@ class ScrollPhysics {
/// The returned object will combine some of the behaviors from this
/// [ScrollPhysics] instance and some of the behaviors from [ancestor].
///
/// {@tool sample}
///
/// In the following example, the [applyTo] method is used to combine the
/// scroll physics of two [ScrollPhysics] objects, the resulting [ScrollPhysics]
/// `x` has the same behavior as `y`:
///
/// ```dart
/// final FooScrollPhysics x = FooScrollPhysics().applyTo(BarScrollPhysics());
/// const FooScrollPhysics y = FooScrollPhysics(parent: BarScrollPhysics());
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [buildParent], a utility method that's often used to define [applyTo]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment