Added pull to refresh
This commit is contained in:
parent
be48e955c7
commit
a955ecbfc0
7 changed files with 259 additions and 141 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
v2.3.0
|
||||||
|
Added pull to refresh
|
||||||
|
|
||||||
v2.2.0
|
v2.2.0
|
||||||
Added refresh button on error
|
Added refresh button on error
|
||||||
|
|
||||||
|
|
38
lib/components/sliver_persistent_header_padding.dart
Normal file
38
lib/components/sliver_persistent_header_padding.dart
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SliverPersistentHeaderPadding extends StatelessWidget {
|
||||||
|
final double maxHeight;
|
||||||
|
|
||||||
|
const SliverPersistentHeaderPadding({required this.maxHeight});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SliverPersistentHeader(
|
||||||
|
delegate: _SliverPersistentHeaderPaddingDelegate(maxHeight: maxHeight,),
|
||||||
|
floating: false,
|
||||||
|
pinned: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SliverPersistentHeaderPaddingDelegate extends SliverPersistentHeaderDelegate {
|
||||||
|
final double maxHeight;
|
||||||
|
|
||||||
|
const _SliverPersistentHeaderPaddingDelegate({required this.maxHeight});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double get maxExtent => maxHeight;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double get minExtent => 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
|
||||||
|
return oldDelegate.maxExtent != maxExtent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ class TrainInfo extends StatelessWidget {
|
||||||
return TrainInfoErrorMaterial(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,);
|
return TrainInfoErrorMaterial(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TrainInfoMaterial(trainData: snapshot.data!,);
|
return TrainInfoMaterial(trainData: snapshot.data!, refresh: refresh,);
|
||||||
case UiDesign.CUPERTINO:
|
case UiDesign.CUPERTINO:
|
||||||
if ([RefreshFutureBuilderState.none, RefreshFutureBuilderState.waiting].contains(snapshot.state)) {
|
if ([RefreshFutureBuilderState.none, RefreshFutureBuilderState.waiting].contains(snapshot.state)) {
|
||||||
return TrainInfoLoadingCupertino(title: trainNumber.toString(),);
|
return TrainInfoLoadingCupertino(title: trainNumber.toString(),);
|
||||||
|
@ -45,7 +45,7 @@ class TrainInfo extends StatelessWidget {
|
||||||
return TrainInfoErrorCupertino(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,);
|
return TrainInfoErrorCupertino(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TrainInfoCupertino(trainData: snapshot.data!,);
|
return TrainInfoCupertino(trainData: snapshot.data!, refresh: refresh,);
|
||||||
default:
|
default:
|
||||||
throw UnmatchedUiDesignException(uiDesign);
|
throw UnmatchedUiDesignException(uiDesign);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:info_tren/components/cupertino_divider.dart';
|
import 'package:info_tren/components/cupertino_divider.dart';
|
||||||
|
import 'package:info_tren/components/sliver_persistent_header_padding.dart';
|
||||||
import 'package:info_tren/models/train_data.dart' hide State;
|
import 'package:info_tren/models/train_data.dart' hide State;
|
||||||
import 'package:info_tren/models/ui_design.dart';
|
import 'package:info_tren/models/ui_design.dart';
|
||||||
import 'package:info_tren/pages/train_info_page/train_info_constants.dart';
|
import 'package:info_tren/pages/train_info_page/train_info_constants.dart';
|
||||||
|
@ -58,8 +61,9 @@ class TrainInfoErrorCupertino extends TrainInfoError {
|
||||||
|
|
||||||
class TrainInfoCupertino extends StatelessWidget {
|
class TrainInfoCupertino extends StatelessWidget {
|
||||||
final TrainData trainData;
|
final TrainData trainData;
|
||||||
|
final Future Function()? refresh;
|
||||||
|
|
||||||
TrainInfoCupertino({required this.trainData});
|
TrainInfoCupertino({required this.trainData, this.refresh,});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -74,16 +78,82 @@ class TrainInfoCupertino extends StatelessWidget {
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final topPadding = MediaQuery.of(context).padding.top;
|
final topPadding = MediaQuery.of(context).padding.top;
|
||||||
|
|
||||||
|
return NestedScrollView(
|
||||||
|
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||||
|
return [
|
||||||
|
// SliverPadding(
|
||||||
|
// padding: EdgeInsets.only(
|
||||||
|
// top: topPadding,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
SliverPersistentHeaderPadding(maxHeight: topPadding,)
|
||||||
|
];
|
||||||
|
},
|
||||||
|
body: Builder(
|
||||||
|
builder: (context) {
|
||||||
return CustomScrollView(
|
return CustomScrollView(
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
SliverToBoxAdapter(
|
if (refresh != null)
|
||||||
child: Padding(
|
CupertinoSliverRefreshControl(
|
||||||
padding: EdgeInsets.only(
|
builder: (context, mode, pulledExtent, refreshTriggerPullDistance, refreshIndicatorExtent) {
|
||||||
top: topPadding,
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: pulledExtent,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: min(refreshIndicatorExtent, pulledExtent),
|
||||||
|
child: Center(
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
if (mode == RefreshIndicatorMode.inactive) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
else if (mode == RefreshIndicatorMode.done) {
|
||||||
|
return Text('Refreshed!');
|
||||||
|
}
|
||||||
|
else if (mode == RefreshIndicatorMode.drag) {
|
||||||
|
return Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
CupertinoActivityIndicator(animating: false,),
|
||||||
|
Text('Pull to refresh...'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (mode == RefreshIndicatorMode.armed) {
|
||||||
|
return Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
CupertinoActivityIndicator(animating: false,),
|
||||||
|
Text('Release to refresh...'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
CupertinoActivityIndicator(),
|
||||||
|
Text('Refreshing'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
child: Container(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Expanded(child: Container(),),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onRefresh: refresh,
|
||||||
|
),
|
||||||
DisplayTrainID(trainData: trainData,),
|
DisplayTrainID(trainData: trainData,),
|
||||||
DisplayTrainOperator(trainData: trainData,),
|
DisplayTrainOperator(trainData: trainData,),
|
||||||
DisplayTrainRoute(trainData: trainData,),
|
DisplayTrainRoute(trainData: trainData,),
|
||||||
|
@ -155,6 +225,9 @@ class TrainInfoCupertino extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ class ArrivalTime extends StatelessWidget {
|
||||||
|
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final oldDate = DateTime(now.year, now.month, now.day, splits[0], splits[1]);
|
final oldDate = DateTime(now.year, now.month, now.day, splits[0], splits[1]);
|
||||||
final newDate = oldDate.subtract(Duration(minutes: delay));
|
final newDate = oldDate.add(Duration(minutes: delay));
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -398,7 +398,7 @@ class DepartureTime extends StatelessWidget {
|
||||||
|
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final oldDate = DateTime(now.year, now.month, now.day, splits[0], splits[1]);
|
final oldDate = DateTime(now.year, now.month, now.day, splits[0], splits[1]);
|
||||||
final newDate = oldDate.subtract(Duration(minutes: delay));
|
final newDate = oldDate.add(Duration(minutes: delay));
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|
|
@ -59,8 +59,9 @@ bool isSmallScreen(BuildContext context) => MediaQuery.of(context).size.height <
|
||||||
|
|
||||||
class TrainInfoMaterial extends StatelessWidget {
|
class TrainInfoMaterial extends StatelessWidget {
|
||||||
final TrainData trainData;
|
final TrainData trainData;
|
||||||
|
final Future Function()? refresh;
|
||||||
|
|
||||||
TrainInfoMaterial({required this.trainData});
|
TrainInfoMaterial({required this.trainData, this.refresh,});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -80,6 +81,8 @@ class TrainInfoMaterial extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
bottom: false,
|
bottom: false,
|
||||||
|
child: RefreshIndicator(
|
||||||
|
onRefresh: refresh ?? () async {},
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
|
@ -146,6 +149,7 @@ class TrainInfoMaterial extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@ description: O aplicație de vizualizare a datelor puse la dispoziție de Inform
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 2.2.0
|
version: 2.3.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue