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
a3670a2f
Commit
a3670a2f
authored
Oct 12, 2018
by
Artur Rymarz
Committed by
xster
Oct 12, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add parameters to allow hiding icons and border of the Cupertino TabBar (#22804)
parent
490d369a
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
167 additions
and
38 deletions
+167
-38
AUTHORS
AUTHORS
+1
-0
bottom_tab_bar.dart
packages/flutter/lib/src/cupertino/bottom_tab_bar.dart
+38
-25
bottom_navigation_bar.dart
packages/flutter/lib/src/material/bottom_navigation_bar.dart
+10
-7
bottom_navigation_bar_item.dart
...s/flutter/lib/src/widgets/bottom_navigation_bar_item.dart
+4
-5
bottom_tab_bar_test.dart
packages/flutter/test/cupertino/bottom_tab_bar_test.dart
+95
-1
bottom_navigation_bar_test.dart
...ges/flutter/test/material/bottom_navigation_bar_test.dart
+19
-0
No files found.
AUTHORS
View file @
a3670a2f
...
@@ -27,3 +27,4 @@ Victor Choueiri <victor@ctrlanddev.com>
...
@@ -27,3 +27,4 @@ Victor Choueiri <victor@ctrlanddev.com>
Christian Mürtz <teraarts@t-online.de>
Christian Mürtz <teraarts@t-online.de>
Lukasz Piliszczuk <lukasz@intheloup.io>
Lukasz Piliszczuk <lukasz@intheloup.io>
Felix Schmidt <felix.free@gmx.de>
Felix Schmidt <felix.free@gmx.de>
Artur Rymarz <artur.rymarz@gmail.com>
packages/flutter/lib/src/cupertino/bottom_tab_bar.dart
View file @
a3670a2f
...
@@ -44,6 +44,13 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -44,6 +44,13 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
this
.
activeColor
=
CupertinoColors
.
activeBlue
,
this
.
activeColor
=
CupertinoColors
.
activeBlue
,
this
.
inactiveColor
=
CupertinoColors
.
inactiveGray
,
this
.
inactiveColor
=
CupertinoColors
.
inactiveGray
,
this
.
iconSize
=
30.0
,
this
.
iconSize
=
30.0
,
this
.
border
=
const
Border
(
top:
BorderSide
(
color:
_kDefaultTabBarBorderColor
,
width:
0.0
,
// One physical pixel.
style:
BorderStyle
.
solid
,
),
),
})
:
assert
(
items
!=
null
),
})
:
assert
(
items
!=
null
),
assert
(
items
.
length
>=
2
),
assert
(
items
.
length
>=
2
),
assert
(
currentIndex
!=
null
),
assert
(
currentIndex
!=
null
),
...
@@ -90,6 +97,11 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -90,6 +97,11 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// Must not be null.
/// Must not be null.
final
double
iconSize
;
final
double
iconSize
;
/// The border of the [CupertinoTabBar].
///
/// The default value is a one physical pixel top border with grey color.
final
Border
border
;
/// True if the tab bar's background color has no transparency.
/// True if the tab bar's background color has no transparency.
bool
get
opaque
=>
backgroundColor
.
alpha
==
0xFF
;
bool
get
opaque
=>
backgroundColor
.
alpha
==
0xFF
;
...
@@ -101,16 +113,9 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -101,16 +113,9 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
final
double
bottomPadding
=
MediaQuery
.
of
(
context
).
padding
.
bottom
;
final
double
bottomPadding
=
MediaQuery
.
of
(
context
).
padding
.
bottom
;
Widget
result
=
DecoratedBox
(
Widget
result
=
DecoratedBox
(
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
border:
const
Border
(
border:
border
,
top:
BorderSide
(
color:
_kDefaultTabBarBorderColor
,
width:
0.0
,
// One physical pixel.
style:
BorderStyle
.
solid
,
),
),
color:
backgroundColor
,
color:
backgroundColor
,
),
),
// TODO(xster): allow icons-only versions of the tab bar too.
child:
SizedBox
(
child:
SizedBox
(
height:
_kTabBarHeight
+
bottomPadding
,
height:
_kTabBarHeight
+
bottomPadding
,
child:
IconTheme
.
merge
(
// Default with the inactive state.
child:
IconTheme
.
merge
(
// Default with the inactive state.
...
@@ -171,15 +176,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -171,15 +176,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
padding:
const
EdgeInsets
.
only
(
bottom:
4.0
),
padding:
const
EdgeInsets
.
only
(
bottom:
4.0
),
child:
Column
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
end
,
mainAxisAlignment:
MainAxisAlignment
.
end
,
children:
<
Widget
>
[
children:
_buildSingleTabItem
(
items
[
index
],
active
),
Expanded
(
child:
Center
(
child:
active
?
items
[
index
].
activeIcon
:
items
[
index
].
icon
),
),
items
[
index
].
title
,
],
),
),
),
),
),
),
...
@@ -193,6 +190,20 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -193,6 +190,20 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
return
result
;
return
result
;
}
}
List
<
Widget
>
_buildSingleTabItem
(
BottomNavigationBarItem
item
,
bool
active
)
{
final
List
<
Widget
>
components
=
<
Widget
>[
Expanded
(
child:
Center
(
child:
active
?
item
.
activeIcon
:
item
.
icon
),
)
];
if
(
item
.
title
!=
null
)
{
components
.
add
(
item
.
title
);
}
return
components
;
}
/// Change the active tab item's icon and title colors to active.
/// Change the active tab item's icon and title colors to active.
Widget
_wrapActiveItem
(
Widget
item
,
{
@required
bool
active
})
{
Widget
_wrapActiveItem
(
Widget
item
,
{
@required
bool
active
})
{
if
(!
active
)
if
(!
active
)
...
@@ -216,6 +227,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -216,6 +227,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
Color
activeColor
,
Color
activeColor
,
Color
inactiveColor
,
Color
inactiveColor
,
Size
iconSize
,
Size
iconSize
,
Border
border
,
int
currentIndex
,
int
currentIndex
,
ValueChanged
<
int
>
onTap
,
ValueChanged
<
int
>
onTap
,
})
{
})
{
...
@@ -226,6 +238,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
...
@@ -226,6 +238,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
activeColor:
activeColor
??
this
.
activeColor
,
activeColor:
activeColor
??
this
.
activeColor
,
inactiveColor:
inactiveColor
??
this
.
inactiveColor
,
inactiveColor:
inactiveColor
??
this
.
inactiveColor
,
iconSize:
iconSize
??
this
.
iconSize
,
iconSize:
iconSize
??
this
.
iconSize
,
border:
border
??
this
.
border
,
currentIndex:
currentIndex
??
this
.
currentIndex
,
currentIndex:
currentIndex
??
this
.
currentIndex
,
onTap:
onTap
??
this
.
onTap
,
onTap:
onTap
??
this
.
onTap
,
);
);
...
...
packages/flutter/lib/src/material/bottom_navigation_bar.dart
View file @
a3670a2f
...
@@ -77,7 +77,7 @@ class BottomNavigationBar extends StatefulWidget {
...
@@ -77,7 +77,7 @@ class BottomNavigationBar extends StatefulWidget {
/// Creates a bottom navigation bar, typically used in a [Scaffold] where it
/// Creates a bottom navigation bar, typically used in a [Scaffold] where it
/// is provided as the [Scaffold.bottomNavigationBar] argument.
/// is provided as the [Scaffold.bottomNavigationBar] argument.
///
///
/// The length of [items] must be at least two.
/// The length of [items] must be at least two
and each item's icon and title must be not null
.
///
///
/// If [type] is null then [BottomNavigationBarType.fixed] is used when there
/// If [type] is null then [BottomNavigationBarType.fixed] is used when there
/// are two or three [items], [BottomNavigationBarType.shifting] otherwise.
/// are two or three [items], [BottomNavigationBarType.shifting] otherwise.
...
@@ -95,12 +95,16 @@ class BottomNavigationBar extends StatefulWidget {
...
@@ -95,12 +95,16 @@ class BottomNavigationBar extends StatefulWidget {
this
.
iconSize
=
24.0
,
this
.
iconSize
=
24.0
,
})
:
assert
(
items
!=
null
),
})
:
assert
(
items
!=
null
),
assert
(
items
.
length
>=
2
),
assert
(
items
.
length
>=
2
),
assert
(
items
.
every
((
BottomNavigationBarItem
item
)
=>
item
.
title
!=
null
)
==
true
,
'Every item must have a non-null title'
,
),
assert
(
0
<=
currentIndex
&&
currentIndex
<
items
.
length
),
assert
(
0
<=
currentIndex
&&
currentIndex
<
items
.
length
),
assert
(
iconSize
!=
null
),
assert
(
iconSize
!=
null
),
type
=
type
??
(
items
.
length
<=
3
?
BottomNavigationBarType
.
fixed
:
BottomNavigationBarType
.
shifting
),
type
=
type
??
(
items
.
length
<=
3
?
BottomNavigationBarType
.
fixed
:
BottomNavigationBarType
.
shifting
),
super
(
key:
key
);
super
(
key:
key
);
/// The interactive items laid out within the bottom navigation bar.
/// The interactive items laid out within the bottom navigation bar
where each item has an icon and title
.
final
List
<
BottomNavigationBarItem
>
items
;
final
List
<
BottomNavigationBarItem
>
items
;
/// The callback that is called when a item is tapped.
/// The callback that is called when a item is tapped.
...
@@ -149,8 +153,7 @@ class _BottomNavigationTile extends StatelessWidget {
...
@@ -149,8 +153,7 @@ class _BottomNavigationTile extends StatelessWidget {
this
.
flex
,
this
.
flex
,
this
.
selected
=
false
,
this
.
selected
=
false
,
this
.
indexLabel
,
this
.
indexLabel
,
}
})
:
assert
(
selected
!=
null
);
):
assert
(
selected
!=
null
);
final
BottomNavigationBarType
type
;
final
BottomNavigationBarType
type
;
final
BottomNavigationBarItem
item
;
final
BottomNavigationBarItem
item
;
...
@@ -335,7 +338,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr
...
@@ -335,7 +338,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr
return
CurvedAnimation
(
return
CurvedAnimation
(
parent:
_controllers
[
index
],
parent:
_controllers
[
index
],
curve:
Curves
.
fastOutSlowIn
,
curve:
Curves
.
fastOutSlowIn
,
reverseCurve:
Curves
.
fastOutSlowIn
.
flipped
reverseCurve:
Curves
.
fastOutSlowIn
.
flipped
,
);
);
});
});
_controllers
[
widget
.
currentIndex
].
value
=
1.0
;
_controllers
[
widget
.
currentIndex
].
value
=
1.0
;
...
@@ -475,7 +478,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr
...
@@ -475,7 +478,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr
flex:
_evaluateFlex
(
_animations
[
i
]),
flex:
_evaluateFlex
(
_animations
[
i
]),
selected:
i
==
widget
.
currentIndex
,
selected:
i
==
widget
.
currentIndex
,
indexLabel:
localizations
.
tabLabel
(
tabIndex:
i
+
1
,
tabCount:
widget
.
items
.
length
),
indexLabel:
localizations
.
tabLabel
(
tabIndex:
i
+
1
,
tabCount:
widget
.
items
.
length
),
)
)
,
);
);
}
}
break
;
break
;
...
@@ -567,7 +570,7 @@ class _Circle {
...
@@ -567,7 +570,7 @@ class _Circle {
);
);
animation
=
CurvedAnimation
(
animation
=
CurvedAnimation
(
parent:
controller
,
parent:
controller
,
curve:
Curves
.
fastOutSlowIn
curve:
Curves
.
fastOutSlowIn
,
);
);
controller
.
forward
();
controller
.
forward
();
}
}
...
...
packages/flutter/lib/src/widgets/bottom_navigation_bar_item.dart
View file @
a3670a2f
...
@@ -21,15 +21,14 @@ import 'framework.dart';
...
@@ -21,15 +21,14 @@ import 'framework.dart';
class
BottomNavigationBarItem
{
class
BottomNavigationBarItem
{
/// Creates an item that is used with [BottomNavigationBar.items].
/// Creates an item that is used with [BottomNavigationBar.items].
///
///
/// The argument
s [icon] and [title] should not be null
.
/// The argument
[icon] should not be null and the argument [title] should not be null when used in a Material Design's [BottomNavigationBar]
.
const
BottomNavigationBarItem
({
const
BottomNavigationBarItem
({
@required
this
.
icon
,
@required
this
.
icon
,
@required
this
.
title
,
this
.
title
,
Widget
activeIcon
,
Widget
activeIcon
,
this
.
backgroundColor
,
this
.
backgroundColor
,
})
:
activeIcon
=
activeIcon
??
icon
,
})
:
activeIcon
=
activeIcon
??
icon
,
assert
(
icon
!=
null
),
assert
(
icon
!=
null
);
assert
(
title
!=
null
);
/// The icon of the item.
/// The icon of the item.
///
///
...
@@ -61,7 +60,7 @@ class BottomNavigationBarItem {
...
@@ -61,7 +60,7 @@ class BottomNavigationBarItem {
/// * [BottomNavigationBarItem.icon], for a description of how to pair icons.
/// * [BottomNavigationBarItem.icon], for a description of how to pair icons.
final
Widget
activeIcon
;
final
Widget
activeIcon
;
/// The title of the item.
/// The title of the item.
If the title is not provided only the icon will be shown when not used in a Material Design [BottomNavigationBar].
final
Widget
title
;
final
Widget
title
;
/// The color of the background radial animation for material [BottomNavigationBar].
/// The color of the background radial animation for material [BottomNavigationBar].
...
...
packages/flutter/test/cupertino/bottom_tab_bar_test.dart
View file @
a3670a2f
...
@@ -238,4 +238,98 @@ void main() {
...
@@ -238,4 +238,98 @@ void main() {
semantics
.
dispose
();
semantics
.
dispose
();
});
});
testWidgets
(
'Title of items should be nullable'
,
(
WidgetTester
tester
)
async
{
const
TestImageProvider
iconProvider
=
TestImageProvider
(
16
,
16
);
final
List
<
int
>
itemsTapped
=
<
int
>[];
await
pumpWidgetWithBoilerplate
(
tester
,
MediaQuery
(
data:
const
MediaQueryData
(),
child:
CupertinoTabBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
ImageIcon
(
TestImageProvider
(
24
,
24
),
),
title:
Text
(
'Tab 1'
),
),
BottomNavigationBarItem
(
icon:
ImageIcon
(
iconProvider
,
),
),
],
onTap:
(
int
index
)
=>
itemsTapped
.
add
(
index
),
),
));
expect
(
find
.
text
(
'Tab 1'
),
findsOneWidget
);
final
Finder
finder
=
find
.
byWidgetPredicate
(
(
Widget
widget
)
=>
widget
is
Image
&&
widget
.
image
==
iconProvider
);
await
tester
.
tap
(
finder
);
expect
(
itemsTapped
,
<
int
>[
1
]);
});
testWidgets
(
'Hide border hides the top border of the tabBar'
,
(
WidgetTester
tester
)
async
{
await
pumpWidgetWithBoilerplate
(
tester
,
MediaQuery
(
data:
const
MediaQueryData
(),
child:
CupertinoTabBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
ImageIcon
(
TestImageProvider
(
24
,
24
),
),
title:
Text
(
'Tab 1'
),
),
BottomNavigationBarItem
(
icon:
ImageIcon
(
TestImageProvider
(
24
,
24
),
),
title:
Text
(
'Tab 2'
),
),
],
),
));
final
DecoratedBox
decoratedBox
=
tester
.
widget
(
find
.
byType
(
DecoratedBox
));
final
BoxDecoration
boxDecoration
=
decoratedBox
.
decoration
;
expect
(
boxDecoration
.
border
,
isNotNull
);
await
pumpWidgetWithBoilerplate
(
tester
,
MediaQuery
(
data:
const
MediaQueryData
(),
child:
CupertinoTabBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
ImageIcon
(
TestImageProvider
(
24
,
24
),
),
title:
Text
(
'Tab 1'
),
),
BottomNavigationBarItem
(
icon:
ImageIcon
(
TestImageProvider
(
24
,
24
),
),
title:
Text
(
'Tab 2'
),
),
],
backgroundColor:
const
Color
(
0xFFFFFFFF
),
// Opaque white.
border:
null
,
),
));
final
DecoratedBox
decoratedBoxHiddenBorder
=
tester
.
widget
(
find
.
byType
(
DecoratedBox
));
final
BoxDecoration
boxDecorationHiddenBorder
=
decoratedBoxHiddenBorder
.
decoration
;
expect
(
boxDecorationHiddenBorder
.
border
,
isNull
);
});
}
}
\ No newline at end of file
packages/flutter/test/material/bottom_navigation_bar_test.dart
View file @
a3670a2f
...
@@ -781,6 +781,25 @@ void main() {
...
@@ -781,6 +781,25 @@ void main() {
expect
(
_backgroundColor
,
Colors
.
green
);
expect
(
_backgroundColor
,
Colors
.
green
);
expect
(
tester
.
widget
<
Material
>(
backgroundMaterial
).
color
,
Colors
.
green
);
expect
(
tester
.
widget
<
Material
>(
backgroundMaterial
).
color
,
Colors
.
green
);
});
});
testWidgets
(
'BottomNavigationBar item title should not be nullable'
,
(
WidgetTester
tester
)
async
{
expect
(()
{
MaterialApp
(
home:
Scaffold
(
bottomNavigationBar:
BottomNavigationBar
(
type:
BottomNavigationBarType
.
shifting
,
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
ac_unit
),
title:
Text
(
'AC'
),
),
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
access_alarm
),
)
])));
},
throwsA
(
isInstanceOf
<
AssertionError
>()));
});
}
}
Widget
boilerplate
(
{
Widget
bottomNavigationBar
,
@required
TextDirection
textDirection
})
{
Widget
boilerplate
(
{
Widget
bottomNavigationBar
,
@required
TextDirection
textDirection
})
{
...
...
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