Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
gm_flutter
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
林生雨
gm_flutter
Commits
ec0284ff
Commit
ec0284ff
authored
Jul 05, 2020
by
林生雨
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commot
parent
8ecd2a5b
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
540 additions
and
8 deletions
+540
-8
LevelOneModel.dart
lib/ClueModel/page/levelOne/LevelOneModel.dart
+1
-0
LevelOnePage.dart
lib/ClueModel/page/levelOne/LevelOnePage.dart
+22
-8
baseRefreshIndicator.dart
lib/commonModel/view/baseRefreshIndicator.dart
+517
-0
No files found.
lib/ClueModel/page/levelOne/LevelOneModel.dart
View file @
ec0284ff
...
@@ -72,4 +72,5 @@ class LevelOneModel extends BaseModel {
...
@@ -72,4 +72,5 @@ class LevelOneModel extends BaseModel {
void
selectTab
(
int
index
)
{
void
selectTab
(
int
index
)
{
}
}
}
}
lib/ClueModel/page/levelOne/LevelOnePage.dart
View file @
ec0284ff
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* @author lsy
* @author lsy
* @date 2020/6/29
* @date 2020/6/29
**/
**/
import
'dart:async'
;
import
'dart:math'
;
import
'dart:math'
;
import
'dart:ui'
;
import
'dart:ui'
;
...
@@ -21,6 +22,7 @@ import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
...
@@ -21,6 +22,7 @@ import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import
'package:gm_flutter/commonModel/base/BaseState.dart'
;
import
'package:gm_flutter/commonModel/base/BaseState.dart'
;
import
'package:gm_flutter/commonModel/bean/Pair.dart'
;
import
'package:gm_flutter/commonModel/bean/Pair.dart'
;
import
'package:gm_flutter/commonModel/util/DartUtil.dart'
;
import
'package:gm_flutter/commonModel/util/DartUtil.dart'
;
import
'package:gm_flutter/commonModel/view/baseRefreshIndicator.dart'
;
import
'package:pull_to_refresh/pull_to_refresh.dart'
;
import
'package:pull_to_refresh/pull_to_refresh.dart'
;
import
'LevelOneBar.dart'
;
import
'LevelOneBar.dart'
;
...
@@ -114,7 +116,18 @@ class LevelOneState extends BaseState<LevelOnePage> {
...
@@ -114,7 +116,18 @@ class LevelOneState extends BaseState<LevelOnePage> {
MediaQuery
.
of
(
context
).
size
.
width
,
MediaQuery
.
of
(
context
).
size
.
width
,
MediaQuery
.
of
(
context
).
size
.
height
,
MediaQuery
.
of
(
context
).
size
.
height
,
_model
.
stateLive
,
_model
.
stateLive
,
newHomeWarp
(),
()
{
Container
(
child:
NestedScrollViewRefreshIndicator
(
onRefresh:
()
async
{
Completer
completer
=
new
Completer
();
_model
.
init
(()
{
setState
(()
{});
completer
.
complete
();
});
return
completer
.
future
;
},
child:
newHomeWarp
()),
),
()
{
_model
.
init
(()
{
_model
.
init
(()
{
setState
(()
{});
setState
(()
{});
});
});
...
@@ -168,7 +181,8 @@ class LevelOneState extends BaseState<LevelOnePage> {
...
@@ -168,7 +181,8 @@ class LevelOneState extends BaseState<LevelOnePage> {
var
d
=
MediaQueryData
.
fromWindow
(
window
).
padding
.
top
;
var
d
=
MediaQueryData
.
fromWindow
(
window
).
padding
.
top
;
for
(
int
i
=
0
;
i
<
_model
.
tabsList
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
_model
.
tabsList
.
length
;
i
++)
{
list
.
add
(
list
.
add
(
LevelOneList
(
planId
,
_model
.
tabsList
[
i
].
tabType
,
kToolbarHeight
+
d
).
toActive
());
LevelOneList
(
planId
,
_model
.
tabsList
[
i
].
tabType
,
kToolbarHeight
+
d
)
.
toActive
());
}
}
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
final
double
pinnedHeaderHeight
=
statusBarHeight
+
kToolbarHeight
;
final
double
pinnedHeaderHeight
=
statusBarHeight
+
kToolbarHeight
;
...
@@ -179,21 +193,21 @@ class LevelOneState extends BaseState<LevelOnePage> {
...
@@ -179,21 +193,21 @@ class LevelOneState extends BaseState<LevelOnePage> {
(
BuildContext
context
,
bool
innerBoxIsScrolled
)
{
(
BuildContext
context
,
bool
innerBoxIsScrolled
)
{
return
<
Widget
>[
return
<
Widget
>[
SliverOverlapAbsorber
(
SliverOverlapAbsorber
(
handle:
handle:
NestedScrollView
.
sliverOverlapAbsorberHandleFor
(
NestedScrollView
.
sliverOverlapAbsorberHandleFor
(
context
),
context
),
sliver:
baseSliverAppBar
(
sliver:
baseSliverAppBar
(
// _model.imageUrl
// _model.imageUrl
"https://pic.igengmei.com/2018/09/11/1513/b7e825a4e4c1-w"
)),
"https://pic.igengmei.com/2018/09/11/1513/b7e825a4e4c1-w"
)),
SliverList
(
SliverList
(
delegate:
SliverChildBuilderDelegate
((
BuildContext
c
,
int
i
)
{
delegate:
if
(
i
==
0
){
SliverChildBuilderDelegate
((
BuildContext
c
,
int
i
)
{
if
(
i
==
0
)
{
return
Container
(
return
Container
(
height:
pinnedHeaderHeight
,
height:
pinnedHeaderHeight
,
);
);
}
}
return
oneList
[
i
-
1
];
return
oneList
[
i
-
1
];
},
childCount:
oneList
.
length
+
1
)),
},
childCount:
oneList
.
length
+
1
)),
SliverPersistentHeader
(
SliverPersistentHeader
(
pinned:
true
,
pinned:
true
,
delegate:
StickyTabBarDelegate
(
delegate:
StickyTabBarDelegate
(
...
...
lib/commonModel/view/baseRefreshIndicator.dart
0 → 100755
View file @
ec0284ff
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:math'
as
math
;
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:gm_flutter/commonModel/GMBase.dart'
;
import
'package:lottie/lottie.dart'
;
// The over-scroll distance that moves the indicator to its maximum
// displacement, as a percentage of the scrollable's container extent.
const
double
_kDragContainerExtentPercentage
=
0.25
;
// How much the scroll's drag gesture can overshoot the RefreshIndicator's
// displacement; max displacement = _kDragSizeFactorLimit * displacement.
const
double
_kDragSizeFactorLimit
=
1.5
;
// When the scroll ends, the duration of the refresh indicator's animation
// to the RefreshIndicator's displacement.
const
Duration
_kIndicatorSnapDuration
=
Duration
(
milliseconds:
150
);
// The duration of the ScaleTransition that starts when the refresh action
// has completed.
const
Duration
_kIndicatorScaleDuration
=
Duration
(
milliseconds:
200
);
/// The signature for a function that's called when the user has dragged a
/// [NestedScrollViewRefreshIndicator] far enough to demonstrate that they want the app to
/// refresh. The returned [Future] must complete when the refresh operation is
/// finished.
///
/// Used by [NestedScrollViewRefreshIndicator.onRefresh].
typedef
NestedScrollViewRefreshCallback
=
Future
<
void
>
Function
();
// The state machine moves through these modes only when the scrollable
// identified by scrollableKey has been scrolled to its min or max limit.
enum
_RefreshIndicatorMode
{
drag
,
// Pointer is down.
armed
,
// Dragged far enough that an up event will run the onRefresh callback.
snap
,
// Animating to the indicator's final "displacement".
refresh
,
// Running the refresh callback.
done
,
// Animating the indicator's fade-out after refreshing.
canceled
,
// Animating the indicator's fade-out after not arming.
}
/// A widget that supports the Material "swipe to refresh" idiom.
///
/// When the child's [Scrollable] descendant overscrolls, an animated circular
/// progress indicator is faded into view. When the scroll ends, if the
/// indicator has been dragged far enough for it to become completely opaque,
/// the [onRefresh] callback is called. The callback is expected to update the
/// scrollable's contents and then complete the [Future] it returns. The refresh
/// indicator disappears after the callback's [Future] has completed.
///
/// If the [Scrollable] might not have enough content to overscroll, consider
/// settings its `physics` property to [AlwaysScrollableScrollPhysics]:
///
/// ```dart
/// ListView(
/// physics: const AlwaysScrollableScrollPhysics(),
/// children: ...
// )
/// ```
///
/// Using [AlwaysScrollableScrollPhysics] will ensure that the scroll view is
/// always scrollable and, therefore, can trigger the [NestedScrollViewRefreshIndicator].
///
/// A [NestedScrollViewRefreshIndicator] can only be used with a vertical scroll view.
///
/// See also:
///
/// * <https://material.google.com/patterns/swipe-to-refresh.html>
/// * [NestedScrollViewRefreshIndicatorState], can be used to programmatically show the refresh indicator.
/// * [RefreshProgressIndicator], widget used by [NestedScrollViewRefreshIndicator] to show
/// the inner circular progress spinner during refreshes.
/// * [CupertinoSliverRefreshControl], an iOS equivalent of the pull-to-refresh pattern.
/// Must be used as a sliver inside a [CustomScrollView] instead of wrapping
/// around a [ScrollView] because it's a part of the scrollable instead of
/// being overlaid on top of it.
class
NestedScrollViewRefreshIndicator
extends
StatefulWidget
{
/// Creates a refresh indicator.
///
/// The [onRefresh], [child], and [notificationPredicate] arguments must be
/// non-null. The default
/// [displacement] is 40.0 logical pixels.
const
NestedScrollViewRefreshIndicator
({
Key
key
,
@required
this
.
child
,
this
.
displacement
=
55.0
,
@required
this
.
onRefresh
,
this
.
color
,
this
.
backgroundColor
,
this
.
notificationPredicate
=
nestedScrollViewScrollNotificationPredicate
,
this
.
semanticsLabel
,
this
.
semanticsValue
,
})
:
assert
(
child
!=
null
),
assert
(
onRefresh
!=
null
),
assert
(
notificationPredicate
!=
null
),
super
(
key:
key
);
/// The widget below this widget in the tree.
///
/// The refresh indicator will be stacked on top of this child. The indicator
/// will appear when child's Scrollable descendant is over-scrolled.
///
/// Typically a [ListView] or [CustomScrollView].
final
Widget
child
;
/// The distance from the child's top or bottom edge to where the refresh
/// indicator will settle. During the drag that exposes the refresh indicator,
/// its actual displacement may significantly exceed this value.
final
double
displacement
;
/// A function that's called when the user has dragged the refresh indicator
/// far enough to demonstrate that they want the app to refresh. The returned
/// [Future] must complete when the refresh operation is finished.
final
NestedScrollViewRefreshCallback
onRefresh
;
/// The progress indicator's foreground color. The current theme's
/// [ThemeData.accentColor] by default.
final
Color
color
;
/// The progress indicator's background color. The current theme's
/// [ThemeData.canvasColor] by default.
final
Color
backgroundColor
;
/// A check that specifies whether a [ScrollNotification] should be
/// handled by this widget.
///
/// By default, checks whether `notification.depth == 0`. Set it to something
/// else for more complicated layouts.
final
ScrollNotificationPredicate
notificationPredicate
;
/// {@macro flutter.material.progressIndicator.semanticsLabel}
///
/// This will be defaulted to [MaterialLocalizations.refreshIndicatorSemanticLabel]
/// if it is null.
final
String
semanticsLabel
;
/// {@macro flutter.material.progressIndicator.semanticsValue}
final
String
semanticsValue
;
@override
NestedScrollViewRefreshIndicatorState
createState
()
=>
NestedScrollViewRefreshIndicatorState
();
}
/// Contains the state for a [NestedScrollViewRefreshIndicator]. This class can be used to
/// programmatically show the refresh indicator, see the [show] method.
class
NestedScrollViewRefreshIndicatorState
extends
State
<
NestedScrollViewRefreshIndicator
>
with
TickerProviderStateMixin
<
NestedScrollViewRefreshIndicator
>
{
AnimationController
_positionController
;
Animation
<
double
>
_positionFactor
;
Animation
<
double
>
_value
;
Animation
<
Color
>
_valueColor
;
_RefreshIndicatorMode
_mode
;
Future
<
void
>
_pendingRefreshFuture
;
bool
_isIndicatorAtTop
;
double
_dragOffset
;
static
final
Animatable
<
double
>
_threeQuarterTween
=
Tween
<
double
>(
begin:
0.0
,
end:
0.75
);
static
final
Animatable
<
double
>
_kDragSizeFactorLimitTween
=
Tween
<
double
>(
begin:
0.0
,
end:
_kDragSizeFactorLimit
);
@override
void
initState
()
{
super
.
initState
();
_positionController
=
AnimationController
(
vsync:
this
);
_positionFactor
=
_positionController
.
drive
(
_kDragSizeFactorLimitTween
);
_value
=
_positionController
.
drive
(
_threeQuarterTween
);
// The "value" of the circular progress indicator during a drag.
}
@override
void
didChangeDependencies
()
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
_valueColor
=
_positionController
.
drive
(
ColorTween
(
begin:
(
widget
.
color
??
theme
.
accentColor
).
withOpacity
(
0.0
),
end:
(
widget
.
color
??
theme
.
accentColor
).
withOpacity
(
1.0
))
.
chain
(
CurveTween
(
curve:
const
Interval
(
0.0
,
1.0
/
_kDragSizeFactorLimit
))),
);
super
.
didChangeDependencies
();
}
@override
void
dispose
()
{
_positionController
.
dispose
();
super
.
dispose
();
}
double
maxContainerExtent
=
0.0
;
bool
_handleScrollNotification
(
ScrollNotification
notification
)
{
if
(!
widget
.
notificationPredicate
(
notification
))
{
return
false
;
}
maxContainerExtent
=
math
.
max
(
notification
.
metrics
.
viewportDimension
,
maxContainerExtent
);
if
(
notification
is
ScrollStartNotification
&&
notification
.
metrics
.
extentBefore
==
0.0
&&
_mode
==
null
&&
_start
(
notification
.
metrics
.
axisDirection
))
{
setState
(()
{
_mode
=
_RefreshIndicatorMode
.
drag
;
});
return
false
;
}
bool
indicatorAtTopNow
;
switch
(
notification
.
metrics
.
axisDirection
)
{
case
AxisDirection
.
down
:
indicatorAtTopNow
=
true
;
break
;
case
AxisDirection
.
up
:
indicatorAtTopNow
=
false
;
break
;
case
AxisDirection
.
left
:
case
AxisDirection
.
right
:
indicatorAtTopNow
=
null
;
break
;
}
if
(
indicatorAtTopNow
!=
_isIndicatorAtTop
)
{
if
(
_mode
==
_RefreshIndicatorMode
.
drag
||
_mode
==
_RefreshIndicatorMode
.
armed
)
_dismiss
(
_RefreshIndicatorMode
.
canceled
);
}
else
if
(
notification
is
ScrollUpdateNotification
)
{
if
(
_mode
==
_RefreshIndicatorMode
.
drag
||
_mode
==
_RefreshIndicatorMode
.
armed
)
{
if
(
notification
.
metrics
.
extentBefore
>
0.0
)
{
_dismiss
(
_RefreshIndicatorMode
.
canceled
);
}
else
{
_dragOffset
-=
notification
.
scrollDelta
;
_checkDragOffset
(
maxContainerExtent
);
}
}
if
(
_mode
==
_RefreshIndicatorMode
.
armed
&&
notification
.
dragDetails
==
null
)
{
// On iOS start the refresh when the Scrollable bounces back from the
// overscroll (ScrollNotification indicating this don't have dragDetails
// because the scroll activity is not directly triggered by a drag).
_show
();
}
}
else
if
(
notification
is
OverscrollNotification
)
{
if
(
_mode
==
_RefreshIndicatorMode
.
drag
||
_mode
==
_RefreshIndicatorMode
.
armed
)
{
_dragOffset
-=
notification
.
overscroll
/
2.0
;
_checkDragOffset
(
maxContainerExtent
);
}
}
else
if
(
notification
is
ScrollEndNotification
)
{
switch
(
_mode
)
{
case
_RefreshIndicatorMode
.
armed
:
_show
();
break
;
case
_RefreshIndicatorMode
.
drag
:
_dismiss
(
_RefreshIndicatorMode
.
canceled
);
break
;
default
:
// do nothing
break
;
}
}
return
false
;
}
bool
_handleGlowNotification
(
OverscrollIndicatorNotification
notification
)
{
if
(
notification
.
depth
!=
0
||
!
notification
.
leading
)
{
return
false
;
}
if
(
_mode
==
_RefreshIndicatorMode
.
drag
)
{
notification
.
disallowGlow
();
return
true
;
}
return
false
;
}
bool
_start
(
AxisDirection
direction
)
{
assert
(
_mode
==
null
);
assert
(
_isIndicatorAtTop
==
null
);
assert
(
_dragOffset
==
null
);
switch
(
direction
)
{
case
AxisDirection
.
down
:
_isIndicatorAtTop
=
true
;
break
;
case
AxisDirection
.
up
:
_isIndicatorAtTop
=
false
;
break
;
case
AxisDirection
.
left
:
case
AxisDirection
.
right
:
_isIndicatorAtTop
=
null
;
// we do not support horizontal scroll views.
return
false
;
}
_dragOffset
=
0.0
;
_positionController
.
value
=
0.0
;
return
true
;
}
void
_checkDragOffset
(
double
containerExtent
)
{
assert
(
_mode
==
_RefreshIndicatorMode
.
drag
||
_mode
==
_RefreshIndicatorMode
.
armed
);
double
newValue
=
_dragOffset
/
(
containerExtent
*
_kDragContainerExtentPercentage
);
if
(
_mode
==
_RefreshIndicatorMode
.
armed
)
newValue
=
math
.
max
(
newValue
,
1.0
/
_kDragSizeFactorLimit
);
_positionController
.
value
=
newValue
.
clamp
(
0.0
,
1.0
)
as
double
;
// this triggers various rebuilds
if
(
_mode
==
_RefreshIndicatorMode
.
drag
&&
_valueColor
.
value
.
alpha
==
0xFF
)
_mode
=
_RefreshIndicatorMode
.
armed
;
}
// Stop showing the refresh indicator.
Future
<
void
>
_dismiss
(
_RefreshIndicatorMode
newMode
)
async
{
await
Future
<
void
>.
value
();
// This can only be called from _show() when refreshing and
// _handleScrollNotification in response to a ScrollEndNotification or
// direction change.
assert
(
newMode
==
_RefreshIndicatorMode
.
canceled
||
newMode
==
_RefreshIndicatorMode
.
done
);
setState
(()
{
_mode
=
newMode
;
});
switch
(
_mode
)
{
case
_RefreshIndicatorMode
.
done
:
break
;
case
_RefreshIndicatorMode
.
canceled
:
await
_positionController
.
animateTo
(
0.0
,
duration:
_kIndicatorScaleDuration
);
break
;
default
:
assert
(
false
);
}
if
(
mounted
&&
_mode
==
newMode
)
{
_dragOffset
=
null
;
_isIndicatorAtTop
=
null
;
setState
(()
{
_mode
=
null
;
});
}
}
void
_show
()
{
assert
(
_mode
!=
_RefreshIndicatorMode
.
refresh
);
assert
(
_mode
!=
_RefreshIndicatorMode
.
snap
);
final
Completer
<
void
>
completer
=
Completer
<
void
>();
_pendingRefreshFuture
=
completer
.
future
;
_mode
=
_RefreshIndicatorMode
.
snap
;
_positionController
.
animateTo
(
1.0
/
_kDragSizeFactorLimit
,
duration:
_kIndicatorSnapDuration
)
.
then
<
void
>((
void
value
)
{
if
(
mounted
&&
_mode
==
_RefreshIndicatorMode
.
snap
)
{
assert
(
widget
.
onRefresh
!=
null
);
setState
(()
{
// Show the indeterminate progress indicator.
_mode
=
_RefreshIndicatorMode
.
refresh
;
});
final
Future
<
void
>
refreshResult
=
widget
.
onRefresh
();
assert
(()
{
if
(
refreshResult
==
null
)
FlutterError
.
reportError
(
FlutterErrorDetails
(
exception:
FlutterError
(
'The onRefresh callback returned null.
\n
'
'The RefreshIndicator onRefresh callback must return a Future.'
),
context:
ErrorDescription
(
'when calling onRefresh'
),
library
:
'material library'
,
));
return
true
;
}());
if
(
refreshResult
==
null
)
{
return
;
}
refreshResult
.
whenComplete
(()
{
if
(
mounted
&&
_mode
==
_RefreshIndicatorMode
.
refresh
)
{
completer
.
complete
();
_dismiss
(
_RefreshIndicatorMode
.
done
);
}
});
}
});
}
/// Show the refresh indicator and run the refresh callback as if it had
/// been started interactively. If this method is called while the refresh
/// callback is running, it quietly does nothing.
///
/// Creating the [NestedScrollViewRefreshIndicator] with a [GlobalKey<RefreshIndicatorState>]
/// makes it possible to refer to the [NestedScrollViewRefreshIndicatorState].
///
/// The future returned from this method completes when the
/// [NestedScrollViewRefreshIndicator.onRefresh] callback's future completes.
///
/// If you await the future returned by this function from a [State], you
/// should check that the state is still [mounted] before calling [setState].
///
/// When initiated in this manner, the refresh indicator is independent of any
/// actual scroll view. It defaults to showing the indicator at the top. To
/// show it at the bottom, set `atTop` to false.
Future
<
void
>
show
({
bool
atTop
=
true
})
{
if
(
_mode
!=
_RefreshIndicatorMode
.
refresh
&&
_mode
!=
_RefreshIndicatorMode
.
snap
)
{
if
(
_mode
==
null
)
{
_start
(
atTop
?
AxisDirection
.
down
:
AxisDirection
.
up
);
}
_show
();
}
return
_pendingRefreshFuture
;
}
final
GlobalKey
_key
=
GlobalKey
();
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterialLocalizations
(
context
));
final
Widget
child
=
NotificationListener
<
ScrollNotification
>(
key:
_key
,
onNotification:
_handleScrollNotification
,
child:
NotificationListener
<
OverscrollIndicatorNotification
>(
onNotification:
_handleGlowNotification
,
child:
widget
.
child
,
),
);
if
(
_mode
==
null
)
{
assert
(
_dragOffset
==
null
);
assert
(
_isIndicatorAtTop
==
null
);
return
child
;
}
assert
(
_dragOffset
!=
null
);
assert
(
_isIndicatorAtTop
!=
null
);
final
bool
showIndeterminateIndicator
=
_mode
==
_RefreshIndicatorMode
.
refresh
||
_mode
==
_RefreshIndicatorMode
.
done
;
return
Column
(
children:
<
Widget
>[
Container
(
child:
SizeTransition
(
axisAlignment:
_isIndicatorAtTop
?
1.0
:
-
1.0
,
sizeFactor:
_positionFactor
,
// this is what brings it down
child:
Container
(
padding:
_isIndicatorAtTop
?
EdgeInsets
.
only
(
top:
widget
.
displacement
)
:
EdgeInsets
.
only
(
bottom:
widget
.
displacement
),
alignment:
_isIndicatorAtTop
?
Alignment
.
topCenter
:
Alignment
.
bottomCenter
,
child:
AnimatedBuilder
(
animation:
_positionController
,
builder:
(
BuildContext
context
,
Widget
child
)
{
return
Container
(
height:
55
,
child:
Lottie
.
asset
(
"assets/smart_refresh_header.json"
,
repeat:
true
,
reverse:
false
),
);
},
),
),
),
),
Expanded
(
child:
child
,
)
],
);
// return Stack(
// children: <Widget>[
// child,
// Positioned(
// top: _isIndicatorAtTop ? 0.0 : null,
// bottom: !_isIndicatorAtTop ? 0.0 : null,
// left: 0.0,
// right: 0.0,
// child: SizeTransition(
// axisAlignment: _isIndicatorAtTop ? 1.0 : -1.0,
// sizeFactor: _positionFactor, // this is what brings it down
// child: Container(
// padding: _isIndicatorAtTop
// ? EdgeInsets.only(top: widget.displacement)
// : EdgeInsets.only(bottom: widget.displacement),
// alignment: _isIndicatorAtTop
// ? Alignment.topCenter
// : Alignment.bottomCenter,
// child: ScaleTransition(
// scale: _scaleFactor,
// child: AnimatedBuilder(
// animation: _positionController,
// builder: (BuildContext context, Widget child) {
// return RefreshProgressIndicator(
// semanticsLabel: widget.semanticsLabel ?? MaterialLocalizations.of(context).refreshIndicatorSemanticLabel,
// semanticsValue: widget.semanticsValue,
// value: showIndeterminateIndicator ? null : _value.value,
// valueColor: _valueColor,
// backgroundColor: widget.backgroundColor,
// );
// },
// ),
// ),
// ),
// ),
// ),
// ],
// );
}
}
//return true so that we can handle inner scroll notification
bool
nestedScrollViewScrollNotificationPredicate
(
ScrollNotification
notification
)
{
return
true
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment