您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
231 行
8.6 KiB
231 行
8.6 KiB
using System.Collections.Generic;
|
|
using Unity.UIWidgets.foundation;
|
|
using Unity.UIWidgets.gestures;
|
|
using Unity.UIWidgets.painting;
|
|
using Unity.UIWidgets.rendering;
|
|
using Unity.UIWidgets.ui;
|
|
using Unity.UIWidgets.widgets;
|
|
using TextStyle = Unity.UIWidgets.painting.TextStyle;
|
|
|
|
namespace Unity.UIWidgets.cupertino {
|
|
class BottomAppBarUtils {
|
|
public const float _kTabBarHeight = 50.0f;
|
|
|
|
public static readonly Color _kDefaultTabBarBorderColor =
|
|
CupertinoDynamicColor.withBrightness(
|
|
color: new Color(0x4C000000),
|
|
darkColor: new Color(0x29000000)
|
|
);
|
|
public static readonly Color _kDefaultTabBarInactiveColor = CupertinoColors.inactiveGray;
|
|
}
|
|
|
|
|
|
public class CupertinoTabBar : StatelessWidget{
|
|
|
|
public CupertinoTabBar(
|
|
Key key = null,
|
|
List<BottomNavigationBarItem> items = null,
|
|
ValueChanged<int> onTap = null,
|
|
int currentIndex = 0,
|
|
Color backgroundColor = null,
|
|
Color activeColor = null,
|
|
Color inactiveColor = null,
|
|
float iconSize = 30.0f,
|
|
Border border = null
|
|
) : base(key: key) {
|
|
|
|
D.assert(items != null);
|
|
D.assert(items.Count >= 2,
|
|
() => "Tabs need at least 2 items to conform to Apple's HIG"
|
|
);
|
|
D.assert(0 <= currentIndex && currentIndex < items.Count);
|
|
|
|
this.items = items;
|
|
this.onTap = onTap;
|
|
this.currentIndex = currentIndex;
|
|
this.backgroundColor = backgroundColor;
|
|
this.activeColor = activeColor;
|
|
this.inactiveColor = inactiveColor ?? BottomAppBarUtils._kDefaultTabBarInactiveColor;
|
|
this.iconSize = iconSize;
|
|
this.border = border ?? new Border(
|
|
top: new BorderSide(
|
|
color: BottomAppBarUtils._kDefaultTabBarBorderColor,
|
|
width: 0.0f,
|
|
style: BorderStyle.solid
|
|
)
|
|
);
|
|
}
|
|
|
|
public readonly List<BottomNavigationBarItem> items;
|
|
|
|
public readonly ValueChanged<int> onTap;
|
|
|
|
public readonly int currentIndex;
|
|
|
|
public readonly Color backgroundColor;
|
|
|
|
public readonly Color activeColor;
|
|
|
|
public readonly Color inactiveColor;
|
|
|
|
public readonly float iconSize;
|
|
|
|
public readonly Border border;
|
|
|
|
public Size preferredSize {
|
|
get { return Size.fromHeight(BottomAppBarUtils._kTabBarHeight); }
|
|
}
|
|
|
|
public bool opaque(BuildContext context) {
|
|
|
|
Color backgroundColor =
|
|
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor;
|
|
|
|
return CupertinoDynamicColor.resolve(backgroundColor, context).alpha == 0xFF;
|
|
}
|
|
|
|
public override Widget build(BuildContext context) {
|
|
float bottomPadding = MediaQuery.of(context).padding.bottom;
|
|
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));
|
|
}
|
|
Border resolvedBorder = border == null || border.GetType() != typeof(Border)
|
|
? border
|
|
: new Border(
|
|
top: resolveBorderSide(border.top),
|
|
left: resolveBorderSide(border.left),
|
|
bottom: resolveBorderSide(border.bottom),
|
|
right: resolveBorderSide(border.right)
|
|
);
|
|
|
|
Color inactive = CupertinoDynamicColor.resolve(inactiveColor, context);
|
|
Widget result = new DecoratedBox(
|
|
decoration: new BoxDecoration(
|
|
border: resolvedBorder,
|
|
color: backgroundColor
|
|
),
|
|
child: new SizedBox(
|
|
height: BottomAppBarUtils._kTabBarHeight + bottomPadding,
|
|
child: IconTheme.merge( // Default with the inactive state.
|
|
data: new IconThemeData(
|
|
color: inactiveColor,
|
|
size: iconSize
|
|
),
|
|
child: new DefaultTextStyle( // Default with the inactive state.
|
|
style: CupertinoTheme.of(context).textTheme.tabLabelTextStyle.copyWith(color: inactive),
|
|
child: new Padding(
|
|
padding: EdgeInsets.only(bottom: bottomPadding),
|
|
child: new Row(
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
children: _buildTabItems(context)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
if (!opaque(context)) {
|
|
result = new ClipRect(
|
|
child: new BackdropFilter(
|
|
filter: ImageFilter.blur(sigmaX: 10.0f, sigmaY: 10.0f),
|
|
child: result
|
|
)
|
|
);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
List<Widget> _buildTabItems(BuildContext context) {
|
|
List<Widget> result = new List<Widget> { };
|
|
|
|
for (int index = 0; index < items.Count; index += 1) {
|
|
bool active = index == currentIndex;
|
|
var tabIndex = index;
|
|
result.Add(
|
|
_wrapActiveItem(
|
|
context,
|
|
new Expanded(
|
|
child: new GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: onTap == null ? null : (GestureTapCallback) (() => { onTap(tabIndex); }),
|
|
child: new Padding(
|
|
padding: EdgeInsets.only(bottom: 4.0f),
|
|
child: new Column(
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
children: _buildSingleTabItem(items[index], active)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
active: active
|
|
)
|
|
);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
List<Widget> _buildSingleTabItem(BottomNavigationBarItem item, bool active) {
|
|
List<Widget> components = new List<Widget> {
|
|
new Expanded(
|
|
child: new Center(child: active ? item.activeIcon : item.icon)
|
|
)
|
|
};
|
|
|
|
if (item.title != null) {
|
|
components.Add(item.title);
|
|
}
|
|
|
|
return components;
|
|
}
|
|
|
|
Widget _wrapActiveItem(BuildContext context, Widget item, bool active) {
|
|
if (!active) {
|
|
return item;
|
|
}
|
|
Color activeColor = CupertinoDynamicColor.resolve(
|
|
this.activeColor ?? CupertinoTheme.of(context).primaryColor,
|
|
context
|
|
);
|
|
return IconTheme.merge(
|
|
data: new IconThemeData(color: activeColor),
|
|
child: DefaultTextStyle.merge(
|
|
style: new TextStyle(color: activeColor),
|
|
child: item
|
|
)
|
|
);
|
|
}
|
|
|
|
public CupertinoTabBar copyWith(
|
|
Key key = null,
|
|
List<BottomNavigationBarItem> items = null,
|
|
Color backgroundColor = null,
|
|
Color activeColor = null,
|
|
Color inactiveColor = null,
|
|
float? iconSize = null,
|
|
Border border = null,
|
|
int? currentIndex = null,
|
|
ValueChanged<int> onTap = null
|
|
) {
|
|
return new CupertinoTabBar(
|
|
key: key ?? this.key,
|
|
items: items ?? this.items,
|
|
backgroundColor: backgroundColor ?? this.backgroundColor,
|
|
activeColor: activeColor ?? this.activeColor,
|
|
inactiveColor: inactiveColor ?? this.inactiveColor,
|
|
iconSize: iconSize ?? this.iconSize,
|
|
border: border ?? this.border,
|
|
currentIndex: currentIndex ?? this.currentIndex,
|
|
onTap: onTap ?? this.onTap
|
|
);
|
|
}
|
|
}
|
|
}
|