From 20c40020c088976cb4360b507ad3166aefd80197 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Tue, 9 Jun 2020 10:17:35 +0900 Subject: [PATCH] collection: sloppy scroll physics to improve scale gesture recognition --- lib/widgets/album/thumbnail_collection.dart | 3 ++- lib/widgets/common/sloppy_scroll_physics.dart | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 lib/widgets/common/sloppy_scroll_physics.dart diff --git a/lib/widgets/album/thumbnail_collection.dart b/lib/widgets/album/thumbnail_collection.dart index b515d0af1..d300aa16d 100644 --- a/lib/widgets/album/thumbnail_collection.dart +++ b/lib/widgets/album/thumbnail_collection.dart @@ -12,6 +12,7 @@ import 'package:aves/widgets/album/grid/scaling.dart'; import 'package:aves/widgets/album/grid/tile_extent_manager.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/common/scroll_thumb.dart'; +import 'package:aves/widgets/common/sloppy_scroll_physics.dart'; import 'package:draggable_scrollbar/draggable_scrollbar.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -153,7 +154,7 @@ class _CollectionScrollViewState extends State { primary: true, // workaround to prevent scrolling the app bar away // when there is no content and we use `SliverFillRemaining` - physics: collection.isEmpty ? const NeverScrollableScrollPhysics() : null, + physics: collection.isEmpty ? const NeverScrollableScrollPhysics() : const SloppyScrollPhysics(parent: AlwaysScrollableScrollPhysics()), cacheExtent: widget.cacheExtent, slivers: [ appBar, diff --git a/lib/widgets/common/sloppy_scroll_physics.dart b/lib/widgets/common/sloppy_scroll_physics.dart new file mode 100644 index 000000000..1fbb8f158 --- /dev/null +++ b/lib/widgets/common/sloppy_scroll_physics.dart @@ -0,0 +1,25 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/widgets.dart'; + +class SloppyScrollPhysics extends ScrollPhysics { + const SloppyScrollPhysics({ + this.touchSlopFactor = 1, + ScrollPhysics parent, + }) : super(parent: parent); + + // in [0, 1] + // 0: most reactive but will not let other recognizers accept gestures + // 1: less reactive but gives the most leeway to other recognizers + final double touchSlopFactor; + + @override + SloppyScrollPhysics applyTo(ScrollPhysics ancestor) { + return SloppyScrollPhysics( + touchSlopFactor: touchSlopFactor, + parent: buildParent(ancestor), + ); + } + + @override + double get dragStartDistanceMotionThreshold => kTouchSlop * touchSlopFactor; +}