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
6178fdff
Commit
6178fdff
authored
Dec 21, 2015
by
Hans Muller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TabBarSelection is now expected to be an ancestor of its TabBar and TabBarView.
parent
3f32201c
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
157 additions
and
115 deletions
+157
-115
tabs_demo.dart
examples/material_gallery/lib/demo/tabs_demo.dart
+10
-5
widget_demo.dart
examples/material_gallery/lib/demo/widget_demo.dart
+11
-1
gallery_page.dart
examples/material_gallery/lib/gallery_page.dart
+15
-8
stock_home.dart
examples/stocks/lib/stock_home.dart
+19
-24
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+90
-67
tool_bar.dart
packages/flutter/lib/src/material/tool_bar.dart
+1
-2
tabs_test.dart
packages/flutter/test/widget/tabs_test.dart
+11
-8
No files found.
examples/material_gallery/lib/demo/tabs_demo.dart
View file @
6178fdff
...
...
@@ -7,11 +7,16 @@ import 'package:flutter/material.dart';
import
'widget_demo.dart'
;
final
List
<
String
>
_iconNames
=
<
String
>[
"event"
,
"home"
,
"android"
,
"alarm"
,
"face"
,
"language"
];
final
TabBarSelection
_selection
=
new
TabBarSelection
(
maxIndex:
_iconNames
.
length
-
1
);
Widget
buildTabBar
(
_
)
{
Widget
_buildTabBarSelection
(
_
,
Widget
child
)
{
return
new
TabBarSelection
(
maxIndex:
_iconNames
.
length
-
1
,
child:
child
);
}
Widget
_buildTabBar
(
_
)
{
return
new
TabBar
(
selection:
_selection
,
isScrollable:
true
,
labels:
_iconNames
.
map
((
String
iconName
)
=>
new
TabLabel
(
text:
iconName
,
icon:
"action/
$iconName
"
)).
toList
()
);
...
...
@@ -24,7 +29,6 @@ class TabsDemo extends StatefulComponent {
class
_TabsDemoState
extends
State
<
TabsDemo
>
{
Widget
build
(
_
)
{
return
new
TabBarView
<
String
>(
selection:
_selection
,
items:
_iconNames
,
itemBuilder:
(
BuildContext
context
,
String
iconName
,
int
index
)
{
return
new
Container
(
...
...
@@ -42,6 +46,7 @@ class _TabsDemoState extends State<TabsDemo> {
final
WidgetDemo
kTabsDemo
=
new
WidgetDemo
(
title:
'Tabs'
,
routeName:
'/tabs'
,
tabBarBuilder:
buildTabBar
,
tabBarBuilder:
_buildTabBar
,
pageWrapperBuilder:
_buildTabBarSelection
,
builder:
(
_
)
=>
new
TabsDemo
()
);
examples/material_gallery/lib/demo/widget_demo.dart
View file @
6178fdff
...
...
@@ -4,12 +4,22 @@
import
'package:flutter/material.dart'
;
typedef
Widget
PageWrapperBuilder
(
BuildContext
context
,
Widget
child
);
class
WidgetDemo
{
WidgetDemo
({
this
.
title
,
this
.
routeName
,
this
.
tabBarBuilder
,
this
.
floatingActionButtonBuilder
,
this
.
builder
});
WidgetDemo
({
this
.
title
,
this
.
routeName
,
this
.
tabBarBuilder
,
this
.
pageWrapperBuilder
,
this
.
floatingActionButtonBuilder
,
this
.
builder
});
final
String
title
;
final
String
routeName
;
final
WidgetBuilder
tabBarBuilder
;
final
PageWrapperBuilder
pageWrapperBuilder
;
final
WidgetBuilder
floatingActionButtonBuilder
;
final
WidgetBuilder
builder
;
}
examples/material_gallery/lib/gallery_page.dart
View file @
6178fdff
...
...
@@ -63,20 +63,27 @@ class _GalleryPageState extends State<GalleryPage> {
return
builder
!=
null
?
builder
(
context
)
:
null
;
}
Widget
_buildPageWrapper
(
BuildContext
context
,
Widget
child
)
{
final
PageWrapperBuilder
builder
=
config
.
active
?.
pageWrapperBuilder
;
return
builder
!=
null
?
builder
(
context
,
child
)
:
child
;
}
Widget
_buildFloatingActionButton
()
{
final
WidgetBuilder
builder
=
config
.
active
?.
floatingActionButtonBuilder
;
return
builder
!=
null
?
builder
(
context
)
:
null
;
}
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
toolBar:
new
ToolBar
(
center:
new
Text
(
config
.
active
?.
title
??
'Flutter Material gallery'
),
tabBar:
_buildTabBar
()
),
drawer:
_buildDrawer
(),
floatingActionButton:
_buildFloatingActionButton
(),
body:
_buildBody
()
return
_buildPageWrapper
(
context
,
new
Scaffold
(
toolBar:
new
ToolBar
(
center:
new
Text
(
config
.
active
?.
title
??
'Flutter Material gallery'
),
tabBar:
_buildTabBar
()
),
drawer:
_buildDrawer
(),
floatingActionButton:
_buildFloatingActionButton
(),
body:
_buildBody
()
)
);
}
}
examples/stocks/lib/stock_home.dart
View file @
6178fdff
...
...
@@ -24,15 +24,9 @@ class StockHomeState extends State<StockHome> {
final
GlobalKey
<
ScaffoldState
>
_scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
bool
_isSearching
=
false
;
String
_searchQuery
;
TabBarSelection
_tabBarSelection
;
void
initState
()
{
super
.
initState
();
_tabBarSelection
=
PageStorage
.
of
(
context
)?.
readState
(
context
);
if
(
_tabBarSelection
==
null
)
{
_tabBarSelection
=
new
TabBarSelection
(
maxIndex:
1
);
PageStorage
.
of
(
context
)?.
writeState
(
context
,
_tabBarSelection
);
}
}
void
_handleSearchBegin
()
{
...
...
@@ -168,7 +162,6 @@ class StockHomeState extends State<StockHome> {
)
],
tabBar:
new
TabBar
(
selection:
_tabBarSelection
,
labels:
<
TabLabel
>[
new
TabLabel
(
text:
StockStrings
.
of
(
context
).
market
()),
new
TabLabel
(
text:
StockStrings
.
of
(
context
).
portfolio
())
...
...
@@ -273,24 +266,26 @@ class StockHomeState extends State<StockHome> {
}
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
key:
_scaffoldKey
,
toolBar:
_isSearching
?
buildSearchBar
()
:
buildToolBar
(),
floatingActionButton:
buildFloatingActionButton
(),
drawer:
_buildDrawer
(
context
),
body:
new
TabBarView
<
StockHomeTab
>(
selection:
_tabBarSelection
,
items:
<
StockHomeTab
>[
StockHomeTab
.
market
,
StockHomeTab
.
portfolio
],
itemBuilder:
(
BuildContext
context
,
StockHomeTab
tab
,
_
)
{
switch
(
tab
)
{
case
StockHomeTab
.
market
:
return
_buildStockTab
(
context
,
tab
,
config
.
symbols
);
case
StockHomeTab
.
portfolio
:
return
_buildStockTab
(
context
,
tab
,
portfolioSymbols
);
default
:
assert
(
false
);
return
new
TabBarSelection
(
maxIndex:
1
,
child:
new
Scaffold
(
key:
_scaffoldKey
,
toolBar:
_isSearching
?
buildSearchBar
()
:
buildToolBar
(),
floatingActionButton:
buildFloatingActionButton
(),
drawer:
_buildDrawer
(
context
),
body:
new
TabBarView
<
StockHomeTab
>(
items:
<
StockHomeTab
>[
StockHomeTab
.
market
,
StockHomeTab
.
portfolio
],
itemBuilder:
(
BuildContext
context
,
StockHomeTab
tab
,
_
)
{
switch
(
tab
)
{
case
StockHomeTab
.
market
:
return
_buildStockTab
(
context
,
tab
,
config
.
symbols
);
case
StockHomeTab
.
portfolio
:
return
_buildStockTab
(
context
,
tab
,
portfolioSymbols
);
default
:
assert
(
false
);
}
}
}
)
)
);
}
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
6178fdff
...
...
@@ -381,32 +381,26 @@ class _TabsScrollBehavior extends BoundedBehavior {
}
}
class
_TabBarSelection
extends
InheritedWidget
{
_TabBarSelection
({
this
.
selection
,
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
final
TabBarSelectionState
selection
;
bool
updateShouldNotify
(
_TabBarSelection
oldWidget
)
=>
selection
!=
oldWidget
.
selection
;
abstract
class
TabBarSelectionPerformanceListener
{
void
handleStatusChange
(
PerformanceStatus
status
);
void
handleProgressChange
();
void
handleSelectionDeactivate
();
}
class
TabBarSelection
extends
StatefulComponent
{
TabBarSelection
({
Key
key
,
this
.
index
:
0
,
this
.
index
,
this
.
maxIndex
,
this
.
onChanged
,
Widget
this
.
child
})
{
this
.
child
})
:
super
(
key:
key
)
{
assert
(
child
!=
null
);
assert
(
maxIndex
!=
null
);
assert
(
index
!=
null
);
assert
(
index
>=
0
&&
index
<=
maxIndex
);
assert
((
index
!=
null
)
?
index
>=
0
&&
index
<=
maxIndex
:
true
);
}
final
int
index
;
// TBD: this doesn't work yet...
final
int
index
;
final
int
maxIndex
;
final
Widget
child
;
final
ValueChanged
<
int
>
onChanged
;
...
...
@@ -414,20 +408,25 @@ class TabBarSelection extends StatefulComponent {
TabBarSelectionState
createState
()
=>
new
TabBarSelectionState
();
static
TabBarSelectionState
of
(
BuildContext
context
)
{
_TabBarSelection
widget
=
context
.
inheritFromWidgetOfType
(
_TabBarSelection
);
return
widget
?.
selection
;
return
context
.
ancestorStateOfType
(
TabBarSelectionState
);
}
}
class
TabBarSelectionState
extends
State
<
TabBarSelection
>
{
PerformanceView
get
performance
=>
_performance
.
view
;
// Both the TabBar and TabBarView classes access _performance because they
// alternately drive selection progress between tabs.
PerformanceView
get
performance
=>
_performance
.
view
;
final
_performance
=
new
Performance
(
duration:
_kTabBarScroll
,
progress:
1.0
);
void
initState
()
{
super
.
initState
();
_index
=
config
.
index
??
PageStorage
.
of
(
context
)?.
readState
(
context
)
??
0
;
}
void
dispose
()
{
_performance
.
stop
();
PageStorage
.
of
(
context
)?.
writeState
(
context
,
_index
);
super
.
dispose
();
}
...
...
@@ -435,11 +434,12 @@ class TabBarSelectionState extends State<TabBarSelection> {
bool
get
indexIsChanging
=>
_indexIsChanging
;
int
get
index
=>
_index
;
int
_index
=
0
;
int
_index
;
void
set
index
(
int
value
)
{
if
(
value
==
_index
)
return
;
_previousIndex
=
_index
;
if
(!
_indexIsChanging
)
_previousIndex
=
_index
;
_index
=
value
;
_indexIsChanging
=
true
;
...
...
@@ -469,17 +469,43 @@ class TabBarSelectionState extends State<TabBarSelection> {
_performance
..
progress
=
progress
..
forward
().
then
((
_
)
{
if
(
config
.
onChanged
!=
null
)
config
.
onChanged
(
_index
);
_indexIsChanging
=
false
;
if
(
_performance
.
progress
==
1.0
)
{
if
(
config
.
onChanged
!=
null
)
config
.
onChanged
(
_index
);
_indexIsChanging
=
false
;
}
});
}
int
get
previousIndex
=>
_previousIndex
;
int
_previousIndex
=
0
;
final
List
<
TabBarSelectionPerformanceListener
>
_performanceListeners
=
<
TabBarSelectionPerformanceListener
>[];
void
registerPerformanceListener
(
TabBarSelectionPerformanceListener
listener
)
{
_performanceListeners
.
add
(
listener
);
_performance
..
addStatusListener
(
listener
.
handleStatusChange
)
..
addListener
(
listener
.
handleProgressChange
);
}
void
unregisterPerformanceListener
(
TabBarSelectionPerformanceListener
listener
)
{
_performanceListeners
.
remove
(
listener
);
_performance
..
removeStatusListener
(
listener
.
handleStatusChange
)
..
removeListener
(
listener
.
handleProgressChange
);
}
void
deactivate
()
{
for
(
TabBarSelectionPerformanceListener
listener
in
_performanceListeners
.
toList
())
{
listener
.
handleSelectionDeactivate
();
unregisterPerformanceListener
(
listener
);
}
assert
(
_performanceListeners
.
isEmpty
);
}
Widget
build
(
BuildContext
context
)
{
return
new
_TabBarSelection
(
selection:
this
,
child:
config
.
child
)
;
return
config
.
child
;
}
}
...
...
@@ -507,40 +533,30 @@ class TabBar extends Scrollable {
_TabBarState
createState
()
=>
new
_TabBarState
();
}
class
_TabBarState
extends
ScrollableState
<
TabBar
>
{
class
_TabBarState
extends
ScrollableState
<
TabBar
>
implements
TabBarSelectionPerformanceListener
{
TabBarSelectionState
_selection
;
bool
_indexIsChanging
=
false
;
int
get
_tabCount
=>
config
.
labels
.
length
;
void
_addSelectionListeners
(
TabBarSelectionState
selection
)
{
if
(
selection
!=
null
)
{
selection
.
_performance
..
addStatusListener
(
_handleStatusChange
)
..
addListener
(
_handleProgressChange
);
}
}
void
_removeSelectionListeners
(
TabBarSelectionState
selection
)
{
if
(
selection
!=
null
)
{
selection
.
_performance
..
removeStatusListener
(
_handleStatusChange
)
..
removeListener
(
_handleProgressChange
);
}
}
void
initState
()
{
super
.
initState
();
scrollBehavior
.
isScrollable
=
config
.
isScrollable
;
_selection
=
TabBarSelection
.
of
(
context
);
_selection
?.
registerPerformanceListener
(
this
);
}
void
dispose
()
{
_
removeSelectionListeners
(
_selection
);
_
selection
?.
unregisterPerformanceListener
(
this
);
super
.
dispose
();
}
void
_handleStatusChange
(
PerformanceStatus
status
)
{
void
handleSelectionDeactivate
()
{
_selection
=
null
;
}
void
handleStatusChange
(
PerformanceStatus
status
)
{
if
(
_tabCount
==
0
)
return
;
...
...
@@ -561,7 +577,7 @@ class _TabBarState extends ScrollableState<TabBar> {
}
}
void
_
handleProgressChange
()
{
void
handleProgressChange
()
{
if
(
_tabCount
==
0
||
_selection
==
null
)
return
;
...
...
@@ -574,9 +590,11 @@ class _TabBarState extends ScrollableState<TabBar> {
..
curve
=
Curves
.
ease
;
_indexIsChanging
=
true
;
}
setState
(()
{
_indicatorRect
.
setProgress
(
_selection
.
performance
.
progress
,
AnimationDirection
.
forward
);
});
Rect
oldRect
=
_indicatorRect
.
value
;
_indicatorRect
.
setProgress
(
_selection
.
performance
.
progress
,
AnimationDirection
.
forward
);
Rect
newRect
=
_indicatorRect
.
value
;
if
(
oldRect
!=
newRect
)
setState
(()
{
});
}
Size
_viewportSize
=
Size
.
zero
;
...
...
@@ -671,8 +689,8 @@ class _TabBarState extends ScrollableState<TabBar> {
TabBarSelectionState
oldSelection
=
_selection
;
_selection
=
TabBarSelection
.
of
(
context
);
if
(
oldSelection
!=
_selection
)
{
_removeSelectionListeners
(
oldSelection
);
_
addSelectionListeners
(
_selection
);
oldSelection
?.
registerPerformanceListener
(
this
);
_
selection
?.
registerPerformanceListener
(
this
);
}
assert
(
config
.
labels
!=
null
&&
config
.
labels
.
isNotEmpty
);
...
...
@@ -746,7 +764,7 @@ class TabBarView<T> extends PageableList<T> {
_TabBarViewState
createState
()
=>
new
_TabBarViewState
<
T
>();
}
class
_TabBarViewState
<
T
>
extends
PageableListState
<
T
,
TabBarView
<
T
>>
{
class
_TabBarViewState
<
T
>
extends
PageableListState
<
T
,
TabBarView
<
T
>>
implements
TabBarSelectionPerformanceListener
{
TabBarSelectionState
_selection
;
List
<
int
>
_itemIndices
=
[
0
,
1
];
...
...
@@ -754,16 +772,6 @@ class _TabBarViewState<T> extends PageableListState<T, TabBarView<T>> {
int
get
_tabCount
=>
config
.
items
.
length
;
void
_addSelectionListeners
(
TabBarSelectionState
selection
)
{
if
(
selection
!=
null
)
selection
.
_performance
.
addListener
(
_handleProgressChange
);
}
void
_removeSelectionListeners
(
TabBarSelectionState
selection
)
{
if
(
selection
!=
null
)
selection
.
_performance
.
removeListener
(
_handleProgressChange
);
}
BoundedBehavior
_boundedBehavior
;
ExtentScrollBehavior
get
scrollBehavior
{
...
...
@@ -771,11 +779,25 @@ class _TabBarViewState<T> extends PageableListState<T, TabBarView<T>> {
return
_boundedBehavior
;
}
void
initState
()
{
super
.
initState
();
_selection
=
TabBarSelection
.
of
(
context
);
if
(
_selection
!=
null
)
{
_selection
.
registerPerformanceListener
(
this
);
_initItemIndicesAndScrollPosition
();
}
}
void
dispose
()
{
_
removeSelectionListeners
(
_selection
);
_
selection
?.
unregisterPerformanceListener
(
this
);
super
.
dispose
();
}
void
handleSelectionDeactivate
()
{
_selection
=
null
;
}
void
_initItemIndicesAndScrollPosition
()
{
assert
(
_selection
!=
null
);
final
int
selectedIndex
=
_selection
.
index
;
...
...
@@ -791,7 +813,10 @@ class _TabBarViewState<T> extends PageableListState<T, TabBarView<T>> {
}
}
void
_handleProgressChange
()
{
void
handleStatusChange
(
PerformanceStatus
status
)
{
}
void
handleProgressChange
()
{
if
(
_selection
==
null
||
!
_selection
.
indexIsChanging
)
return
;
// The TabBar is driving the TabBarSelection performance.
...
...
@@ -865,10 +890,8 @@ class _TabBarViewState<T> extends PageableListState<T, TabBarView<T>> {
TabBarSelectionState
oldSelection
=
_selection
;
_selection
=
TabBarSelection
.
of
(
context
);
if
(
oldSelection
!=
_selection
)
{
_removeSelectionListeners
(
oldSelection
);
_addSelectionListeners
(
_selection
);
if
(
_selection
!=
null
)
_initItemIndicesAndScrollPosition
();
oldSelection
?.
unregisterPerformanceListener
(
this
);
_selection
?.
registerPerformanceListener
(
this
);
}
return
_itemIndices
...
...
packages/flutter/lib/src/material/tool_bar.dart
View file @
6178fdff
...
...
@@ -8,7 +8,6 @@ import 'constants.dart';
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'material.dart'
;
import
'tabs.dart'
;
import
'theme.dart'
;
import
'typography.dart'
;
...
...
@@ -30,7 +29,7 @@ class ToolBar extends StatelessComponent {
final
Widget
center
;
final
List
<
Widget
>
right
;
final
Widget
bottom
;
final
TabBar
tabBar
;
final
Widget
tabBar
;
final
int
elevation
;
final
Color
backgroundColor
;
final
TextTheme
textTheme
;
...
...
packages/flutter/test/widget/tabs_test.dart
View file @
6178fdff
...
...
@@ -7,14 +7,15 @@ import 'package:flutter/material.dart';
import
'package:flutter/widgets.dart'
;
import
'package:test/test.dart'
;
TabBarSelection
selection
;
Widget
buildFrame
(
{
List
<
String
>
tabs
,
bool
isScrollable:
false
})
{
return
new
Material
(
child:
new
TabBar
(
labels:
tabs
.
map
((
String
tab
)
=>
new
TabLabel
(
text:
tab
)).
toList
(),
selection:
selection
,
isScrollable:
isScrollable
child:
new
TabBarSelection
(
index:
2
,
maxIndex:
tabs
.
length
-
1
,
child:
new
TabBar
(
labels:
tabs
.
map
((
String
tab
)
=>
new
TabLabel
(
text:
tab
)).
toList
(),
isScrollable:
isScrollable
)
)
);
}
...
...
@@ -23,9 +24,10 @@ void main() {
test
(
'TabBar tap selects tab'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
List
<
String
>
tabs
=
<
String
>[
'A'
,
'B'
,
'C'
];
selection
=
new
TabBarSelection
(
index:
2
,
maxIndex:
tabs
.
length
-
1
);
tester
.
pumpWidget
(
buildFrame
(
tabs:
tabs
,
isScrollable:
false
));
TabBarSelectionState
selection
=
tester
.
findStateOfType
(
TabBarSelectionState
);
expect
(
selection
,
isNotNull
);
expect
(
tester
.
findText
(
'A'
),
isNotNull
);
expect
(
tester
.
findText
(
'B'
),
isNotNull
);
expect
(
tester
.
findText
(
'C'
),
isNotNull
);
...
...
@@ -51,9 +53,10 @@ void main() {
test
(
'Scrollable TabBar tap selects tab'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
List
<
String
>
tabs
=
<
String
>[
'A'
,
'B'
,
'C'
];
selection
=
new
TabBarSelection
(
index:
2
,
maxIndex:
tabs
.
length
-
1
);
tester
.
pumpWidget
(
buildFrame
(
tabs:
tabs
,
isScrollable:
true
));
TabBarSelectionState
selection
=
tester
.
findStateOfType
(
TabBarSelectionState
);
expect
(
selection
,
isNotNull
);
expect
(
tester
.
findText
(
'A'
),
isNotNull
);
expect
(
tester
.
findText
(
'B'
),
isNotNull
);
expect
(
tester
.
findText
(
'C'
),
isNotNull
);
...
...
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