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
cafea7f5
Commit
cafea7f5
authored
Jan 11, 2016
by
Hans Muller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Floating Action Button transitions
parent
d04e2221
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
228 additions
and
15 deletions
+228
-15
flutter.yaml
examples/material_gallery/flutter.yaml
+1
-0
fab.dart
examples/widgets/fab.dart
+94
-0
flutter.yaml
examples/widgets/flutter.yaml
+2
-0
floating_action_button.dart
...ages/flutter/lib/src/material/floating_action_button.dart
+24
-1
scaffold.dart
packages/flutter/lib/src/material/scaffold.dart
+68
-1
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+13
-13
transitions.dart
packages/flutter/lib/src/widgets/transitions.dart
+26
-0
No files found.
examples/material_gallery/flutter.yaml
View file @
cafea7f5
...
...
@@ -14,3 +14,4 @@ material-design-icons:
-
name
:
action/face
-
name
:
action/language
-
name
:
content/add
-
name
:
content/create
examples/widgets/fab.dart
0 → 100644
View file @
cafea7f5
// Copyright 2015 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
'package:flutter/material.dart'
;
class
_Page
{
_Page
({
this
.
label
,
this
.
color
,
this
.
icon
});
final
String
label
;
final
Map
<
int
,
Color
>
color
;
final
String
icon
;
TabLabel
get
tabLabel
=>
new
TabLabel
(
text:
label
);
bool
get
fabDefined
=>
color
!=
null
&&
icon
!=
null
;
Color
get
fabColor
=>
color
[
400
];
Icon
get
fabIcon
=>
new
Icon
(
icon:
icon
);
Key
get
fabKey
=>
new
ValueKey
<
Color
>(
fabColor
);
}
List
<
_Page
>
_pages
=
<
_Page
>[
new
_Page
(
label:
"Blue"
,
color:
Colors
.
indigo
,
icon:
'content/add'
),
new
_Page
(
label:
"Too"
,
color:
Colors
.
indigo
,
icon:
'content/add'
),
new
_Page
(
label:
"Eco"
,
color:
Colors
.
green
,
icon:
'content/create'
),
new
_Page
(
label:
"No"
),
new
_Page
(
label:
"Teal"
,
color:
Colors
.
teal
,
icon:
'content/add'
),
new
_Page
(
label:
"Red"
,
color:
Colors
.
red
,
icon:
'content/create'
)
];
class
FabApp
extends
StatefulComponent
{
FabApp
();
FabAppState
createState
()
=>
new
FabAppState
();
}
class
FabAppState
extends
State
<
FabApp
>
{
_Page
selectedPage
=
_pages
[
0
];
void
_handleTabSelection
(
_Page
page
)
{
setState
(()
{
selectedPage
=
page
;
});
}
Widget
buildTabView
(
_Page
page
)
{
return
new
Builder
(
builder:
(
BuildContext
context
)
{
final
TextStyle
textStyle
=
new
TextStyle
(
color:
Theme
.
of
(
context
).
primaryColor
,
fontSize:
32.0
,
textAlign:
TextAlign
.
center
);
return
new
Container
(
key:
new
ValueKey
<
String
>(
page
.
label
),
padding:
const
EdgeDims
.
TRBL
(
48.0
,
48.0
,
96.0
,
48.0
),
child:
new
Card
(
child:
new
Center
(
child:
new
Text
(
page
.
label
,
style:
textStyle
)
)
)
);
}
);
}
Widget
build
(
BuildContext
context
)
{
return
new
TabBarSelection
<
_Page
>(
values:
_pages
,
onChanged:
_handleTabSelection
,
child:
new
Scaffold
(
toolBar:
new
ToolBar
(
elevation:
0
,
center:
new
Text
(
'FAB Transition Demo'
),
tabBar:
new
TabBar
<
String
>(
labels:
new
Map
.
fromIterable
(
_pages
,
value:
(
_Page
page
)
=>
page
.
tabLabel
)
)
),
body:
new
TabBarView
(
children:
_pages
.
map
(
buildTabView
).
toList
()),
floatingActionButton:
!
selectedPage
.
fabDefined
?
null
:
new
FloatingActionButton
(
key:
selectedPage
.
fabKey
,
backgroundColor:
selectedPage
.
fabColor
,
child:
selectedPage
.
fabIcon
)
)
);
}
}
void
main
(
)
{
runApp
(
new
MaterialApp
(
title:
'FabApp'
,
routes:
{
'/'
:
(
RouteArguments
args
)
=>
new
FabApp
()
}
));
}
examples/widgets/flutter.yaml
View file @
cafea7f5
...
...
@@ -10,6 +10,8 @@ material-design-icons:
-
name
:
action/home
-
name
:
action/language
-
name
:
action/list
-
name
:
content/add
-
name
:
content/create
-
name
:
device/dvr
-
name
:
editor/format_align_center
-
name
:
editor/format_align_left
...
...
packages/flutter/lib/src/material/floating_action_button.dart
View file @
cafea7f5
...
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/animation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'icon_theme.dart'
;
...
...
@@ -14,6 +15,8 @@ import 'theme.dart';
// http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
const
double
_kSize
=
56.0
;
const
double
_kSizeMini
=
40.0
;
const
Duration
_kChildSegue
=
const
Duration
(
milliseconds:
400
);
const
Interval
_kChildSegueInterval
=
const
Interval
(
0.65
,
1.0
);
class
FloatingActionButton
extends
StatefulComponent
{
const
FloatingActionButton
({
...
...
@@ -37,6 +40,22 @@ class FloatingActionButton extends StatefulComponent {
}
class
_FloatingActionButtonState
extends
State
<
FloatingActionButton
>
{
final
Performance
_childSegue
=
new
Performance
(
duration:
_kChildSegue
);
void
initState
()
{
super
.
initState
();
_childSegue
.
play
();
}
void
didUpdateConfig
(
FloatingActionButton
oldConfig
)
{
super
.
didUpdateConfig
(
oldConfig
);
if
(
Widget
.
canUpdate
(
oldConfig
.
child
,
config
.
child
)
&&
config
.
backgroundColor
==
oldConfig
.
backgroundColor
)
return
;
_childSegue
..
progress
=
0.0
..
play
();
}
bool
_highlight
=
false
;
void
_handleHighlightChanged
(
bool
value
)
{
...
...
@@ -67,11 +86,15 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
child:
new
Center
(
child:
new
IconTheme
(
data:
new
IconThemeData
(
color:
iconThemeColor
),
child:
new
RotationTransition
(
performance:
_childSegue
,
turns:
new
AnimatedValue
<
double
>(-
0.125
,
end:
0.0
,
curve:
_kChildSegueInterval
),
child:
config
.
child
)
)
)
)
)
);
}
}
packages/flutter/lib/src/material/scaffold.dart
View file @
cafea7f5
...
...
@@ -19,6 +19,7 @@ import 'drawer.dart';
import
'icon_button.dart'
;
const
double
_kFloatingActionButtonMargin
=
16.0
;
// TODO(hmuller): should be device dependent
const
Duration
_kFloatingActionButtonSegue
=
const
Duration
(
milliseconds:
400
);
enum
_Child
{
body
,
...
...
@@ -96,6 +97,66 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
bool
shouldRelayout
(
MultiChildLayoutDelegate
oldDelegate
)
=>
false
;
}
class
_FloatingActionButtonTransition
extends
StatefulComponent
{
_FloatingActionButtonTransition
({
Key
key
,
this
.
child
})
:
super
(
key:
key
)
{
assert
(
child
!=
null
);
}
final
Widget
child
;
_FloatingActionButtonTransitionState
createState
()
=>
new
_FloatingActionButtonTransitionState
();
}
class
_FloatingActionButtonTransitionState
extends
State
<
_FloatingActionButtonTransition
>
{
final
Performance
performance
=
new
Performance
(
duration:
_kFloatingActionButtonSegue
);
Widget
oldChild
;
void
initState
()
{
super
.
initState
();
performance
.
play
().
then
((
_
)
{
oldChild
=
null
;
});
}
void
dispose
()
{
performance
.
stop
();
super
.
dispose
();
}
void
didUpdateConfig
(
_FloatingActionButtonTransition
oldConfig
)
{
if
(
Widget
.
canUpdate
(
oldConfig
.
child
,
config
.
child
))
return
;
oldChild
=
oldConfig
.
child
;
performance
..
progress
=
0.0
..
play
().
then
((
_
)
{
oldChild
=
null
;
});
}
Widget
build
(
BuildContext
context
)
{
final
List
<
Widget
>
children
=
new
List
<
Widget
>();
if
(
oldChild
!=
null
)
{
children
.
add
(
new
ScaleTransition
(
scale:
new
AnimatedValue
<
double
>(
1.0
,
end:
0.0
,
curve:
new
Interval
(
0.0
,
0.5
,
curve:
Curves
.
easeIn
)),
performance:
performance
,
child:
oldChild
));
}
children
.
add
(
new
ScaleTransition
(
scale:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
new
Interval
(
0.5
,
1.0
,
curve:
Curves
.
easeIn
)),
performance:
performance
,
child:
config
.
child
));
return
new
Stack
(
children:
children
);
}
}
class
Scaffold
extends
StatefulComponent
{
Scaffold
({
Key
key
,
...
...
@@ -323,7 +384,13 @@ class ScaffoldState extends State<Scaffold> {
if
(
_snackBars
.
isNotEmpty
)
_addIfNonNull
(
children
,
_snackBars
.
first
.
_widget
,
_Child
.
snackBar
);
_addIfNonNull
(
children
,
config
.
floatingActionButton
,
_Child
.
floatingActionButton
);
if
(
config
.
floatingActionButton
!=
null
)
{
Widget
fab
=
new
_FloatingActionButtonTransition
(
key:
new
ValueKey
<
Key
>(
config
.
floatingActionButton
.
key
),
child:
config
.
floatingActionButton
);
children
.
add
(
new
LayoutId
(
child:
fab
,
id:
_Child
.
floatingActionButton
));
}
if
(
config
.
drawer
!=
null
)
{
children
.
add
(
new
LayoutId
(
...
...
packages/flutter/lib/src/widgets/framework.dart
View file @
cafea7f5
...
...
@@ -230,6 +230,11 @@ abstract class Widget {
}
void
debugFillDescription
(
List
<
String
>
description
)
{
}
static
bool
canUpdate
(
Widget
oldWidget
,
Widget
newWidget
)
{
return
oldWidget
.
runtimeType
==
newWidget
.
runtimeType
&&
oldWidget
.
key
==
newWidget
.
key
;
}
}
// TODO(ianh): move the next four classes to below InheritedWidget
...
...
@@ -512,11 +517,6 @@ abstract class InheritedWidget extends _ProxyComponent {
// ELEMENTS
bool
_canUpdate
(
Widget
oldWidget
,
Widget
newWidget
)
{
return
oldWidget
.
runtimeType
==
newWidget
.
runtimeType
&&
oldWidget
.
key
==
newWidget
.
key
;
}
enum
_ElementLifecycle
{
initial
,
active
,
...
...
@@ -691,7 +691,7 @@ abstract class Element<T extends Widget> implements BuildContext {
updateSlotForChild
(
child
,
newSlot
);
return
child
;
}
if
(
_
canUpdate
(
child
.
widget
,
newWidget
))
{
if
(
Widget
.
canUpdate
(
child
.
widget
,
newWidget
))
{
if
(
child
.
slot
!=
newSlot
)
updateSlotForChild
(
child
,
newSlot
);
child
.
update
(
newWidget
);
...
...
@@ -741,7 +741,7 @@ abstract class Element<T extends Widget> implements BuildContext {
assert
(
newWidget
!=
widget
);
assert
(
depth
!=
null
);
assert
(
_active
);
assert
(
_
canUpdate
(
widget
,
newWidget
));
assert
(
Widget
.
canUpdate
(
widget
,
newWidget
));
_widget
=
newWidget
;
}
...
...
@@ -798,7 +798,7 @@ abstract class Element<T extends Widget> implements BuildContext {
Element
element
=
key
.
_currentElement
;
if
(
element
==
null
)
return
null
;
if
(!
_
canUpdate
(
element
.
widget
,
newWidget
))
if
(!
Widget
.
canUpdate
(
element
.
widget
,
newWidget
))
return
null
;
if
(
element
.
_parent
!=
null
&&
!
element
.
_parent
.
detachChild
(
element
))
return
null
;
...
...
@@ -1493,7 +1493,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
Element
oldChild
=
oldChildren
[
childrenTop
];
Widget
newWidget
=
newWidgets
[
childrenTop
];
assert
(
oldChild
.
_debugLifecycleState
==
_ElementLifecycle
.
active
);
if
(!
_
canUpdate
(
oldChild
.
widget
,
newWidget
))
if
(!
Widget
.
canUpdate
(
oldChild
.
widget
,
newWidget
))
break
;
childrenTop
+=
1
;
}
...
...
@@ -1508,7 +1508,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
Element
oldChild
=
oldChildren
[
oldChildrenBottom
];
Widget
newWidget
=
newWidgets
[
newChildrenBottom
];
assert
(
oldChild
.
_debugLifecycleState
==
_ElementLifecycle
.
active
);
if
(!
_
canUpdate
(
oldChild
.
widget
,
newWidget
))
if
(!
Widget
.
canUpdate
(
oldChild
.
widget
,
newWidget
))
break
;
Element
newChild
=
updateChild
(
oldChild
,
newWidget
,
nextSibling
);
assert
(
newChild
.
_debugLifecycleState
==
_ElementLifecycle
.
active
);
...
...
@@ -1543,7 +1543,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
if
(
key
!=
null
)
{
oldChild
=
oldKeyedChildren
[
newWidget
.
key
];
if
(
oldChild
!=
null
)
{
if
(
_
canUpdate
(
oldChild
.
widget
,
newWidget
))
{
if
(
Widget
.
canUpdate
(
oldChild
.
widget
,
newWidget
))
{
// we found a match!
// remove it from oldKeyedChildren so we don't unsync it later
oldKeyedChildren
.
remove
(
key
);
...
...
@@ -1554,7 +1554,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
}
}
}
assert
(
oldChild
==
null
||
_
canUpdate
(
oldChild
.
widget
,
newWidget
));
assert
(
oldChild
==
null
||
Widget
.
canUpdate
(
oldChild
.
widget
,
newWidget
));
Element
newChild
=
updateChild
(
oldChild
,
newWidget
,
nextSibling
);
assert
(
newChild
.
_debugLifecycleState
==
_ElementLifecycle
.
active
);
assert
(
oldChild
==
newChild
||
oldChild
==
null
||
oldChild
.
_debugLifecycleState
!=
_ElementLifecycle
.
active
);
...
...
@@ -1571,7 +1571,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
Element
oldChild
=
oldChildren
[
childrenTop
];
assert
(
oldChild
.
_debugLifecycleState
==
_ElementLifecycle
.
active
);
Widget
newWidget
=
newWidgets
[
childrenTop
];
assert
(
_
canUpdate
(
oldChild
.
widget
,
newWidget
));
assert
(
Widget
.
canUpdate
(
oldChild
.
widget
,
newWidget
));
Element
newChild
=
updateChild
(
oldChild
,
newWidget
,
nextSibling
);
assert
(
newChild
.
_debugLifecycleState
==
_ElementLifecycle
.
active
);
assert
(
oldChild
==
newChild
||
oldChild
==
null
||
oldChild
.
_debugLifecycleState
!=
_ElementLifecycle
.
active
);
...
...
packages/flutter/lib/src/widgets/transitions.dart
View file @
cafea7f5
...
...
@@ -97,6 +97,32 @@ class SlideTransition extends TransitionWithChild {
}
}
class
ScaleTransition
extends
TransitionWithChild
{
ScaleTransition
({
Key
key
,
this
.
scale
,
this
.
alignment
:
const
FractionalOffset
(
0.5
,
0.5
),
PerformanceView
performance
,
Widget
child
})
:
super
(
key:
key
,
performance:
performance
,
child:
child
);
final
AnimatedValue
<
double
>
scale
;
final
FractionalOffset
alignment
;
Widget
buildWithChild
(
BuildContext
context
,
Widget
child
)
{
performance
.
updateVariable
(
scale
);
Matrix4
transform
=
new
Matrix4
.
identity
()
..
scale
(
scale
.
value
,
scale
.
value
);
return
new
Transform
(
transform:
transform
,
alignment:
alignment
,
child:
child
);
}
}
class
RotationTransition
extends
TransitionWithChild
{
RotationTransition
({
Key
key
,
...
...
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