Skip to content

Commit b409297

Browse files
committed
fix pull to refresh animation
1 parent 00d44f9 commit b409297

File tree

1 file changed

+113
-107
lines changed

1 file changed

+113
-107
lines changed

lib/src/widgets/app_page.dart

Lines changed: 113 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:azure_devops/src/mixins/logger_mixin.dart';
55
import 'package:azure_devops/src/services/azure_api_service.dart';
66
import 'package:azure_devops/src/widgets/empty_page.dart';
77
import 'package:azure_devops/src/widgets/error_page.dart';
8+
import 'package:flutter/foundation.dart';
89
import 'package:flutter/material.dart';
910
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
1011

@@ -194,122 +195,127 @@ class _AppPageStateListenable<T> extends State<AppPage<T>> with AppLogger {
194195
);
195196
}
196197

197-
return Scaffold(
198-
body: ValueListenableBuilder<ApiResponse<T?>?>(
199-
valueListenable: widget.notifier!,
200-
builder: (_, response, __) => Stack(
201-
alignment: Alignment.center,
202-
children: [
203-
SafeArea(
204-
bottom: widget.safeAreaBottom,
205-
child: Scrollbar(
206-
controller: scrollController,
207-
thickness: widget.showScrollbar ? null : 0,
208-
child: SmartRefresher(
209-
controller: _refreshController,
210-
onRefresh: _onRefresh,
211-
onLoading: _onLoading,
212-
enablePullUp: widget.onLoading != null,
213-
footer: CustomFooter(
214-
builder: (context, mode) {
215-
var loadText = '';
216-
switch (mode) {
217-
case LoadStatus.canLoading:
218-
loadText = 'Load more';
219-
case LoadStatus.idle:
220-
loadText = 'Idle';
221-
case LoadStatus.loading:
222-
loadText = 'Loading';
223-
case LoadStatus.noMore:
224-
case LoadStatus.failed:
225-
default:
226-
break;
227-
}
228-
return SizedBox(
229-
height: 48,
230-
child: Center(child: Text(loadText)),
231-
);
232-
},
233-
),
234-
child: CustomScrollView(
235-
controller: scrollController,
236-
slivers: [
237-
SliverAppBar(
238-
title: Text(widget.title),
239-
floating: true,
240-
snap: true,
241-
pinned: widget.fixedAppBar,
242-
actions: actions,
243-
surfaceTintColor: context.themeExtension.background,
244-
scrolledUnderElevation: 0,
245-
expandedHeight: 50,
246-
automaticallyImplyLeading: widget.showBackButton,
247-
bottom: widget.header == null
248-
? null
249-
: _Header(
250-
child: Column(
251-
children: [
252-
const SizedBox(
253-
height: 10,
254-
),
255-
widget.header!(),
256-
const SizedBox(
257-
height: 10,
258-
),
259-
],
198+
return RefreshConfiguration(
199+
springDescription: defaultTargetPlatform == TargetPlatform.android
200+
? SpringDescription.withDurationAndBounce()
201+
: const SpringDescription(mass: 1, stiffness: 364.718677686, damping: 35.2),
202+
child: Scaffold(
203+
body: ValueListenableBuilder<ApiResponse<T?>?>(
204+
valueListenable: widget.notifier!,
205+
builder: (_, response, __) => Stack(
206+
alignment: Alignment.center,
207+
children: [
208+
SafeArea(
209+
bottom: widget.safeAreaBottom,
210+
child: Scrollbar(
211+
controller: scrollController,
212+
thickness: widget.showScrollbar ? null : 0,
213+
child: SmartRefresher(
214+
controller: _refreshController,
215+
onRefresh: _onRefresh,
216+
onLoading: _onLoading,
217+
enablePullUp: widget.onLoading != null,
218+
footer: CustomFooter(
219+
builder: (context, mode) {
220+
var loadText = '';
221+
switch (mode) {
222+
case LoadStatus.canLoading:
223+
loadText = 'Load more';
224+
case LoadStatus.idle:
225+
loadText = 'Idle';
226+
case LoadStatus.loading:
227+
loadText = 'Loading';
228+
case LoadStatus.noMore:
229+
case LoadStatus.failed:
230+
default:
231+
break;
232+
}
233+
return SizedBox(
234+
height: 48,
235+
child: Center(child: Text(loadText)),
236+
);
237+
},
238+
),
239+
child: CustomScrollView(
240+
controller: scrollController,
241+
slivers: [
242+
SliverAppBar(
243+
title: Text(widget.title),
244+
floating: true,
245+
snap: true,
246+
pinned: widget.fixedAppBar,
247+
actions: actions,
248+
surfaceTintColor: context.themeExtension.background,
249+
scrolledUnderElevation: 0,
250+
expandedHeight: 50,
251+
automaticallyImplyLeading: widget.showBackButton,
252+
bottom: widget.header == null
253+
? null
254+
: _Header(
255+
child: Column(
256+
children: [
257+
const SizedBox(
258+
height: 10,
259+
),
260+
widget.header!(),
261+
const SizedBox(
262+
height: 10,
263+
),
264+
],
265+
),
260266
),
261-
),
262-
),
263-
if (widget.header == null)
264-
SliverToBoxAdapter(
265-
child: const SizedBox(
266-
height: 20,
267-
),
268267
),
269-
if (response != null && response.isError)
270-
SliverPadding(
271-
padding: EdgeInsets.only(top: paddingTop),
272-
sliver: SliverToBoxAdapter(
273-
child: ErrorPage(
274-
description: (response.errorResponse?.reasonPhrase?.isEmpty ?? true)
275-
? 'Something went wrong'
276-
: response.errorResponse!.reasonPhrase!,
277-
onRetry: widget.init,
268+
if (widget.header == null)
269+
SliverToBoxAdapter(
270+
child: const SizedBox(
271+
height: 20,
272+
),
273+
),
274+
if (response != null && response.isError)
275+
SliverPadding(
276+
padding: EdgeInsets.only(top: paddingTop),
277+
sliver: SliverToBoxAdapter(
278+
child: ErrorPage(
279+
description: (response.errorResponse?.reasonPhrase?.isEmpty ?? true)
280+
? 'Something went wrong'
281+
: response.errorResponse!.reasonPhrase!,
282+
onRetry: widget.init,
283+
),
278284
),
285+
)
286+
else if (response != null &&
287+
widget.onEmpty != null &&
288+
(response.data is List) &&
289+
(response.data as List).isEmpty)
290+
SliverPadding(
291+
padding: EdgeInsets.only(top: paddingTop),
292+
sliver: SliverToBoxAdapter(
293+
child: EmptyPage(widget: widget, onRefresh: _onRefresh),
294+
),
295+
)
296+
else if (response?.data != null)
297+
SliverPadding(
298+
padding: widget.padding ?? const EdgeInsets.symmetric(horizontal: 16),
299+
sliver: widget.sliverBuilder?.call(widget.notifier!.value!.data!) ??
300+
SliverToBoxAdapter(child: widget.builder!(widget.notifier!.value!.data!)),
279301
),
280-
)
281-
else if (response != null &&
282-
widget.onEmpty != null &&
283-
(response.data is List) &&
284-
(response.data as List).isEmpty)
285-
SliverPadding(
286-
padding: EdgeInsets.only(top: paddingTop),
287-
sliver: SliverToBoxAdapter(
288-
child: EmptyPage(widget: widget, onRefresh: _onRefresh),
302+
SliverToBoxAdapter(
303+
child: const SizedBox(
304+
height: 40,
289305
),
290-
)
291-
else if (response?.data != null)
292-
SliverPadding(
293-
padding: widget.padding ?? const EdgeInsets.symmetric(horizontal: 16),
294-
sliver: widget.sliverBuilder?.call(widget.notifier!.value!.data!) ??
295-
SliverToBoxAdapter(child: widget.builder!(widget.notifier!.value!.data!)),
296306
),
297-
SliverToBoxAdapter(
298-
child: const SizedBox(
299-
height: 40,
300-
),
301-
),
302-
],
307+
],
308+
),
303309
),
304310
),
305311
),
306-
),
307-
if (response == null)
308-
Padding(
309-
padding: EdgeInsets.only(top: paddingTop),
310-
child: const CircularProgressIndicator(),
311-
),
312-
],
312+
if (response == null)
313+
Padding(
314+
padding: EdgeInsets.only(top: paddingTop),
315+
child: const CircularProgressIndicator(),
316+
),
317+
],
318+
),
313319
),
314320
),
315321
);

0 commit comments

Comments
 (0)