Open dehypnosis opened 2 years ago
Can you give an example
Something i missed to tell is that my component sometimes triggers EasyRefreshController.callRefresh()
in the middle of scrollView, programtically.. in detail when i need to refresh contents after calculate cache datetime, i trigger controller to refresh but sometimes user might already have been scrolled some extent.
So it happens that scrollview animates to top, then indicator animation starts.
I know it is too complicate usecase, and it can be my component's fault. so I just give you a simple diagram.
NestedScrollView(
headerSliverBuilder: SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(_),
sliver: SliverAppBar(
// has flexible title and pinned bottom
)
)
body: NotificationListener( // which moves NestedScrollView's scroll position on CustomScrollView scroll update.
PageView(
EasyRefresh(
CustomScrollView(
SliverPinnedOverlapInjector(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(_)),
<EasyRefreshIndicatorHeader>,
Other slivers..
<EasyRefreshIndicatorFooter>,
)
)
)
)
)
It is fairly incomplete but i think you can guess some potential problems here. Nevertheless i made a custom ScrollPhysics as a workaround to prevent overscrolling while refreshing is ongoing and it fixed UI disrupting.
class ConditionalScrollPhysics extends ScrollPhysics {
const ConditionalScrollPhysics({
required this.parent,
required this.shouldAccept,
}) : super(parent: parent);
@override
final ScrollPhysics parent;
final bool Function(ScrollMetrics position) shouldAccept;
@override
ConditionalScrollPhysics applyTo(ScrollPhysics? ancestor) {
return ConditionalScrollPhysics(
parent: buildParent(ancestor) ?? parent,
shouldAccept: shouldAccept,
);
}
// it prevents user scroll attempts while refreshing
@override
bool shouldAcceptUserOffset(ScrollMetrics position) {
if (!shouldAccept(position)) return false;
return super.shouldAcceptUserOffset(position);
}
// it prevents overscrolling
@override
double applyBoundaryConditions(ScrollMetrics position, double value) {
var s = super.applyBoundaryConditions(position, value);
return max(s, 0);
}
}
and
...
EasyRefresh(
CustomScrollView(
controller: scrollController,
physics: ConditionalScrollPhysics(
parent: RangeMaintainingScrollPhysics(),
shouldAccept: (e) {
return NOT_REFREHSING;
},
),
...
Thank you for the awesome work. I found an issue in latest version 3.0.4
The indicator is being bouncing up and down when i try to scroll while refreshing is ongoing.