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
68c77e37
Unverified
Commit
68c77e37
authored
Apr 04, 2018
by
David Shuckerow
Committed by
GitHub
Apr 04, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a bottom app bar to the floating action button motion demo. (#16196)
parent
b8629bab
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
510 additions
and
157 deletions
+510
-157
bottom_app_bar_demo.dart
...lutter_gallery/lib/demo/material/bottom_app_bar_demo.dart
+500
-0
fab_motion_demo.dart
...es/flutter_gallery/lib/demo/material/fab_motion_demo.dart
+0
-147
material.dart
examples/flutter_gallery/lib/demo/material/material.dart
+1
-1
item.dart
examples/flutter_gallery/lib/gallery/item.dart
+7
-7
floating_action_button_location.dart
...ter/lib/src/material/floating_action_button_location.dart
+2
-2
No files found.
examples/flutter_gallery/lib/demo/material/bottom_app_bar_demo.dart
0 → 100644
View file @
68c77e37
// Copyright 2018 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/foundation.dart'
;
import
'package:flutter/material.dart'
;
class
BottomAppBarDemo
extends
StatefulWidget
{
static
const
String
routeName
=
'/material/bottom_app_bar'
;
@override
State
createState
()
=>
new
_BottomAppBarDemoState
();
}
class
_BottomAppBarDemoState
extends
State
<
BottomAppBarDemo
>
{
// The key given to the Scaffold so that _showSnackbar can find it.
static
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
// The index of the currently-selected _FabLocationConfiguration.
int
fabLocationIndex
=
1
;
static
const
List
<
_FabLocationConfiguration
>
_fabLocationConfigurations
=
const
<
_FabLocationConfiguration
>[
const
_FabLocationConfiguration
(
'End, undocked above the bottom app bar'
,
_BabMode
.
END_FAB
,
FloatingActionButtonLocation
.
endFloat
),
const
_FabLocationConfiguration
(
'End, docked to the bottom app bar'
,
_BabMode
.
END_FAB
,
FloatingActionButtonLocation
.
endDocked
),
const
_FabLocationConfiguration
(
'Center, docked to the bottom app bar'
,
_BabMode
.
CENTER_FAB
,
FloatingActionButtonLocation
.
centerDocked
),
const
_FabLocationConfiguration
(
'Center, undocked above the bottom app bar'
,
_BabMode
.
CENTER_FAB
,
FloatingActionButtonLocation
.
centerFloat
),
// This configuration uses a custom FloatingActionButtonLocation.
const
_FabLocationConfiguration
(
'Start, docked to the top app bar'
,
_BabMode
.
CENTER_FAB
,
const
_StartTopFloatingActionButtonLocation
()),
];
// The index of the currently-selected _FabShapeConfiguration.
int
fabShapeIndex
=
1
;
static
const
List
<
_FabShapeConfiguration
>
_fabShapeConfigurations
=
const
<
_FabShapeConfiguration
>[
const
_FabShapeConfiguration
(
'None'
,
null
),
const
_FabShapeConfiguration
(
'Circular'
,
const
FloatingActionButton
(
onPressed:
_showSnackbar
,
child:
const
Icon
(
Icons
.
add
),
backgroundColor:
Colors
.
orange
,
),
),
const
_FabShapeConfiguration
(
'Diamond'
,
const
_DiamondFab
(
onPressed:
_showSnackbar
,
child:
const
Icon
(
Icons
.
add
),
),
),
];
// The currently-selected Color for the Bottom App Bar.
Color
babColor
;
static
const
List
<
Color
>
babColors
=
const
<
Color
>
[
null
,
Colors
.
orange
,
Colors
.
green
,
Colors
.
lightBlue
,
];
// Whether or not to show a notch in the Bottom App Bar around the
// Floating Action Button when it is docked.
bool
notchEnabled
=
true
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
key:
_scaffoldKey
,
appBar:
new
AppBar
(
title:
const
Text
(
'Bottom App Bar with FAB location'
),
// Add 48dp of space onto the bottom of the appbar.
// This gives space for the top-start location to attach to without
// blocking the 'back' button.
bottom:
const
PreferredSize
(
preferredSize:
const
Size
.
fromHeight
(
48.0
),
child:
const
SizedBox
(),
),
),
body:
new
SingleChildScrollView
(
padding:
const
EdgeInsets
.
all
(
16.0
),
child:
buildControls
(
context
),
),
bottomNavigationBar:
new
_DemoBottomAppBar
(
_fabLocationConfigurations
[
fabLocationIndex
].
babMode
,
babColor
,
notchEnabled
),
floatingActionButton:
_fabShapeConfigurations
[
fabShapeIndex
].
fab
,
floatingActionButtonLocation:
_fabLocationConfigurations
[
fabLocationIndex
].
fabLocation
,
);
}
Widget
buildControls
(
BuildContext
context
)
{
return
new
Column
(
children:
<
Widget
>
[
new
Text
(
'Floating action button'
,
style:
Theme
.
of
(
context
).
textTheme
.
title
,
),
new
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
<
Widget
>[
const
SizedBox
(
width:
96.0
,
child:
const
Text
(
'Shape: '
),
),
new
Expanded
(
child:
buildFabShapePicker
()),
],
),
new
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
<
Widget
>[
const
SizedBox
(
width:
96.0
,
child:
const
Text
(
'Location: '
),
),
new
Expanded
(
child:
buildFabLocationPicker
()),
],
),
const
Divider
(),
new
Text
(
'Bottom app bar options'
,
style:
Theme
.
of
(
context
).
textTheme
.
title
,
),
buildBabColorPicker
(),
new
CheckboxListTile
(
title:
const
Text
(
'Enable notch'
),
value:
notchEnabled
,
onChanged:
(
bool
value
)
{
setState
(()
{
notchEnabled
=
value
;
});
},
controlAffinity:
ListTileControlAffinity
.
leading
,
),
],
);
}
Widget
buildFabShapePicker
()
{
return
new
Padding
(
padding:
const
EdgeInsets
.
all
(
8.0
),
child:
new
RaisedButton
(
child:
const
Text
(
'Change'
),
onPressed:
()
{
setState
(()
{
fabShapeIndex
=
(
fabShapeIndex
+
1
)
%
_fabShapeConfigurations
.
length
;
});
},
),
);
}
Widget
buildFabLocationPicker
()
{
return
new
Padding
(
padding:
const
EdgeInsets
.
all
(
8.0
),
child:
new
RaisedButton
(
child:
const
Text
(
'Move'
),
onPressed:
()
{
setState
(()
{
fabLocationIndex
=
(
fabLocationIndex
+
1
)
%
_fabLocationConfigurations
.
length
;
});
},
),
);
}
Widget
buildBabColorPicker
()
{
final
List
<
Widget
>
colors
=
<
Widget
>
[
const
Text
(
'Color:'
),
];
for
(
Color
color
in
babColors
)
{
colors
.
add
(
new
Radio
<
Color
>(
value:
color
,
groupValue:
babColor
,
onChanged:
(
Color
color
)
{
setState
(()
{
babColor
=
color
;
});
},
),
);
colors
.
add
(
new
Container
(
decoration:
new
BoxDecoration
(
color:
color
,
border:
new
Border
.
all
(
width:
2.0
,
color:
Colors
.
black
),
),
child:
const
SizedBox
(
width:
20.0
,
height:
20.0
),
),
);
colors
.
add
(
const
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
12.0
)));
}
return
new
Row
(
children:
colors
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
);
}
static
void
_showSnackbar
()
{
_scaffoldKey
.
currentState
.
showSnackBar
(
const
SnackBar
(
content:
const
Text
(
_explanatoryText
)),
);
}
}
const
String
_explanatoryText
=
"When the Scaffold's floating action button location changes, "
'the floating action button animates to its new position.'
'The BottomAppBar adapts its shape appropriately.'
;
// Whether the Bottom App Bar's menu should keep icons away from the center or from the end of the screen.
//
// When the Floating Action Button is positioned at the end of the screen,
// it would cover icons at the end of the screen, so the END_FAB mode tells
// the MyBottomAppBar to place icons away from the end.
//
// Similar logic applies to the CENTER_FAB mode.
enum
_BabMode
{
END_FAB
,
CENTER_FAB
,
}
// Pairs the Bottom App Bar's menu mode with a Floating Action Button Location.
class
_FabLocationConfiguration
{
const
_FabLocationConfiguration
(
this
.
name
,
this
.
babMode
,
this
.
fabLocation
);
// The name of this configuration.
final
String
name
;
// The _BabMode to place the menu in the bab with.
final
_BabMode
babMode
;
// The location for the Floating Action Button.
final
FloatingActionButtonLocation
fabLocation
;
}
// Map of names to the different shapes of Floating Action Button in this demo.
class
_FabShapeConfiguration
{
const
_FabShapeConfiguration
(
this
.
name
,
this
.
fab
);
final
String
name
;
final
Widget
fab
;
}
// A bottom app bar with a menu inside it.
class
_DemoBottomAppBar
extends
StatelessWidget
{
const
_DemoBottomAppBar
(
this
.
babMode
,
this
.
color
,
this
.
enableNotch
);
final
_BabMode
babMode
;
final
Color
color
;
final
bool
enableNotch
;
final
Curve
fadeOutCurve
=
const
Interval
(
0.0
,
0.3333
);
final
Curve
fadeInCurve
=
const
Interval
(
0.3333
,
1.0
);
@override
Widget
build
(
BuildContext
context
)
{
final
bool
showsFirst
=
babMode
==
_BabMode
.
END_FAB
;
return
new
BottomAppBar
(
color:
color
,
hasNotch:
enableNotch
,
child:
new
Row
(
children:
<
Widget
>
[
new
IconButton
(
icon:
const
Icon
(
Icons
.
menu
),
onPressed:
()
{
showModalBottomSheet
<
Null
>(
context:
context
,
builder:
(
BuildContext
context
)
=>
const
_DemoDrawer
());
},
),
new
Expanded
(
child:
new
AnimatedCrossFade
(
duration:
const
Duration
(
milliseconds:
225
),
firstChild:
buildBabContents
(
context
,
_BabMode
.
END_FAB
),
firstCurve:
showsFirst
?
fadeOutCurve
:
fadeInCurve
,
secondChild:
buildBabContents
(
context
,
_BabMode
.
CENTER_FAB
),
secondCurve:
showsFirst
?
fadeInCurve
:
fadeOutCurve
,
crossFadeState:
showsFirst
?
CrossFadeState
.
showFirst
:
CrossFadeState
.
showSecond
,
),
),
],
),
);
}
Widget
buildBabContents
(
BuildContext
context
,
_BabMode
babMode
)
{
final
List
<
Widget
>
rowContents
=
<
Widget
>
[];
if
(
babMode
==
_BabMode
.
CENTER_FAB
)
{
rowContents
.
add
(
new
Expanded
(
child:
new
ConstrainedBox
(
constraints:
const
BoxConstraints
(
maxHeight:
0.0
),
),
),
);
}
rowContents
.
addAll
(<
Widget
>
[
new
IconButton
(
icon:
const
Icon
(
Icons
.
search
),
onPressed:
()
{},
),
new
IconButton
(
icon:
const
Icon
(
Icons
.
more_vert
),
onPressed:
()
{},
)
]);
return
new
Row
(
children:
rowContents
,
);
}
}
// A drawer that pops up from the bottom of the screen.
class
_DemoDrawer
extends
StatelessWidget
{
const
_DemoDrawer
();
@override
Widget
build
(
BuildContext
context
)
{
return
new
Drawer
(
child:
new
Column
(
children:
const
<
Widget
>[
const
ListTile
(
leading:
const
Icon
(
Icons
.
search
),
title:
const
Text
(
'Search'
),
),
const
ListTile
(
leading:
const
Icon
(
Icons
.
threed_rotation
),
title:
const
Text
(
'3D'
),
),
],
),
);
}
}
// A diamond-shaped floating action button.
class
_DiamondFab
extends
StatefulWidget
{
const
_DiamondFab
({
this
.
child
,
this
.
notchMargin
:
6.0
,
this
.
onPressed
,
});
final
Widget
child
;
final
double
notchMargin
;
final
VoidCallback
onPressed
;
@override
State
createState
()
=>
new
_DiamondFabState
();
}
class
_DiamondFabState
extends
State
<
_DiamondFab
>
{
VoidCallback
_clearComputeNotch
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
Material
(
shape:
const
_DiamondBorder
(),
color:
Colors
.
orange
,
child:
new
InkWell
(
onTap:
widget
.
onPressed
,
child:
new
Container
(
width:
56.0
,
height:
56.0
,
child:
IconTheme
.
merge
(
data:
new
IconThemeData
(
color:
Theme
.
of
(
context
).
accentIconTheme
.
color
),
child:
widget
.
child
,
),
),
),
elevation:
6.0
,
);
}
@override
void
didChangeDependencies
()
{
super
.
didChangeDependencies
();
_clearComputeNotch
=
Scaffold
.
setFloatingActionButtonNotchFor
(
context
,
_computeNotch
);
}
@override
void
deactivate
()
{
if
(
_clearComputeNotch
!=
null
)
_clearComputeNotch
();
super
.
deactivate
();
}
Path
_computeNotch
(
Rect
host
,
Rect
guest
,
Offset
start
,
Offset
end
)
{
final
Rect
marginedGuest
=
guest
.
inflate
(
widget
.
notchMargin
);
if
(!
host
.
overlaps
(
marginedGuest
))
return
new
Path
()..
lineTo
(
end
.
dx
,
end
.
dy
);
final
Rect
intersection
=
marginedGuest
.
intersect
(
host
);
// We are computing a "V" shaped notch, as in this diagram:
// -----\**** /-----
// \ /
// \ /
// \ /
//
// "-" marks the top edge of the bottom app bar.
// "\" and "/" marks the notch outline
//
// notchToCenter is the horizontal distance between the guest's center and
// the host's top edge where the notch starts (marked with "*").
// We compute notchToCenter by similar triangles:
final
double
notchToCenter
=
intersection
.
height
*
(
marginedGuest
.
height
/
2.0
)
/
(
marginedGuest
.
width
/
2.0
);
return
new
Path
()
..
lineTo
(
marginedGuest
.
center
.
dx
-
notchToCenter
,
host
.
top
)
..
lineTo
(
marginedGuest
.
left
+
marginedGuest
.
width
/
2.0
,
marginedGuest
.
bottom
)
..
lineTo
(
marginedGuest
.
center
.
dx
+
notchToCenter
,
host
.
top
)
..
lineTo
(
end
.
dx
,
end
.
dy
);
}
}
class
_DiamondBorder
extends
ShapeBorder
{
const
_DiamondBorder
();
@override
EdgeInsetsGeometry
get
dimensions
{
return
const
EdgeInsets
.
only
();
}
@override
Path
getInnerPath
(
Rect
rect
,
{
TextDirection
textDirection
})
{
return
getOuterPath
(
rect
,
textDirection:
textDirection
);
}
@override
Path
getOuterPath
(
Rect
rect
,
{
TextDirection
textDirection
})
{
return
new
Path
()
..
moveTo
(
rect
.
left
+
rect
.
width
/
2.0
,
rect
.
top
)
..
lineTo
(
rect
.
right
,
rect
.
top
+
rect
.
height
/
2.0
)
..
lineTo
(
rect
.
left
+
rect
.
width
/
2.0
,
rect
.
bottom
)
..
lineTo
(
rect
.
left
,
rect
.
top
+
rect
.
height
/
2.0
)
..
close
();
}
@override
void
paint
(
Canvas
canvas
,
Rect
rect
,
{
TextDirection
textDirection
})
{}
// This border doesn't support scaling.
@override
ShapeBorder
scale
(
double
t
)
{
return
null
;
}
}
// Places the Floating Action Button at the top of the content area of the
// app, on the border between the body and the app bar.
class
_StartTopFloatingActionButtonLocation
extends
FloatingActionButtonLocation
{
const
_StartTopFloatingActionButtonLocation
();
@override
Offset
getOffset
(
ScaffoldPrelayoutGeometry
scaffoldGeometry
)
{
// First, we'll place the X coordinate for the Floating Action Button
// at the start of the screen, based on the text direction.
double
fabX
;
assert
(
scaffoldGeometry
.
textDirection
!=
null
);
switch
(
scaffoldGeometry
.
textDirection
)
{
case
TextDirection
.
rtl
:
// In RTL layouts, the start of the screen is on the right side,
// and the end of the screen is on the left.
//
// We need to align the right edge of the floating action button with
// the right edge of the screen, then move it inwards by the designated padding.
//
// The Scaffold's origin is at its top-left, so we need to offset fabX
// by the Scaffold's width to get the right edge of the screen.
//
// The Floating Action Button's origin is at its top-left, so we also need
// to subtract the Floating Action Button's width to align the right edge
// of the Floating Action Button instead of the left edge.
final
double
startPadding
=
kFloatingActionButtonMargin
+
scaffoldGeometry
.
minInsets
.
right
;
fabX
=
scaffoldGeometry
.
scaffoldSize
.
width
-
scaffoldGeometry
.
floatingActionButtonSize
.
width
-
startPadding
;
break
;
case
TextDirection
.
ltr
:
// In LTR layouts, the start of the screen is on the left side,
// and the end of the screen is on the right.
//
// Placing the fabX at 0.0 will align the left edge of the
// Floating Action Button with the left edge of the screen, so all
// we need to do is offset fabX by the designated padding.
final
double
startPadding
=
kFloatingActionButtonMargin
+
scaffoldGeometry
.
minInsets
.
left
;
fabX
=
startPadding
;
break
;
}
// Finally, we'll place the Y coordinate for the Floating Action Button
// at the top of the content body.
//
// We want to place the middle of the Floating Action Button on the
// border between the Scaffold's app bar and its body. To do this,
// we place fabY at the scaffold geometry's contentTop, then subtract
// half of the Floating Action Button's height to place the center
// over the contentTop.
//
// We don't have to worry about which way is the top like we did
// for left and right, so we place fabY in this one-liner.
final
double
fabY
=
scaffoldGeometry
.
contentTop
-
(
scaffoldGeometry
.
floatingActionButtonSize
.
height
/
2.0
);
return
new
Offset
(
fabX
,
fabY
);
}
}
examples/flutter_gallery/lib/demo/material/fab_motion_demo.dart
deleted
100644 → 0
View file @
b8629bab
// Copyright 2018 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'
;
const
String
_explanatoryText
=
"When the Scaffold's floating action button location changes, "
'the floating action button animates to its new position'
;
class
FabMotionDemo
extends
StatefulWidget
{
static
const
String
routeName
=
'/material/fab-motion'
;
@override
_FabMotionDemoState
createState
()
{
return
new
_FabMotionDemoState
();
}
}
class
_FabMotionDemoState
extends
State
<
FabMotionDemo
>
{
static
const
List
<
FloatingActionButtonLocation
>
_floatingActionButtonLocations
=
const
<
FloatingActionButtonLocation
>[
FloatingActionButtonLocation
.
endFloat
,
FloatingActionButtonLocation
.
centerFloat
,
const
_StartTopFloatingActionButtonLocation
(),
];
bool
_showFab
=
true
;
FloatingActionButtonLocation
_floatingActionButtonLocation
=
FloatingActionButtonLocation
.
endFloat
;
@override
Widget
build
(
BuildContext
context
)
{
final
Widget
floatingActionButton
=
_showFab
?
new
Builder
(
builder:
(
BuildContext
context
)
{
// We use a widget builder here so that this inner context can find the Scaffold.
// This makes it possible to show the snackbar.
return
new
FloatingActionButton
(
backgroundColor:
Colors
.
yellow
.
shade900
,
onPressed:
()
=>
_showSnackbar
(
context
),
child:
const
Icon
(
Icons
.
add
),
);
})
:
null
;
return
new
Scaffold
(
appBar:
new
AppBar
(
title:
const
Text
(
'FAB Location'
),
// Add 48dp of space onto the bottom of the appbar.
// This gives space for the top-start location to attach to without
// blocking the 'back' button.
bottom:
const
PreferredSize
(
preferredSize:
const
Size
.
fromHeight
(
48.0
),
child:
const
SizedBox
(),
),
),
floatingActionButtonLocation:
_floatingActionButtonLocation
,
floatingActionButton:
floatingActionButton
,
body:
new
Center
(
child:
new
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
new
RaisedButton
(
onPressed:
_moveFab
,
child:
const
Text
(
'MOVE FAB'
),
),
new
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
const
Text
(
'Toggle FAB'
),
new
Switch
(
value:
_showFab
,
onChanged:
_toggleFab
),
],
),
],
),
),
);
}
void
_moveFab
()
{
setState
(()
{
_floatingActionButtonLocation
=
_floatingActionButtonLocations
[(
_floatingActionButtonLocations
.
indexOf
(
_floatingActionButtonLocation
)
+
1
)
%
_floatingActionButtonLocations
.
length
];
});
}
void
_toggleFab
(
bool
showFab
)
{
setState
(()
{
_showFab
=
showFab
;
});
}
void
_showSnackbar
(
BuildContext
context
)
{
Scaffold
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
const
Text
(
_explanatoryText
)));
}
}
// Places the Floating Action Button at the top of the content area of the
// app, on the border between the body and the app bar.
class
_StartTopFloatingActionButtonLocation
extends
FloatingActionButtonLocation
{
const
_StartTopFloatingActionButtonLocation
();
@override
Offset
getOffset
(
ScaffoldPrelayoutGeometry
scaffoldGeometry
)
{
// First, we'll place the X coordinate for the Floating Action Button
// at the start of the screen, based on the text direction.
double
fabX
;
assert
(
scaffoldGeometry
.
textDirection
!=
null
);
switch
(
scaffoldGeometry
.
textDirection
)
{
case
TextDirection
.
rtl
:
// In RTL layouts, the start of the screen is on the right side,
// and the end of the screen is on the left.
//
// We need to align the right edge of the floating action button with
// the right edge of the screen, then move it inwards by the designated padding.
//
// The Scaffold's origin is at its top-left, so we need to offset fabX
// by the Scaffold's width to get the right edge of the screen.
//
// The Floating Action Button's origin is at its top-left, so we also need
// to subtract the Floating Action Button's width to align the right edge
// of the Floating Action Button instead of the left edge.
final
double
startPadding
=
kFloatingActionButtonMargin
+
scaffoldGeometry
.
minInsets
.
right
;
fabX
=
scaffoldGeometry
.
scaffoldSize
.
width
-
scaffoldGeometry
.
floatingActionButtonSize
.
width
-
startPadding
;
break
;
case
TextDirection
.
ltr
:
// In LTR layouts, the start of the screen is on the left side,
// and the end of the screen is on the right.
//
// Placing the fabX at 0.0 will align the left edge of the
// Floating Action Button with the left edge of the screen, so all
// we need to do is offset fabX by the designated padding.
final
double
startPadding
=
kFloatingActionButtonMargin
+
scaffoldGeometry
.
minInsets
.
left
;
fabX
=
startPadding
;
break
;
}
// Finally, we'll place the Y coordinate for the Floating Action Button
// at the top of the content body.
//
// We want to place the middle of the Floating Action Button on the
// border between the Scaffold's app bar and its body. To do this,
// we place fabY at the scaffold geometry's contentTop, then subtract
// half of the Floating Action Button's height to place the center
// over the contentTop.
//
// We don't have to worry about which way is the top like we did
// for left and right, so we place fabY in this one-liner.
final
double
fabY
=
scaffoldGeometry
.
contentTop
-
(
scaffoldGeometry
.
floatingActionButtonSize
.
height
/
2.0
);
return
new
Offset
(
fabX
,
fabY
);
}
}
examples/flutter_gallery/lib/demo/material/material.dart
View file @
68c77e37
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
export
'backdrop_demo.dart'
;
export
'bottom_app_bar_demo.dart'
;
export
'bottom_navigation_demo.dart'
;
export
'buttons_demo.dart'
;
export
'cards_demo.dart'
;
...
...
@@ -12,7 +13,6 @@ export 'date_and_time_picker_demo.dart';
export
'dialog_demo.dart'
;
export
'drawer_demo.dart'
;
export
'expansion_panels_demo.dart'
;
export
'fab_motion_demo.dart'
;
export
'grid_list_demo.dart'
;
export
'icons_demo.dart'
;
export
'leave_behind_demo.dart'
;
...
...
examples/flutter_gallery/lib/gallery/item.dart
View file @
68c77e37
...
...
@@ -88,6 +88,13 @@ List<GalleryItem> _buildGalleryItems() {
routeName:
BackdropDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
new
BackdropDemo
(),
),
new
GalleryItem
(
title:
'Bottom App Bar'
,
subtitle:
'With repositionable floating action button'
,
category:
'Material Components'
,
routeName:
BottomAppBarDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
new
BottomAppBarDemo
(),
),
new
GalleryItem
(
title:
'Bottom navigation'
,
subtitle:
'Bottom navigation with cross-fading views'
,
...
...
@@ -165,13 +172,6 @@ List<GalleryItem> _buildGalleryItems() {
routeName:
TabsFabDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
new
TabsFabDemo
(),
),
new
GalleryItem
(
title:
'Floating action button motion'
,
subtitle:
'Action buttons with customized positions'
,
category:
'Material Components'
,
routeName:
FabMotionDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
new
FabMotionDemo
(),
),
new
GalleryItem
(
title:
'Grid'
,
subtitle:
'Row and column layout'
,
...
...
packages/flutter/lib/src/material/floating_action_button_location.dart
View file @
68c77e37
...
...
@@ -67,7 +67,7 @@ abstract class FloatingActionButtonLocation {
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
static
FloatingActionButtonLocation
endDocked
=
const
_EndDockedFloatingActionButtonLocation
();
static
const
FloatingActionButtonLocation
endDocked
=
const
_EndDockedFloatingActionButtonLocation
();
/// Center-aligned [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
...
...
@@ -79,7 +79,7 @@ abstract class FloatingActionButtonLocation {
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
static
FloatingActionButtonLocation
centerDocked
=
const
_CenterDockedFloatingActionButtonLocation
();
static
const
FloatingActionButtonLocation
centerDocked
=
const
_CenterDockedFloatingActionButtonLocation
();
/// Places the [FloatingActionButton] based on the [Scaffold]'s layout.
///
...
...
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