mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 04:56:48 +00:00
Refresh fix (#436)
* Add notificationPredicate to improve scroll-to-reload Ref: https://api.flutter.dev/flutter/material/RefreshIndicator-class.html * Add scroll-to-refresh for paginated list
This commit is contained in:
parent
8f1cd1cae1
commit
b6ab9d5da5
@ -4,6 +4,7 @@
|
||||
- Add ability to scan in received items using supplier barcodes
|
||||
- Store API token, rather than username:password
|
||||
- Ensure that user will lose access if token is revoked by server
|
||||
- Improve scroll-to-refresh behaviour across multiple widgets
|
||||
|
||||
|
||||
### 0.12.8 - September 2023
|
||||
|
@ -394,31 +394,36 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
children.add(
|
||||
Expanded(
|
||||
child: CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
physics: ClampingScrollPhysics(),
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: <Widget>[
|
||||
PagedSliverList.separated(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<InvenTreeModel>(
|
||||
itemBuilder: (ctx, item, index) {
|
||||
return buildItem(ctx, item);
|
||||
},
|
||||
noItemsFoundIndicatorBuilder: (context) {
|
||||
return NoResultsWidget(noResultsText);
|
||||
}
|
||||
),
|
||||
separatorBuilder: (context, item) => const Divider(height: .1),
|
||||
)
|
||||
]
|
||||
child: CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: <Widget>[
|
||||
PagedSliverList.separated(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<InvenTreeModel>(
|
||||
itemBuilder: (ctx, item, index) {
|
||||
return buildItem(ctx, item);
|
||||
},
|
||||
noItemsFoundIndicatorBuilder: (context) {
|
||||
return NoResultsWidget(noResultsText);
|
||||
}
|
||||
),
|
||||
separatorBuilder: (context, item) => const Divider(height: 1),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return Column(
|
||||
return RefreshIndicator(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: children,
|
||||
),
|
||||
onRefresh: () async {
|
||||
_pagingController.refresh();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ mixin BaseWidgetProperties {
|
||||
*/
|
||||
List<Widget> appBarActions(BuildContext context) => [];
|
||||
|
||||
// Return a title for the appBar
|
||||
// Return a title for the appBar (placeholder)
|
||||
String getAppBarTitle() { return "--- app bar ---"; }
|
||||
|
||||
// Function to construct a drawer (override if needed)
|
||||
@ -40,6 +40,7 @@ mixin BaseWidgetProperties {
|
||||
|
||||
// Default body calls getTiles()
|
||||
return SingleChildScrollView(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
child: Column(
|
||||
children: getTiles(context)
|
||||
)
|
||||
@ -202,7 +203,8 @@ mixin BaseWidgetProperties {
|
||||
*/
|
||||
abstract class RefreshableState<T extends StatefulWidget> extends State<T> with BaseWidgetProperties {
|
||||
|
||||
final refreshableKey = GlobalKey<ScaffoldState>();
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final refreshKey = GlobalKey<RefreshIndicatorState>();
|
||||
|
||||
// Storage for context once "Build" is called
|
||||
late BuildContext? _context;
|
||||
@ -265,19 +267,31 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> with
|
||||
|
||||
Widget body = tabs.isEmpty ? getBody(context) : TabBarView(children: getTabs(context));
|
||||
|
||||
// predicateDepth needs to be different based on the child type
|
||||
// hack, determined experimentally
|
||||
int predicateDepth = 0;
|
||||
|
||||
if (tabs.isNotEmpty) {
|
||||
predicateDepth = 1;
|
||||
}
|
||||
|
||||
Scaffold view = Scaffold(
|
||||
key: refreshableKey,
|
||||
appBar: buildAppBar(context, refreshableKey),
|
||||
key: scaffoldKey,
|
||||
appBar: buildAppBar(context, scaffoldKey),
|
||||
drawer: getDrawer(context),
|
||||
floatingActionButton: buildSpeedDial(context),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.miniEndDocked,
|
||||
body: RefreshIndicator(
|
||||
key: refreshKey,
|
||||
notificationPredicate: (ScrollNotification notification) {
|
||||
return notification.depth == predicateDepth;
|
||||
},
|
||||
onRefresh: () async {
|
||||
refresh(context);
|
||||
},
|
||||
child: body
|
||||
),
|
||||
bottomNavigationBar: buildBottomAppBar(context, refreshableKey),
|
||||
bottomNavigationBar: buildBottomAppBar(context, scaffoldKey),
|
||||
);
|
||||
|
||||
// Default implementation is *not* tabbed
|
||||
|
Loading…
x
Reference in New Issue
Block a user