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
082730e9
Commit
082730e9
authored
Aug 16, 2016
by
Hans Muller
Committed by
GitHub
Aug 16, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tapping status bar scrolls to top on IOS (#5425)
parent
ba53d192
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
227 additions
and
40 deletions
+227
-40
cards_demo.dart
examples/flutter_gallery/lib/demo/cards_demo.dart
+3
-0
colors_demo.dart
examples/flutter_gallery/lib/demo/colors_demo.dart
+46
-22
contacts_demo.dart
examples/flutter_gallery/lib/demo/contacts_demo.dart
+4
-1
grid_list_demo.dart
examples/flutter_gallery/lib/demo/grid_list_demo.dart
+6
-3
leave_behind_demo.dart
examples/flutter_gallery/lib/demo/leave_behind_demo.dart
+7
-2
list_demo.dart
examples/flutter_gallery/lib/demo/list_demo.dart
+4
-1
overscroll_demo.dart
examples/flutter_gallery/lib/demo/overscroll_demo.dart
+1
-0
pesto_demo.dart
examples/flutter_gallery/lib/demo/pesto_demo.dart
+8
-1
shrine_home.dart
examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
+3
-0
shrine_order.dart
examples/flutter_gallery/lib/demo/shrine/shrine_order.dart
+3
-0
shrine_page.dart
examples/flutter_gallery/lib/demo/shrine/shrine_page.dart
+3
-0
tabs_demo.dart
examples/flutter_gallery/lib/demo/tabs_demo.dart
+24
-1
home.dart
examples/flutter_gallery/lib/gallery/home.dart
+7
-2
scaffold.dart
packages/flutter/lib/src/material/scaffold.dart
+40
-7
scaffold_test.dart
packages/flutter/test/material/scaffold_test.dart
+68
-0
No files found.
examples/flutter_gallery/lib/demo/cards_demo.dart
View file @
082730e9
...
...
@@ -128,15 +128,18 @@ class TravelDestinationItem extends StatelessWidget {
}
class
CardsDemo
extends
StatelessWidget
{
static
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
static
const
String
routeName
=
'/cards'
;
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
scrollableKey:
_scrollableKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'Travel stream'
)
),
body:
new
ScrollableList
(
scrollableKey:
_scrollableKey
,
itemExtent:
TravelDestinationItem
.
height
,
padding:
const
EdgeInsets
.
only
(
top:
8.0
,
left:
8.0
,
right:
8.0
),
children:
destinations
.
map
((
TravelDestination
destination
)
{
...
...
examples/flutter_gallery/lib/demo/colors_demo.dart
View file @
082730e9
...
...
@@ -8,8 +8,9 @@ import 'package:flutter/widgets.dart';
const
double
kColorItemHeight
=
48.0
;
class
ColorSwatch
{
const
ColorSwatch
({
this
.
name
,
this
.
colors
,
this
.
accentColors
,
this
.
threshold
:
900
});
ColorSwatch
({
this
.
name
,
this
.
colors
,
this
.
accentColors
,
this
.
threshold
:
900
});
final
GlobalKey
<
ScrollableState
>
scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
String
name
;
final
Map
<
int
,
Color
>
colors
;
final
Map
<
int
,
Color
>
accentColors
;
...
...
@@ -18,26 +19,26 @@ class ColorSwatch {
bool
get
isValid
=>
this
.
name
!=
null
&&
this
.
colors
!=
null
&&
threshold
!=
null
;
}
const
List
<
ColorSwatch
>
colorSwatches
=
const
<
ColorSwatch
>[
const
ColorSwatch
(
name:
'RED'
,
colors:
Colors
.
red
,
accentColors:
Colors
.
redAccent
,
threshold:
300
),
const
ColorSwatch
(
name:
'PINK'
,
colors:
Colors
.
pink
,
accentColors:
Colors
.
pinkAccent
,
threshold:
200
),
const
ColorSwatch
(
name:
'PURPLE'
,
colors:
Colors
.
purple
,
accentColors:
Colors
.
purpleAccent
,
threshold:
200
),
const
ColorSwatch
(
name:
'DEEP PURPLE'
,
colors:
Colors
.
deepPurple
,
accentColors:
Colors
.
deepPurpleAccent
,
threshold:
200
),
const
ColorSwatch
(
name:
'INDIGO'
,
colors:
Colors
.
indigo
,
accentColors:
Colors
.
indigoAccent
,
threshold:
200
),
const
ColorSwatch
(
name:
'BLUE'
,
colors:
Colors
.
blue
,
accentColors:
Colors
.
blueAccent
,
threshold:
400
),
const
ColorSwatch
(
name:
'LIGHT BLUE'
,
colors:
Colors
.
lightBlue
,
accentColors:
Colors
.
lightBlueAccent
,
threshold:
500
),
const
ColorSwatch
(
name:
'CYAN'
,
colors:
Colors
.
cyan
,
accentColors:
Colors
.
cyanAccent
,
threshold:
600
),
const
ColorSwatch
(
name:
'TEAL'
,
colors:
Colors
.
teal
,
accentColors:
Colors
.
tealAccent
,
threshold:
400
),
const
ColorSwatch
(
name:
'GREEN'
,
colors:
Colors
.
green
,
accentColors:
Colors
.
greenAccent
,
threshold:
500
),
const
ColorSwatch
(
name:
'LIGHT GREEN'
,
colors:
Colors
.
lightGreen
,
accentColors:
Colors
.
lightGreenAccent
,
threshold:
600
),
const
ColorSwatch
(
name:
'LIME'
,
colors:
Colors
.
lime
,
accentColors:
Colors
.
limeAccent
,
threshold:
800
),
const
ColorSwatch
(
name:
'YELLOW'
,
colors:
Colors
.
yellow
,
accentColors:
Colors
.
yellowAccent
),
const
ColorSwatch
(
name:
'AMBER'
,
colors:
Colors
.
amber
,
accentColors:
Colors
.
amberAccent
),
const
ColorSwatch
(
name:
'ORANGE'
,
colors:
Colors
.
orange
,
accentColors:
Colors
.
orangeAccent
,
threshold:
700
),
const
ColorSwatch
(
name:
'DEEP ORANGE'
,
colors:
Colors
.
deepOrange
,
accentColors:
Colors
.
deepOrangeAccent
,
threshold:
400
),
const
ColorSwatch
(
name:
'BROWN'
,
colors:
Colors
.
brown
,
threshold:
200
),
const
ColorSwatch
(
name:
'GREY'
,
colors:
Colors
.
grey
,
threshold:
500
),
const
ColorSwatch
(
name:
'BLUE GREY'
,
colors:
Colors
.
blueGrey
,
threshold:
500
)
final
List
<
ColorSwatch
>
colorSwatches
=
<
ColorSwatch
>[
new
ColorSwatch
(
name:
'RED'
,
colors:
Colors
.
red
,
accentColors:
Colors
.
redAccent
,
threshold:
300
),
new
ColorSwatch
(
name:
'PINK'
,
colors:
Colors
.
pink
,
accentColors:
Colors
.
pinkAccent
,
threshold:
200
),
new
ColorSwatch
(
name:
'PURPLE'
,
colors:
Colors
.
purple
,
accentColors:
Colors
.
purpleAccent
,
threshold:
200
),
new
ColorSwatch
(
name:
'DEEP PURPLE'
,
colors:
Colors
.
deepPurple
,
accentColors:
Colors
.
deepPurpleAccent
,
threshold:
200
),
new
ColorSwatch
(
name:
'INDIGO'
,
colors:
Colors
.
indigo
,
accentColors:
Colors
.
indigoAccent
,
threshold:
200
),
new
ColorSwatch
(
name:
'BLUE'
,
colors:
Colors
.
blue
,
accentColors:
Colors
.
blueAccent
,
threshold:
400
),
new
ColorSwatch
(
name:
'LIGHT BLUE'
,
colors:
Colors
.
lightBlue
,
accentColors:
Colors
.
lightBlueAccent
,
threshold:
500
),
new
ColorSwatch
(
name:
'CYAN'
,
colors:
Colors
.
cyan
,
accentColors:
Colors
.
cyanAccent
,
threshold:
600
),
new
ColorSwatch
(
name:
'TEAL'
,
colors:
Colors
.
teal
,
accentColors:
Colors
.
tealAccent
,
threshold:
400
),
new
ColorSwatch
(
name:
'GREEN'
,
colors:
Colors
.
green
,
accentColors:
Colors
.
greenAccent
,
threshold:
500
),
new
ColorSwatch
(
name:
'LIGHT GREEN'
,
colors:
Colors
.
lightGreen
,
accentColors:
Colors
.
lightGreenAccent
,
threshold:
600
),
new
ColorSwatch
(
name:
'LIME'
,
colors:
Colors
.
lime
,
accentColors:
Colors
.
limeAccent
,
threshold:
800
),
new
ColorSwatch
(
name:
'YELLOW'
,
colors:
Colors
.
yellow
,
accentColors:
Colors
.
yellowAccent
),
new
ColorSwatch
(
name:
'AMBER'
,
colors:
Colors
.
amber
,
accentColors:
Colors
.
amberAccent
),
new
ColorSwatch
(
name:
'ORANGE'
,
colors:
Colors
.
orange
,
accentColors:
Colors
.
orangeAccent
,
threshold:
700
),
new
ColorSwatch
(
name:
'DEEP ORANGE'
,
colors:
Colors
.
deepOrange
,
accentColors:
Colors
.
deepOrangeAccent
,
threshold:
400
),
new
ColorSwatch
(
name:
'BROWN'
,
colors:
Colors
.
brown
,
threshold:
200
),
new
ColorSwatch
(
name:
'GREY'
,
colors:
Colors
.
grey
,
threshold:
500
),
new
ColorSwatch
(
name:
'BLUE GREY'
,
colors:
Colors
.
blueGrey
,
threshold:
500
)
];
...
...
@@ -102,20 +103,43 @@ class ColorSwatchTabView extends StatelessWidget {
}
return
new
ScrollableList
(
scrollableKey:
swatch
.
scrollableKey
,
itemExtent:
kColorItemHeight
,
children:
colorItems
);
}
}
class
ColorsDemo
extends
StatelessWidget
{
class
ColorsDemo
extends
StatefulWidget
{
ColorsDemo
({
Key
key
})
:
super
(
key:
key
);
static
const
String
routeName
=
'/colors'
;
@override
_ColorsDemoState
createState
()
=>
new
_ColorsDemoState
();
}
class
_ColorsDemoState
extends
State
<
ColorsDemo
>
{
ColorSwatch
_selectedSwatch
;
@override
void
initState
()
{
super
.
initState
();
_selectedSwatch
=
colorSwatches
.
first
;
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
TabBarSelection
<
ColorSwatch
>(
values:
colorSwatches
,
onChanged:
(
ColorSwatch
value
)
{
setState
(()
{
_selectedSwatch
=
value
;
});
},
child:
new
Scaffold
(
scrollableKey:
_selectedSwatch
.
scrollableKey
,
appBar:
new
AppBar
(
elevation:
0
,
title:
new
Text
(
'Colors'
),
...
...
examples/flutter_gallery/lib/demo/contacts_demo.dart
View file @
082730e9
...
...
@@ -80,7 +80,8 @@ class ContactsDemo extends StatefulWidget {
}
class
ContactsDemoState
extends
State
<
ContactsDemo
>
{
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
double
_appBarHeight
=
256.0
;
AppBarBehavior
_appBarBehavior
=
AppBarBehavior
.
under
;
...
...
@@ -94,6 +95,7 @@ class ContactsDemoState extends State<ContactsDemo> {
),
child:
new
Scaffold
(
key:
_scaffoldKey
,
scrollableKey:
_scrollableKey
,
appBarBehavior:
_appBarBehavior
,
appBar:
new
AppBar
(
expandedHeight:
_appBarHeight
,
...
...
@@ -151,6 +153,7 @@ class ContactsDemoState extends State<ContactsDemo> {
),
body:
new
Block
(
padding:
new
EdgeInsets
.
only
(
top:
_appBarHeight
+
statusBarHeight
),
scrollableKey:
_scrollableKey
,
children:
<
Widget
>[
new
_ContactCategory
(
icon:
Icons
.
call
,
...
...
examples/flutter_gallery/lib/demo/grid_list_demo.dart
View file @
082730e9
...
...
@@ -133,7 +133,8 @@ class GridListDemo extends StatefulWidget {
}
class
GridListDemoState
extends
State
<
GridListDemo
>
{
GridDemoTileStyle
tileStyle
=
GridDemoTileStyle
.
twoLine
;
static
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
GridDemoTileStyle
_tileStyle
=
GridDemoTileStyle
.
twoLine
;
List
<
Photo
>
photos
=
<
Photo
>[
new
Photo
(
...
...
@@ -200,7 +201,7 @@ class GridListDemoState extends State<GridListDemo> {
void
changeTileStyle
(
GridDemoTileStyle
value
)
{
setState
(()
{
tileStyle
=
value
;
_
tileStyle
=
value
;
});
}
...
...
@@ -211,6 +212,7 @@ class GridListDemoState extends State<GridListDemo> {
Widget
build
(
BuildContext
context
)
{
final
Orientation
orientation
=
MediaQuery
.
of
(
context
).
orientation
;
return
new
Scaffold
(
scrollableKey:
_scrollableKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'Grid list'
),
actions:
<
Widget
>[
...
...
@@ -237,6 +239,7 @@ class GridListDemoState extends State<GridListDemo> {
children:
<
Widget
>[
new
Flexible
(
child:
new
ScrollableGrid
(
scrollableKey:
_scrollableKey
,
delegate:
new
FixedColumnCountGridDelegate
(
columnCount:
(
orientation
==
Orientation
.
portrait
)
?
2
:
3
,
rowSpacing:
4.0
,
...
...
@@ -247,7 +250,7 @@ class GridListDemoState extends State<GridListDemo> {
children:
photos
.
map
((
Photo
photo
)
{
return
new
GridDemoPhotoItem
(
photo:
photo
,
tileStyle:
tileStyle
,
tileStyle:
_
tileStyle
,
onBannerTap:
(
Photo
photo
)
{
setState
(()
{
photo
.
isFavorite
=
!
photo
.
isFavorite
;
...
...
examples/flutter_gallery/lib/demo/leave_behind_demo.dart
View file @
082730e9
...
...
@@ -38,7 +38,8 @@ class LeaveBehindDemo extends StatefulWidget {
}
class
LeaveBehindDemoState
extends
State
<
LeaveBehindDemo
>
{
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
DismissDirection
_dismissDirection
=
DismissDirection
.
horizontal
;
List
<
LeaveBehindItem
>
leaveBehindItems
;
...
...
@@ -131,6 +132,7 @@ class LeaveBehindDemoState extends State<LeaveBehindDemo> {
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
key:
_scaffoldKey
,
scrollableKey:
_scrollableKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'Swipe items to dismiss'
),
actions:
<
Widget
>[
...
...
@@ -161,7 +163,10 @@ class LeaveBehindDemoState extends State<LeaveBehindDemo> {
)
]
),
body:
new
Block
(
children:
leaveBehindItems
.
map
(
buildItem
).
toList
())
body:
new
Block
(
scrollableKey:
_scrollableKey
,
children:
leaveBehindItems
.
map
(
buildItem
).
toList
()
)
);
}
}
examples/flutter_gallery/lib/demo/list_demo.dart
View file @
082730e9
...
...
@@ -14,7 +14,8 @@ class ListDemo extends StatefulWidget {
}
class
ListDemoState
extends
State
<
ListDemo
>
{
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
PersistentBottomSheetController
<
Null
>
_bottomSheet
;
MaterialListType
_itemType
=
MaterialListType
.
threeLine
;
...
...
@@ -171,6 +172,7 @@ class ListDemoState extends State<ListDemo> {
return
new
Scaffold
(
key:
scaffoldKey
,
scrollableKey:
_scrollableKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'Scrolling list
\n
$itemTypeText$layoutText
'
),
actions:
<
Widget
>[
...
...
@@ -193,6 +195,7 @@ class ListDemoState extends State<ListDemo> {
),
body:
new
Scrollbar
(
child:
new
MaterialList
(
scrollableKey:
_scrollableKey
,
type:
_itemType
,
padding:
new
EdgeInsets
.
symmetric
(
vertical:
_dense
?
4.0
:
8.0
),
children:
listItems
...
...
examples/flutter_gallery/lib/demo/overscroll_demo.dart
View file @
082730e9
...
...
@@ -90,6 +90,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
return
new
Scaffold
(
key:
_scaffoldKey
,
scrollableKey:
_scrollableKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'
$indicatorTypeText
'
),
actions:
<
Widget
>[
...
...
examples/flutter_gallery/lib/demo/pesto_demo.dart
View file @
082730e9
...
...
@@ -51,6 +51,8 @@ class PestoDemo extends StatefulWidget {
class
_PestoDemoState
extends
State
<
PestoDemo
>
{
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
static
final
GlobalKey
<
ScrollableState
>
_homeScrollableKey
=
new
GlobalKey
<
ScrollableState
>();
static
final
GlobalKey
<
ScrollableState
>
_favoritesScrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
TextStyle
favoritesMessageStyle
=
_textStyle
(
16.0
);
final
TextStyle
userStyle
=
_textStyle
(
12.0
,
FontWeight
.
bold
);
final
TextStyle
emailStyle
=
_textStyle
(
12.0
).
copyWith
(
color:
Colors
.
black54
);
...
...
@@ -61,6 +63,7 @@ class _PestoDemoState extends State<PestoDemo> {
data:
_kTheme
,
child:
new
Scaffold
(
key:
_scaffoldKey
,
scrollableKey:
config
.
showFavorites
?
_favoritesScrollableKey
:
_homeScrollableKey
,
appBarBehavior:
AppBarBehavior
.
under
,
appBar:
_buildAppBar
(
context
),
drawer:
_buildDrawer
(
context
),
...
...
@@ -180,6 +183,7 @@ class _PestoDemoState extends State<PestoDemo> {
}
return
new
ScrollableGrid
(
scrollableKey:
config
.
showFavorites
?
_favoritesScrollableKey
:
_homeScrollableKey
,
delegate:
new
MaxTileWidthGridDelegate
(
maxTileWidth:
500.0
,
rowSpacing:
8.0
,
...
...
@@ -282,7 +286,8 @@ class _RecipePage extends StatefulWidget {
}
class
_RecipePageState
extends
State
<
_RecipePage
>
{
static
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
TextStyle
menuItemStyle
=
_textStyle
(
15.0
).
copyWith
(
color:
Colors
.
black54
,
height:
24.0
/
15.0
);
double
_getAppBarHeight
(
BuildContext
context
)
=>
MediaQuery
.
of
(
context
).
size
.
height
*
0.3
;
...
...
@@ -291,6 +296,7 @@ class _RecipePageState extends State<_RecipePage> {
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
key:
_scaffoldKey
,
scrollableKey:
_scrollableKey
,
appBarBehavior:
AppBarBehavior
.
scroll
,
appBar:
new
AppBar
(
expandedHeight:
_getAppBarHeight
(
context
),
...
...
@@ -347,6 +353,7 @@ class _RecipePageState extends State<_RecipePage> {
new
ClampOverscrolls
(
value:
true
,
child:
new
ScrollableViewport
(
scrollableKey:
_scrollableKey
,
child:
new
RepaintBoundary
(
child:
new
Padding
(
padding:
new
EdgeInsets
.
only
(
top:
appBarHeight
),
...
...
examples/flutter_gallery/lib/demo/shrine/shrine_home.dart
View file @
082730e9
...
...
@@ -293,6 +293,7 @@ class ShrineHome extends StatefulWidget {
class
_ShrineHomeState
extends
State
<
ShrineHome
>
{
static
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>(
debugLabel:
'Order page'
);
static
final
GlobalKey
<
ScrollableState
>
scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
static
final
GridDelegate
gridDelegate
=
new
ShrineGridDelegate
();
void
handleCompletedOrder
(
Order
completedOrder
)
{
...
...
@@ -323,9 +324,11 @@ class _ShrineHomeState extends State<ShrineHome> {
final
Product
featured
=
_products
.
firstWhere
((
Product
product
)
=>
product
.
featureDescription
!=
null
);
return
new
ShrinePage
(
scaffoldKey:
scaffoldKey
,
scrollableKey:
scrollableKey
,
products:
_products
,
shoppingCart:
_shoppingCart
,
body:
new
ScrollableViewport
(
scrollableKey:
scrollableKey
,
child:
new
RepaintBoundary
(
child:
new
Column
(
children:
<
Widget
>[
...
...
examples/flutter_gallery/lib/demo/shrine/shrine_order.dart
View file @
082730e9
...
...
@@ -137,6 +137,7 @@ class OrderPage extends StatefulWidget {
/// order to the shopping cart.
class
_OrderPageState
extends
State
<
OrderPage
>
{
static
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>(
debugLabel:
'Order page'
);
static
final
GlobalKey
<
ScrollableState
>
scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
Order
get
currentOrder
=>
ShrineOrderRoute
.
of
(
context
).
order
;
...
...
@@ -162,6 +163,7 @@ class _OrderPageState extends State<OrderPage> {
Widget
build
(
BuildContext
context
)
{
return
new
ShrinePage
(
scaffoldKey:
scaffoldKey
,
scrollableKey:
scrollableKey
,
products:
config
.
products
,
shoppingCart:
config
.
shoppingCart
,
floatingActionButton:
new
FloatingActionButton
(
...
...
@@ -180,6 +182,7 @@ class _OrderPageState extends State<OrderPage> {
)
),
body:
new
Block
(
scrollableKey:
scrollableKey
,
children:
<
Widget
>[
new
OrderItem
(
product:
config
.
order
.
product
,
...
...
examples/flutter_gallery/lib/demo/shrine/shrine_page.dart
View file @
082730e9
...
...
@@ -17,6 +17,7 @@ class ShrinePage extends StatefulWidget {
ShrinePage
({
Key
key
,
this
.
scaffoldKey
,
this
.
scrollableKey
,
this
.
body
,
this
.
floatingActionButton
,
this
.
products
,
...
...
@@ -27,6 +28,7 @@ class ShrinePage extends StatefulWidget {
}
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
;
final
GlobalKey
<
ScrollableState
>
scrollableKey
;
final
Widget
body
;
final
Widget
floatingActionButton
;
final
List
<
Product
>
products
;
...
...
@@ -86,6 +88,7 @@ class ShrinePageState extends State<ShrinePage> {
final
ShrineTheme
theme
=
ShrineTheme
.
of
(
context
);
return
new
Scaffold
(
key:
config
.
scaffoldKey
,
scrollableKey:
config
.
scrollableKey
,
appBar:
new
AppBar
(
elevation:
_appBarElevation
,
backgroundColor:
theme
.
appBarBackgroundColor
,
...
...
examples/flutter_gallery/lib/demo/tabs_demo.dart
View file @
082730e9
...
...
@@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
class
_Page
{
_Page
({
this
.
label
});
final
GlobalKey
<
ScrollableState
>
scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
String
label
;
String
get
id
=>
label
[
0
];
}
...
...
@@ -111,14 +112,35 @@ class _CardDataItem extends StatelessWidget {
}
}
class
TabsDemo
extends
StatelessWidget
{
class
TabsDemo
extends
StatefulWidget
{
TabsDemo
({
Key
key
})
:
super
(
key:
key
);
static
const
String
routeName
=
'/tabs'
;
@override
_TabsDemoState
createState
()
=>
new
_TabsDemoState
();
}
class
_TabsDemoState
extends
State
<
TabsDemo
>
{
_Page
_selectedPage
;
@override
void
initState
()
{
super
.
initState
();
_selectedPage
=
_allPages
.
keys
.
first
;
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
TabBarSelection
<
_Page
>(
values:
_allPages
.
keys
.
toList
(),
onChanged:
(
_Page
value
)
{
setState
(()
{
_selectedPage
=
value
;
});
},
child:
new
Scaffold
(
scrollableKey:
_selectedPage
.
scrollableKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'Tabs and scrolling'
),
bottom:
new
TabBar
<
_Page
>(
...
...
@@ -130,6 +152,7 @@ class TabsDemo extends StatelessWidget {
body:
new
TabBarView
<
_Page
>(
children:
_allPages
.
keys
.
map
((
_Page
page
)
{
return
new
ScrollableList
(
scrollableKey:
_selectedPage
.
scrollableKey
,
padding:
const
EdgeInsets
.
symmetric
(
vertical:
8.0
,
horizontal:
16.0
),
itemExtent:
_CardDataItem
.
height
,
children:
_allPages
[
page
].
map
((
_CardData
data
)
{
...
...
examples/flutter_gallery/lib/gallery/home.dart
View file @
082730e9
...
...
@@ -97,7 +97,8 @@ class GalleryHome extends StatefulWidget {
}
class
GalleryHomeState
extends
State
<
GalleryHome
>
{
final
Key
_homeKey
=
new
ValueKey
<
String
>(
"Gallery Home"
);
static
final
Key
_homeKey
=
new
ValueKey
<
String
>(
"Gallery Home"
);
static
final
GlobalKey
<
ScrollableState
>
_scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
List
<
Widget
>
_listItems
=
<
Widget
>[];
@override
...
...
@@ -135,6 +136,7 @@ class GalleryHomeState extends State<GalleryHome> {
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
key:
_homeKey
,
scrollableKey:
_scrollableKey
,
drawer:
new
GalleryDrawer
(
useLightTheme:
config
.
useLightTheme
,
onThemeChanged:
config
.
onThemeChanged
,
...
...
@@ -157,7 +159,10 @@ class GalleryHomeState extends State<GalleryHome> {
)
),
appBarBehavior:
AppBarBehavior
.
under
,
body:
new
Block
(
children:
_listItems
)
body:
new
Block
(
scrollableKey:
_scrollableKey
,
children:
_listItems
)
);
}
}
packages/flutter/lib/src/material/scaffold.dart
View file @
082730e9
...
...
@@ -16,6 +16,7 @@ import 'icon_button.dart';
import
'icons.dart'
;
import
'material.dart'
;
import
'snack_bar.dart'
;
import
'theme.dart'
;
const
double
_kFloatingActionButtonMargin
=
16.0
;
// TODO(hmuller): should be device dependent
const
Duration
_kFloatingActionButtonSegue
=
const
Duration
(
milliseconds:
200
);
...
...
@@ -52,12 +53,18 @@ enum _ScaffoldSlot {
snackBar
,
floatingActionButton
,
drawer
,
statusBar
,
}
class
_ScaffoldLayout
extends
MultiChildLayoutDelegate
{
_ScaffoldLayout
({
this
.
padding
,
this
.
appBarBehavior
:
AppBarBehavior
.
anchor
});
_ScaffoldLayout
({
this
.
padding
,
this
.
statusBarHeight
,
this
.
appBarBehavior
:
AppBarBehavior
.
anchor
});
final
EdgeInsets
padding
;
final
double
statusBarHeight
;
final
AppBarBehavior
appBarBehavior
;
@override
...
...
@@ -120,6 +127,11 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
positionChild
(
_ScaffoldSlot
.
floatingActionButton
,
new
Offset
(
fabX
,
fabY
));
}
if
(
hasChild
(
_ScaffoldSlot
.
statusBar
))
{
layoutChild
(
_ScaffoldSlot
.
statusBar
,
fullWidthConstraints
.
tighten
(
height:
statusBarHeight
));
positionChild
(
_ScaffoldSlot
.
statusBar
,
Offset
.
zero
);
}
if
(
hasChild
(
_ScaffoldSlot
.
drawer
))
{
layoutChild
(
_ScaffoldSlot
.
drawer
,
new
BoxConstraints
.
tight
(
size
));
positionChild
(
_ScaffoldSlot
.
drawer
,
Offset
.
zero
);
...
...
@@ -270,9 +282,7 @@ class Scaffold extends StatefulWidget {
this
.
scrollableKey
,
this
.
appBarBehavior
:
AppBarBehavior
.
anchor
,
this
.
resizeToAvoidBottomPadding
:
true
})
:
super
(
key:
key
)
{
assert
(
scrollableKey
!=
null
?
(
appBarBehavior
!=
AppBarBehavior
.
anchor
)
:
true
);
}
})
:
super
(
key:
key
);
/// An app bar to display at the top of the scaffold.
final
AppBar
appBar
;
...
...
@@ -298,7 +308,7 @@ class Scaffold extends StatefulWidget {
///
/// Used to control scroll-linked effects, such as the collapse of the
/// [appBar].
final
Key
scrollableKey
;
final
GlobalKey
<
ScrollableState
>
scrollableKey
;
/// How the [appBar] should respond to scrolling.
///
...
...
@@ -663,6 +673,19 @@ class ScaffoldState extends State<Scaffold> {
return
appBar
;
}
// On iOS, tapping the status bar scrolls the app's primary scrollable to the top.
void
_handleStatusBarTap
()
{
ScrollableState
scrollable
=
config
.
scrollableKey
?.
currentState
;
if
(
scrollable
==
null
||
scrollable
.
scrollBehavior
is
!
ExtentScrollBehavior
)
return
;
ExtentScrollBehavior
behavior
=
scrollable
.
scrollBehavior
;
scrollable
.
scrollTo
(
behavior
.
minScrollOffset
,
duration:
const
Duration
(
milliseconds:
300
)
);
}
@override
Widget
build
(
BuildContext
context
)
{
EdgeInsets
padding
=
MediaQuery
.
of
(
context
).
padding
;
...
...
@@ -729,6 +752,16 @@ class ScaffoldState extends State<Scaffold> {
)
));
if
(
Theme
.
of
(
context
).
platform
==
TargetPlatform
.
iOS
)
{
children
.
add
(
new
LayoutId
(
id:
_ScaffoldSlot
.
statusBar
,
child:
new
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
_handleStatusBarTap
)
));
}
if
(
config
.
drawer
!=
null
)
{
children
.
add
(
new
LayoutId
(
id:
_ScaffoldSlot
.
drawer
,
...
...
@@ -739,12 +772,12 @@ class ScaffoldState extends State<Scaffold> {
));
}
EdgeInsets
appPadding
=
(
config
.
appBarBehavior
!=
AppBarBehavior
.
anchor
)
?
EdgeInsets
.
zero
:
padding
;
EdgeInsets
appPadding
=
(
config
.
appBarBehavior
!=
AppBarBehavior
.
anchor
)
?
EdgeInsets
.
zero
:
padding
;
Widget
application
=
new
CustomMultiChildLayout
(
children:
children
,
delegate:
new
_ScaffoldLayout
(
padding:
appPadding
,
statusBarHeight:
padding
.
top
,
appBarBehavior:
config
.
appBarBehavior
)
);
...
...
packages/flutter/test/material/scaffold_test.dart
View file @
082730e9
...
...
@@ -128,4 +128,72 @@ void main() {
RenderBox
renderBox
=
tester
.
renderObject
(
find
.
byKey
(
appBarKey
));
expect
(
renderBox
.
size
.
height
,
equals
(
appBarHeight
));
});
testWidgets
(
'Tapping the status bar scrolls to top on iOS'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
ScrollableState
>
scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
Key
appBarKey
=
new
UniqueKey
();
await
tester
.
pumpWidget
(
new
MaterialApp
(
theme:
new
ThemeData
(
platform:
TargetPlatform
.
iOS
),
home:
new
MediaQuery
(
data:
new
MediaQueryData
(
padding:
const
EdgeInsets
.
only
(
top:
25.0
)),
// status bar
child:
new
Scaffold
(
scrollableKey:
scrollableKey
,
appBar:
new
AppBar
(
key:
appBarKey
,
title:
new
Text
(
'Title'
)
),
body:
new
Block
(
scrollableKey:
scrollableKey
,
initialScrollOffset:
500.0
,
children:
new
List
<
Widget
>.
generate
(
20
,
(
int
index
)
=>
new
SizedBox
(
height:
100.0
,
child:
new
Text
(
'
$index
'
))
)
)
)
)
)
);
expect
(
scrollableKey
.
currentState
.
scrollOffset
,
equals
(
500.0
));
await
tester
.
tapAt
(
const
Point
(
100.0
,
10.0
));
await
tester
.
pump
();
await
tester
.
pump
(
new
Duration
(
seconds:
1
));
expect
(
scrollableKey
.
currentState
.
scrollOffset
,
equals
(
0.0
));
});
testWidgets
(
'Tapping the status bar does not scroll to top on Android'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
ScrollableState
>
scrollableKey
=
new
GlobalKey
<
ScrollableState
>();
final
Key
appBarKey
=
new
UniqueKey
();
await
tester
.
pumpWidget
(
new
MaterialApp
(
theme:
new
ThemeData
(
platform:
TargetPlatform
.
android
),
home:
new
MediaQuery
(
data:
new
MediaQueryData
(
padding:
const
EdgeInsets
.
only
(
top:
25.0
)),
// status bar
child:
new
Scaffold
(
scrollableKey:
scrollableKey
,
appBar:
new
AppBar
(
key:
appBarKey
,
title:
new
Text
(
'Title'
)
),
body:
new
Block
(
scrollableKey:
scrollableKey
,
initialScrollOffset:
500.0
,
children:
new
List
<
Widget
>.
generate
(
20
,
(
int
index
)
=>
new
SizedBox
(
height:
100.0
,
child:
new
Text
(
'
$index
'
))
)
)
)
)
)
);
expect
(
scrollableKey
.
currentState
.
scrollOffset
,
equals
(
500.0
));
await
tester
.
tapAt
(
const
Point
(
100.0
,
10.0
));
await
tester
.
pump
();
await
tester
.
pump
(
new
Duration
(
seconds:
1
));
expect
(
scrollableKey
.
currentState
.
scrollOffset
,
equals
(
500.0
));
});
}
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