Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
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
abdullh.alsoleman
Front-End
Commits
c3a8df1d
Commit
c3a8df1d
authored
Jul 20, 2015
by
Hans Muller
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #122 from HansMuller/shrinking-card
Card Collection dismiss animation
parents
94a4b972
b954e020
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
328 additions
and
135 deletions
+328
-135
block_viewport.dart
packages/flutter/example/widgets/block_viewport.dart
+3
-1
card_collection.dart
packages/flutter/example/widgets/card_collection.dart
+111
-27
block_viewport.dart
packages/flutter/lib/widgets/block_viewport.dart
+185
-93
card.dart
packages/flutter/lib/widgets/card.dart
+3
-1
variable_height_scrollable.dart
packages/flutter/lib/widgets/variable_height_scrollable.dart
+26
-13
No files found.
packages/flutter/example/widgets/block_viewport.dart
View file @
c3a8df1d
...
...
@@ -15,6 +15,7 @@ import 'package:sky/widgets/widget.dart';
class
BlockViewportApp
extends
App
{
BlockViewportLayoutState
layoutState
=
new
BlockViewportLayoutState
();
List
<
double
>
lengths
=
<
double
>[];
double
offset
=
0.0
;
...
...
@@ -96,7 +97,8 @@ class BlockViewportApp extends App {
child:
new
BlockViewport
(
builder:
builder
,
startOffset:
offset
,
token:
lengths
.
length
token:
lengths
.
length
,
layoutState:
layoutState
)
)
),
...
...
packages/flutter/example/widgets/card_collection.dart
View file @
c3a8df1d
...
...
@@ -2,62 +2,145 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/animation/curves.dart'
;
import
'package:sky/base/lerp.dart'
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/theme/colors.dart'
;
import
'package:sky/widgets/animated_component.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/block_viewport.dart'
;
import
'package:sky/widgets/card.dart'
;
import
'package:sky/widgets/dismissable.dart'
;
import
'package:sky/widgets/scaffold.dart'
;
import
'package:sky/widgets/variable_height_scrollable.dart'
;
import
'package:sky/widgets/scaffold.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:sky/widgets/tool_bar.dart'
;
import
'package:sky/widgets/widget.dart'
;
import
'package:sky/theme/colors.dart'
as
colors
;
import
'package:sky/widgets/task_description.dart'
;
class
CardModel
{
CardModel
(
this
.
value
,
this
.
height
,
this
.
color
);
int
value
;
double
height
;
Color
color
;
AnimationPerformance
performance
;
String
get
label
=>
"Item
$value
"
;
String
get
key
=>
value
.
toString
();
bool
operator
==(
other
)
=>
other
is
CardModel
&&
other
.
value
==
value
;
int
get
hashCode
=>
373
*
37
*
value
.
hashCode
;
}
class
ShrinkingCard
extends
AnimatedComponent
{
ShrinkingCard
({
String
key
,
CardModel
this
.
card
,
Function
this
.
onUpdated
,
Function
this
.
onCompleted
})
:
super
(
key:
key
);
CardModel
card
;
Function
onUpdated
;
Function
onCompleted
;
double
get
currentHeight
=>
card
.
performance
.
variable
.
value
;
void
initState
()
{
assert
(
card
.
performance
!=
null
);
card
.
performance
.
addListener
(
handleAnimationProgress
);
watch
(
card
.
performance
);
}
void
handleAnimationProgress
()
{
if
(
card
.
performance
.
isCompleted
)
{
if
(
onCompleted
!=
null
)
onCompleted
();
}
else
if
(
onUpdated
!=
null
)
{
onUpdated
();
}
}
void
syncFields
(
ShrinkingCard
source
)
{
card
=
source
.
card
;
onCompleted
=
source
.
onCompleted
;
onUpdated
=
source
.
onUpdated
;
super
.
syncFields
(
source
);
}
Widget
build
()
=>
new
Container
(
height:
currentHeight
);
}
class
CardCollectionApp
extends
App
{
final
TextStyle
cardLabelStyle
=
new
TextStyle
(
color:
white
,
fontSize:
18.0
,
fontWeight:
bold
);
final
List
<
double
>
cardHeights
=
[
48.0
,
64.0
,
82.0
,
46.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
64.0
,
82.0
,
46.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
64.0
,
82.0
,
46.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
64.0
,
82.0
,
46.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
];
List
<
int
>
visibleCardIndices
;
BlockViewportLayoutState
layoutState
=
new
BlockViewportLayoutState
();
List
<
CardModel
>
cardModels
;
void
initState
()
{
visibleCardIndices
=
new
List
.
generate
(
cardHeights
.
length
,
(
i
)
=>
i
);
List
<
double
>
cardHeights
=
<
double
>[
48.0
,
63.0
,
82.0
,
146.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
63.0
,
82.0
,
146.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
63.0
,
82.0
,
146.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
];
cardModels
=
new
List
.
generate
(
cardHeights
.
length
,
(
i
)
{
Color
color
=
lerpColor
(
Red
[
300
],
Blue
[
900
],
i
/
cardHeights
.
length
);
return
new
CardModel
(
i
,
cardHeights
[
i
],
color
);
});
super
.
initState
();
}
void
dismissCard
(
int
cardIndex
)
{
void
shrinkCard
(
CardModel
card
,
int
index
)
{
if
(
card
.
performance
!=
null
)
return
;
layoutState
.
invalidate
([
index
]);
setState
(()
{
visibleCardIndices
.
remove
(
cardIndex
);
assert
(
card
.
performance
==
null
);
card
.
performance
=
new
AnimationPerformance
()
..
duration
=
const
Duration
(
milliseconds:
300
)
..
variable
=
new
AnimatedType
<
double
>(
card
.
height
+
kCardMargins
.
top
+
kCardMargins
.
bottom
,
end:
0.0
,
curve:
ease
,
interval:
new
Interval
(
0.5
,
1.0
)
)
..
play
();
});
}
Widget
_builder
(
int
index
)
{
if
(
index
>=
visibleCardIndices
.
length
)
void
dismissCard
(
CardModel
card
)
{
if
(
cardModels
.
contains
(
card
))
{
setState
(()
{
cardModels
.
remove
(
card
);
});
}
}
Widget
builder
(
int
index
)
{
if
(
index
>=
cardModels
.
length
)
return
null
;
CardModel
card
=
cardModels
[
index
];
if
(
card
.
performance
!=
null
)
{
return
new
ShrinkingCard
(
key:
card
.
key
,
card:
card
,
onUpdated:
()
{
layoutState
.
invalidate
([
index
]);
},
onCompleted:
()
{
dismissCard
(
card
);
}
);
}
int
cardIndex
=
visibleCardIndices
[
index
];
Color
color
=
lerpColor
(
Red
[
500
],
Blue
[
500
],
cardIndex
/
cardHeights
.
length
);
Widget
label
=
new
Text
(
"Item
${cardIndex}
"
,
style:
cardLabelStyle
);
return
new
Dismissable
(
key:
card
Index
.
toString
()
,
onDismissed:
()
{
dismissCard
(
cardI
ndex
);
},
key:
card
.
key
,
onDismissed:
()
{
shrinkCard
(
card
,
i
ndex
);
},
child:
new
Card
(
color:
color
,
color:
c
ard
.
c
olor
,
child:
new
Container
(
height:
card
Heights
[
cardIndex
]
,
height:
card
.
height
,
padding:
const
EdgeDims
.
all
(
8.0
),
child:
new
Center
(
child:
label
)
child:
new
Center
(
child:
new
Text
(
card
.
label
,
style:
cardLabelStyle
)
)
)
)
);
...
...
@@ -68,16 +151,17 @@ class CardCollectionApp extends App {
padding:
const
EdgeDims
.
symmetric
(
vertical:
12.0
,
horizontal:
8.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
this
).
primarySwatch
[
50
]),
child:
new
VariableHeightScrollable
(
builder:
_builder
,
token:
visibleCardIndices
.
length
builder:
builder
,
token:
cardModels
.
length
,
layoutState:
layoutState
)
);
return
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
colors
.
Blue
,
accentColor:
colors
.
RedAccent
[
200
]
primarySwatch:
Blue
,
accentColor:
RedAccent
[
200
]
),
child:
new
TaskDescription
(
label:
'Cards'
,
...
...
packages/flutter/lib/widgets/block_viewport.dart
View file @
c3a8df1d
This diff is collapsed.
Click to expand it.
packages/flutter/lib/widgets/card.dart
View file @
c3a8df1d
...
...
@@ -5,6 +5,8 @@
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/material.dart'
;
const
EdgeDims
kCardMargins
=
const
EdgeDims
.
all
(
4.0
);
/// A material design card
///
/// <https://www.google.com/design/spec/components/cards.html>
...
...
@@ -16,7 +18,7 @@ class Card extends Component {
Widget
build
()
{
return
new
Container
(
margin:
const
EdgeDims
.
all
(
4.0
)
,
margin:
kCardMargins
,
child:
new
Material
(
color:
color
,
type:
MaterialType
.
card
,
...
...
packages/flutter/lib/widgets/variable_height_scrollable.dart
View file @
c3a8df1d
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:collection'
;
import
'package:sky/animation/scroll_behavior.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/block_viewport.dart'
;
...
...
@@ -14,18 +12,39 @@ class VariableHeightScrollable extends Scrollable {
VariableHeightScrollable
({
String
key
,
this
.
builder
,
this
.
token
this
.
token
,
this
.
layoutState
})
:
super
(
key:
key
);
IndexedBuilder
builder
;
Object
token
;
BlockViewportLayoutState
layoutState
;
// When the token changes the scrollable's contents may have
// changed. Remember as much so that after the new contents
// have been laid out we can adjust the scrollOffset so that
// the last page of content is still visible.
bool
_contentsChanged
=
true
;
void
initState
()
{
assert
(
layoutState
!=
null
);
layoutState
.
removeListener
(
_handleLayoutChanged
);
layoutState
.
addListener
(
_handleLayoutChanged
);
super
.
initState
();
}
void
syncFields
(
VariableHeightScrollable
source
)
{
builder
=
source
.
builder
;
if
(
token
!=
source
.
token
)
_contentsChanged
=
true
;
token
=
source
.
token
;
if
(
layoutState
!=
source
.
layoutState
)
{
// Warning: this is unlikely to be what you intended.
assert
(
source
.
layoutState
!=
null
);
layoutState
==
source
.
layoutState
;
layoutState
.
removeListener
(
_handleLayoutChanged
);
layoutState
.
addListener
(
_handleLayoutChanged
);
}
super
.
syncFields
(
source
);
}
...
...
@@ -36,15 +55,9 @@ class VariableHeightScrollable extends Scrollable {
scrollBehavior
.
containerSize
=
newSize
.
height
;
}
void
_handleLayoutChanged
(
int
firstVisibleChildIndex
,
int
visibleChildCount
,
UnmodifiableListView
<
double
>
childOffsets
,
bool
didReachLastChild
)
{
assert
(
childOffsets
.
length
>
0
);
if
(
didReachLastChild
)
{
scrollBehavior
.
contentsSize
=
childOffsets
.
last
;
void
_handleLayoutChanged
()
{
if
(
layoutState
.
didReachLastChild
)
{
scrollBehavior
.
contentsSize
=
layoutState
.
contentsSize
;
if
(
_contentsChanged
&&
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
{
_contentsChanged
=
false
;
settleScrollOffset
();
...
...
@@ -59,7 +72,7 @@ class VariableHeightScrollable extends Scrollable {
callback:
_handleSizeChanged
,
child:
new
BlockViewport
(
builder:
builder
,
onLayoutChanged:
_handleLayoutChanged
,
layoutState:
layoutState
,
startOffset:
scrollOffset
,
token:
token
)
...
...
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