浏览代码

Merge pull request #281 from UnityTech/yczhang1.5.4

[Cupertino] Implement nav bar (with ValueListenerBuilder and DefaultTextStyleTransition)
/main
GitHub 5 年前
当前提交
5836cbf7
共有 10 个文件被更改,包括 1354 次插入10 次删除
  1. 8
      Runtime/cupertino/page_scaffold.cs
  2. 2
      Runtime/cupertino/text_theme.cs
  3. 12
      Runtime/cupertino/theme.cs
  4. 43
      Runtime/widgets/transitions.cs
  5. 202
      Runtime/cupertino/bottom_app_bar.cs
  6. 11
      Runtime/cupertino/bottom_app_bar.cs.meta
  7. 1001
      Runtime/cupertino/nav_bar.cs
  8. 11
      Runtime/cupertino/nav_bar.cs.meta
  9. 63
      Runtime/widgets/value_listenable_builder.cs
  10. 11
      Runtime/widgets/value_listenable_builder.cs.meta

8
Runtime/cupertino/page_scaffold.cs


? existingMediaQuery.viewInsets.copyWith(bottom: 0.0f)
: existingMediaQuery.viewInsets;
bool fullObstruction =
bool? fullObstruction =
if (fullObstruction) {
if (fullObstruction == true) {
paddedContent = new MediaQuery(
data: existingMediaQuery
.removePadding(removeTop: true)

}
public abstract class ObstructingPreferredSizeWidget : PreferredSizeWidget {
public bool fullObstruction { get; }
protected ObstructingPreferredSizeWidget(Key key = null) : base(key: key) {}
public virtual bool? fullObstruction { get; }
}
}

2
Runtime/cupertino/text_theme.cs


readonly TextStyle _navTitleTextStyle;
TextStyle navTitleTextStyle {
public TextStyle navTitleTextStyle {
get {
return this._navTitleTextStyle ??
(this._isLight

12
Runtime/cupertino/theme.cs


}
public CupertinoThemeData copyWith(
Brightness? brightness,
Color primaryColor,
Color primaryContrastingColor,
CupertinoTextThemeData textTheme,
Color barBackgroundColor,
Color scaffoldBackgroundColor
Brightness? brightness = null,
Color primaryColor = null,
Color primaryContrastingColor = null,
CupertinoTextThemeData textTheme = null,
Color barBackgroundColor = null,
Color scaffoldBackgroundColor = null
) {
return new CupertinoThemeData(
brightness: brightness ?? this._brightness,

43
Runtime/widgets/transitions.cs


using Unity.UIWidgets.ui;
using UnityEngine;
using Rect = Unity.UIWidgets.ui.Rect;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.widgets {
public abstract class AnimatedWidget : StatefulWidget {

alignment: this.alignment.value,
widthFactor: this.widthFactor,
heightFactor: this.heightFactor,
child: this.child
);
}
}
public class DefaultTextStyleTransition : AnimatedWidget {
public DefaultTextStyleTransition(
Key key = null,
Animation<TextStyle> style = null,
Widget child = null,
TextAlign? textAlign = null,
bool softWrap = true,
TextOverflow overflow = TextOverflow.clip,
int? maxLines = null
) : base(key: key, listenable: style) {
D.assert(style != null);
D.assert(child != null);
this.textAlign = textAlign;
this.softWrap = softWrap;
this.overflow = overflow;
this.maxLines = maxLines;
this.child = child;
}
Animation<TextStyle> style {
get { return (Animation<TextStyle>) this.listenable; }
}
public readonly TextAlign? textAlign;
public readonly bool softWrap;
public readonly TextOverflow overflow;
public readonly int? maxLines;
public readonly Widget child;
protected internal override Widget build(BuildContext context) {
return new DefaultTextStyle(
style: this.style.value,
textAlign: this.textAlign,
softWrap: this.softWrap,
overflow: this.overflow,
maxLines: this.maxLines,
child: this.child
);
}

202
Runtime/cupertino/bottom_app_bar.cs


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 = new Color(0x4C000000);
}
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);
D.assert(inactiveColor != null);
this.items = items;
this.onTap = onTap;
this.currentIndex = currentIndex;
this.backgroundColor = backgroundColor;
this.activeColor = activeColor;
this.inactiveColor = inactiveColor ?? CupertinoColors.inactiveGray;
this.iconSize = iconSize;
this.border = border ?? new Border(
top: new BorderSide(
color: BottomAppBarUtils._kDefaultTabBarBorderColor,
width: 0.0f, // One physical pixel.
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); }
}
bool opaque(BuildContext context) {
Color backgroundColor =
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor;
return backgroundColor.alpha == 0xFF;
}
public override Widget build(BuildContext context) {
float bottomPadding = MediaQuery.of(context).padding.bottom;
Widget result = new DecoratedBox(
decoration: new BoxDecoration(
border: this.border,
color: this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor
),
child: new SizedBox(
height: BottomAppBarUtils._kTabBarHeight + bottomPadding,
child: IconTheme.merge( // Default with the inactive state.
data: new IconThemeData(
color: this.inactiveColor,
size: this.iconSize
),
child: new DefaultTextStyle( // Default with the inactive state.
style: CupertinoTheme.of(context).textTheme.tabLabelTextStyle
.copyWith(color: this.inactiveColor),
child: new Padding(
padding: EdgeInsets.only(bottom: bottomPadding),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: this._buildTabItems(context)
)
)
)
)
)
);
if (!this.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 < this.items.Count; index += 1) {
bool active = index == this.currentIndex;
result.Add(
this._wrapActiveItem(
context,
new Expanded(
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: this.onTap == null ? null : (GestureTapCallback) (() => { this.onTap(index); }),
child: new Padding(
padding: EdgeInsets.only(bottom: 4.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.end,
children: this._buildSingleTabItem(this.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 = this.activeColor ?? CupertinoTheme.of(context).primaryColor;
return IconTheme.merge(
data: new IconThemeData(color: activeColor),
child: DefaultTextStyle.merge(
style: new TextStyle(color: activeColor),
child: item
)
);
}
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
);
}
}
}

11
Runtime/cupertino/bottom_app_bar.cs.meta


fileFormatVersion: 2
guid: a4d68e50e84368e42b995ebca3727675
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

1001
Runtime/cupertino/nav_bar.cs
文件差异内容过多而无法显示
查看文件

11
Runtime/cupertino/nav_bar.cs.meta


fileFormatVersion: 2
guid: 3b784deecd91aef4085ba0796eea3324
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

63
Runtime/widgets/value_listenable_builder.cs


using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.widgets {
public delegate Widget ValueWidgetBuilder<T>(BuildContext context, T value, Widget child);
public class ValueListenableBuilder<T> : StatefulWidget {
public ValueListenableBuilder(
ValueListenable<T> valueListenable,
ValueWidgetBuilder<T> builder,
Widget child = null
) {
D.assert(valueListenable != null);
D.assert(builder != null);
this.valueListenable = valueListenable;
this.builder = builder;
this.child = child;
}
public readonly ValueListenable<T> valueListenable;
public readonly ValueWidgetBuilder<T> builder;
public readonly Widget child;
public override State createState() {
return new _ValueListenableBuilderState<T>();
}
}
class _ValueListenableBuilderState<T> : State<ValueListenableBuilder<T>> {
T value;
public override void initState() {
base.initState();
this.value = this.widget.valueListenable.value;
this.widget.valueListenable.addListener(this._valueChanged);
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
ValueListenableBuilder<T> oldWidget = _oldWidget as ValueListenableBuilder<T>;
if (oldWidget.valueListenable != this.widget.valueListenable) {
oldWidget.valueListenable.removeListener(this._valueChanged);
this.value = this.widget.valueListenable.value;
this.widget.valueListenable.addListener(this._valueChanged);
}
base.didUpdateWidget(oldWidget);
}
public override void dispose() {
this.widget.valueListenable.removeListener(this._valueChanged);
base.dispose();
}
void _valueChanged() {
this.setState(() => { this.value = this.widget.valueListenable.value; });
}
public override Widget build(BuildContext context) {
return this.widget.builder(context, this.value, this.widget.child);
}
}
}

11
Runtime/widgets/value_listenable_builder.cs.meta


fileFormatVersion: 2
guid: c4b7ae22b588cdf4093501087a4ecadb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存