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
443892bd
Unverified
Commit
443892bd
authored
Sep 05, 2019
by
LongCatIsLooong
Committed by
GitHub
Sep 05, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CupertinoButton & Bottom tab bar dark mode (#39765)
* CupertinoTabBar * CupertinoButton * update * review
parent
b6abf0ca
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
204 additions
and
39 deletions
+204
-39
bottom_tab_bar.dart
packages/flutter/lib/src/cupertino/bottom_tab_bar.dart
+44
-19
button.dart
packages/flutter/lib/src/cupertino/button.dart
+16
-14
bottom_tab_bar_test.dart
packages/flutter/test/cupertino/bottom_tab_bar_test.dart
+91
-2
button_test.dart
packages/flutter/test/cupertino/button_test.dart
+49
-0
tab_scaffold_test.dart
...es/flutter/test/cupertino/material/tab_scaffold_test.dart
+1
-1
tab_scaffold_test.dart
packages/flutter/test/cupertino/tab_scaffold_test.dart
+3
-3
No files found.
packages/flutter/lib/src/cupertino/bottom_tab_bar.dart
View file @
443892bd
...
...
@@ -12,7 +12,14 @@ import 'theme.dart';
// Standard iOS 10 tab bar height.
const
double
_kTabBarHeight
=
50.0
;
const
Color
_kDefaultTabBarBorderColor
=
Color
(
0x4C000000
);
const
Color
_kDefaultTabBarBorderColor
=
CupertinoDynamicColor
.
withBrightness
(
color:
Color
(
0x4C000000
),
darkColor:
Color
(
0x29000000
),
);
const
Color
_kDefaultTabBarInactiveColor
=
CupertinoDynamicColor
.
withBrightness
(
color:
Color
(
0xFF999999
),
darkColor:
Color
(
0xFF757575
),
);
/// An iOS-styled bottom navigation tab bar.
///
...
...
@@ -52,7 +59,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
this
.
currentIndex
=
0
,
this
.
backgroundColor
,
this
.
activeColor
,
this
.
inactiveColor
=
CupertinoColors
.
inactiveGray
,
this
.
inactiveColor
=
_kDefaultTabBarInactiveColor
,
this
.
iconSize
=
30.0
,
this
.
border
=
const
Border
(
top:
BorderSide
(
...
...
@@ -106,7 +113,8 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// The foreground color of the icon and title for the [BottomNavigationBarItem]s
/// in the unselected state.
///
/// Defaults to [CupertinoColors.inactiveGray] and cannot be null.
/// Defaults to a [CupertinoDynamicColor] that matches the disabled foreground
/// color of the native `UITabBar` component. Cannot be null.
final
Color
inactiveColor
;
/// The size of all of the [BottomNavigationBarItem] icons.
...
...
@@ -131,27 +139,46 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
bool
opaque
(
BuildContext
context
)
{
final
Color
backgroundColor
=
this
.
backgroundColor
??
CupertinoTheme
.
of
(
context
).
barBackgroundColor
;
return
backgroundColor
.
alpha
==
0xFF
;
return
CupertinoDynamicColor
.
resolve
(
backgroundColor
,
context
)
.
alpha
==
0xFF
;
}
@override
Widget
build
(
BuildContext
context
)
{
final
double
bottomPadding
=
MediaQuery
.
of
(
context
).
padding
.
bottom
;
final
Color
backgroundColor
=
CupertinoDynamicColor
.
resolve
(
this
.
backgroundColor
??
CupertinoTheme
.
of
(
context
).
barBackgroundColor
,
context
,
);
BorderSide
resolveBorderSide
(
BorderSide
side
)
{
return
side
==
BorderSide
.
none
?
side
:
side
.
copyWith
(
color:
CupertinoDynamicColor
.
resolve
(
side
.
color
,
context
));
}
// Return the border as is when it's a subclass.
final
Border
resolvedBorder
=
border
==
null
||
border
.
runtimeType
!=
Border
?
border
:
Border
(
top:
resolveBorderSide
(
border
.
top
),
left:
resolveBorderSide
(
border
.
left
),
bottom:
resolveBorderSide
(
border
.
bottom
),
right:
resolveBorderSide
(
border
.
right
),
);
final
Color
inactive
=
CupertinoDynamicColor
.
resolve
(
inactiveColor
,
context
);
Widget
result
=
DecoratedBox
(
decoration:
BoxDecoration
(
border:
b
order
,
color:
backgroundColor
??
CupertinoTheme
.
of
(
context
).
barBackgroundColor
,
border:
resolvedB
order
,
color:
backgroundColor
,
),
child:
SizedBox
(
height:
_kTabBarHeight
+
bottomPadding
,
child:
IconTheme
.
merge
(
// Default with the inactive state.
data:
IconThemeData
(
color:
inactiveColor
,
size:
iconSize
,
),
data:
IconThemeData
(
color:
inactive
,
size:
iconSize
),
child:
DefaultTextStyle
(
// Default with the inactive state.
style:
CupertinoTheme
.
of
(
context
).
textTheme
.
tabLabelTextStyle
.
copyWith
(
color:
inactive
Color
),
style:
CupertinoTheme
.
of
(
context
).
textTheme
.
tabLabelTextStyle
.
copyWith
(
color:
inactive
),
child:
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
bottomPadding
),
child:
Row
(
...
...
@@ -213,17 +240,12 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
}
List
<
Widget
>
_buildSingleTabItem
(
BottomNavigationBarItem
item
,
bool
active
)
{
final
List
<
Widget
>
components
=
<
Widget
>[
return
<
Widget
>[
Expanded
(
child:
Center
(
child:
active
?
item
.
activeIcon
:
item
.
icon
),
),
if
(
item
.
title
!=
null
)
item
.
title
,
];
if
(
item
.
title
!=
null
)
{
components
.
add
(
item
.
title
);
}
return
components
;
}
/// Change the active tab item's icon and title colors to active.
...
...
@@ -231,7 +253,10 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
if
(!
active
)
return
item
;
final
Color
activeColor
=
this
.
activeColor
??
CupertinoTheme
.
of
(
context
).
primaryColor
;
final
Color
activeColor
=
CupertinoDynamicColor
.
resolve
(
this
.
activeColor
??
CupertinoTheme
.
of
(
context
).
primaryColor
,
context
,
);
return
IconTheme
.
merge
(
data:
IconThemeData
(
color:
activeColor
),
child:
DefaultTextStyle
.
merge
(
...
...
packages/flutter/lib/src/cupertino/button.dart
View file @
443892bd
...
...
@@ -5,13 +5,11 @@
import
'package:flutter/foundation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'constants.dart'
;
import
'theme.dart'
;
const
Color
_kDisabledBackground
=
Color
(
0xFFA9A9A9
);
// Measured against iOS 12 in Xcode.
const
Color
_kDisabledForeground
=
Color
(
0xFFD1D1D1
);
const
EdgeInsets
_kButtonPadding
=
EdgeInsets
.
all
(
16.0
);
const
EdgeInsets
_kBackgroundButtonPadding
=
EdgeInsets
.
symmetric
(
vertical:
14.0
,
...
...
@@ -84,8 +82,8 @@ class CupertinoButton extends StatefulWidget {
///
/// Ignored if the [CupertinoButton] doesn't also have a [color].
///
/// Defaults to
a standard iOS disabled color when [color] is specified and
/// [disabledColor] is null.
/// Defaults to
[CupertinoSystemColors.quaternarySystemFill] when [color] is
///
specified and
[disabledColor] is null.
final
Color
disabledColor
;
/// The callback that is called when the button is tapped or otherwise activated.
...
...
@@ -206,15 +204,19 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
@override
Widget
build
(
BuildContext
context
)
{
final
bool
enabled
=
widget
.
enabled
;
final
Color
primaryColor
=
CupertinoTheme
.
of
(
context
).
primaryColor
;
final
Color
backgroundColor
=
widget
.
color
??
(
widget
.
_filled
?
primaryColor
:
null
);
final
CupertinoThemeData
themeData
=
CupertinoTheme
.
of
(
context
);
final
Color
primaryColor
=
themeData
.
primaryColor
;
final
Color
backgroundColor
=
widget
.
color
==
null
?
(
widget
.
_filled
?
primaryColor
:
null
)
:
CupertinoDynamicColor
.
resolve
(
widget
.
color
,
context
);
final
Color
foregroundColor
=
backgroundColor
!=
null
?
CupertinoTheme
.
of
(
context
)
.
primaryContrastingColor
:
enabled
?
primaryColor
:
_kDisabledForeground
;
final
TextStyle
textStyle
=
CupertinoTheme
.
of
(
context
)
.
textTheme
.
textStyle
.
copyWith
(
color:
foregroundColor
);
?
themeData
.
primaryContrastingColor
:
enabled
?
primaryColor
:
CupertinoDynamicColor
.
resolve
(
CupertinoSystemColors
.
of
(
context
).
placeholderText
,
context
)
;
final
TextStyle
textStyle
=
themeData
.
textTheme
.
textStyle
.
copyWith
(
color:
foregroundColor
);
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
...
...
@@ -237,7 +239,7 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
decoration:
BoxDecoration
(
borderRadius:
widget
.
borderRadius
,
color:
backgroundColor
!=
null
&&
!
enabled
?
widget
.
disabledColor
??
_kDisabledBackground
?
CupertinoDynamicColor
.
resolve
(
widget
.
disabledColor
??
CupertinoSystemColors
.
of
(
context
).
quaternarySystemFill
,
context
)
:
backgroundColor
,
),
child:
Padding
(
...
...
packages/flutter/test/cupertino/bottom_tab_bar_test.dart
View file @
443892bd
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'../painting/mocks_for_image_cache.dart'
;
...
...
@@ -68,6 +69,94 @@ void main() {
expect
(
actualActive
.
text
.
style
.
color
,
const
Color
(
0xFF123456
));
});
testWidgets
(
'Active and inactive colors dark mode'
,
(
WidgetTester
tester
)
async
{
const
CupertinoDynamicColor
dynamicActiveColor
=
CupertinoDynamicColor
.
withBrightness
(
color:
Color
(
0xFF000000
),
darkColor:
Color
(
0xFF000001
),
);
const
CupertinoDynamicColor
dynamicInactiveColor
=
CupertinoDynamicColor
.
withBrightness
(
color:
Color
(
0xFF000002
),
darkColor:
Color
(
0xFF000003
),
);
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'
),
),
],
currentIndex:
1
,
activeColor:
dynamicActiveColor
,
inactiveColor:
dynamicInactiveColor
,
),
));
RichText
actualInactive
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 1'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
actualInactive
.
text
.
style
.
color
.
value
,
0xFF000002
);
RichText
actualActive
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
actualActive
.
text
.
style
.
color
.
value
,
0xFF000000
);
final
RenderDecoratedBox
renderDecoratedBox
=
tester
.
renderObject
(
find
.
descendant
(
of:
find
.
byType
(
BackdropFilter
),
matching:
find
.
byType
(
DecoratedBox
),
));
// Border color is resolved correctly.
final
BoxDecoration
decoration1
=
renderDecoratedBox
.
decoration
;
expect
(
decoration1
.
border
.
top
.
color
.
value
,
0x4C000000
);
// Switch to dark mode.
await
pumpWidgetWithBoilerplate
(
tester
,
MediaQuery
(
data:
const
MediaQueryData
(
platformBrightness:
Brightness
.
dark
),
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'
),
),
],
currentIndex:
1
,
activeColor:
dynamicActiveColor
,
inactiveColor:
dynamicInactiveColor
,
),
));
actualInactive
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 1'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
actualInactive
.
text
.
style
.
color
.
value
,
0xFF000003
);
actualActive
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
actualActive
.
text
.
style
.
color
.
value
,
0xFF000001
);
// Border color is resolved correctly.
final
BoxDecoration
decoration2
=
renderDecoratedBox
.
decoration
;
expect
(
decoration2
.
border
.
top
.
color
.
value
,
0x29000000
);
});
testWidgets
(
'Tabs respects themes'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
CupertinoApp
(
...
...
@@ -91,7 +180,7 @@ void main() {
of:
find
.
text
(
'Tab 1'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
actualInactive
.
text
.
style
.
color
,
CupertinoColors
.
inactiveGray
);
expect
(
actualInactive
.
text
.
style
.
color
.
value
,
0xFF999999
);
RichText
actualActive
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
...
...
@@ -122,7 +211,7 @@ void main() {
of:
find
.
text
(
'Tab 1'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
actualInactive
.
text
.
style
.
color
,
CupertinoColors
.
inactiveGray
);
expect
(
actualInactive
.
text
.
style
.
color
.
value
,
0xFF757575
);
actualActive
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
...
...
packages/flutter/test/cupertino/button_test.dart
View file @
443892bd
...
...
@@ -228,6 +228,55 @@ void main() {
expect
(
boxDecoration
.
color
,
const
Color
(
0x0000FF00
));
});
testWidgets
(
'Can specify dynamic colors'
,
(
WidgetTester
tester
)
async
{
const
Color
bgColor
=
CupertinoDynamicColor
.
withBrightness
(
color:
Color
(
0xFF123456
),
darkColor:
Color
(
0xFF654321
),
);
const
Color
inactive
=
CupertinoDynamicColor
.
withBrightness
(
color:
Color
(
0xFF111111
),
darkColor:
Color
(
0xFF222222
),
);
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
platformBrightness:
Brightness
.
dark
),
child:
boilerplate
(
child:
CupertinoButton
(
child:
const
Text
(
'Skeuomorph me'
),
color:
bgColor
,
disabledColor:
inactive
,
onPressed:
()
{
},
))
),
);
BoxDecoration
boxDecoration
=
tester
.
widget
<
DecoratedBox
>(
find
.
widgetWithText
(
DecoratedBox
,
'Skeuomorph me'
)
).
decoration
;
expect
(
boxDecoration
.
color
.
value
,
0xFF654321
);
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
platformBrightness:
Brightness
.
light
),
child:
boilerplate
(
child:
const
CupertinoButton
(
child:
Text
(
'Skeuomorph me'
),
color:
bgColor
,
disabledColor:
inactive
,
onPressed:
null
,
))
),
);
boxDecoration
=
tester
.
widget
<
DecoratedBox
>(
find
.
widgetWithText
(
DecoratedBox
,
'Skeuomorph me'
)
).
decoration
;
// Disabled color.
expect
(
boxDecoration
.
color
.
value
,
0xFF111111
);
});
testWidgets
(
'Button respects themes'
,
(
WidgetTester
tester
)
async
{
TextStyle
textStyle
;
...
...
packages/flutter/test/cupertino/material/tab_scaffold_test.dart
View file @
443892bd
...
...
@@ -166,7 +166,7 @@ void main() {
matching:
find
.
byType
(
RichText
),
));
// Tab 2 should still be selected after changing theme.
expect
(
tab1
.
text
.
style
.
color
,
CupertinoColors
.
inactiveGray
);
expect
(
tab1
.
text
.
style
.
color
.
value
,
0xFF757575
);
final
RichText
tab2
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
matching:
find
.
byType
(
RichText
),
...
...
packages/flutter/test/cupertino/tab_scaffold_test.dart
View file @
443892bd
...
...
@@ -76,7 +76,7 @@ void main() {
of:
find
.
text
(
'Tab 2'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
tab2
.
text
.
style
.
color
,
CupertinoColors
.
inactiveGray
);
expect
(
tab2
.
text
.
style
.
color
.
value
,
0xFF999999
);
await
tester
.
tap
(
find
.
text
(
'Tab 2'
));
await
tester
.
pump
();
...
...
@@ -86,7 +86,7 @@ void main() {
of:
find
.
text
(
'Tab 1'
),
matching:
find
.
byType
(
RichText
),
));
expect
(
tab1
.
text
.
style
.
color
,
CupertinoColors
.
inactiveGray
);
expect
(
tab1
.
text
.
style
.
color
.
value
,
0xFF999999
);
tab2
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
matching:
find
.
byType
(
RichText
),
...
...
@@ -373,7 +373,7 @@ void main() {
matching:
find
.
byType
(
RichText
),
));
// Tab 2 should still be selected after changing theme.
expect
(
tab1
.
text
.
style
.
color
,
CupertinoColors
.
inactiveGray
);
expect
(
tab1
.
text
.
style
.
color
.
value
,
0xFF757575
);
final
RichText
tab2
=
tester
.
widget
(
find
.
descendant
(
of:
find
.
text
(
'Tab 2'
),
matching:
find
.
byType
(
RichText
),
...
...
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