浏览代码

Merge branch 'zgh/cupertino/fix' into dev_1.17.5

/siyaoH-1.17-PlatformMessage
guanghuispark 4 年前
当前提交
a9d99233
共有 153 个文件被更改,包括 12176 次插入16 次删除
  1. 4
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs
  2. 2
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/model/app_state_model.cs
  3. 4
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/model/product.cs
  4. 7
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/model/scoped_model.cs
  5. 2
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/backdrop.cs
  6. 9
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demos.cs
  7. 4
      com.unity.uiwidgets/Runtime/animation/tween_sequence.cs
  8. 2
      com.unity.uiwidgets/Runtime/material/button_theme.cs
  9. 2
      com.unity.uiwidgets/Runtime/painting/image_provider.cs
  10. 4
      com.unity.uiwidgets/Runtime/widgets/animated_list.cs
  11. 2
      com.unity.uiwidgets/Runtime/widgets/heroes.cs
  12. 5
      com.unity.uiwidgets/Runtime/widgets/navigator.cs
  13. 130
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/app.cs
  14. 421
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/backdrop.cs
  15. 95
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/category_menu_page.cs
  16. 22
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/colors.cs
  17. 697
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/expanding_bottom_sheet.cs
  18. 54
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/home.cs
  19. 136
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/login.cs
  20. 283
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/shopping_cart.cs
  21. 15
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine_demo.cs
  22. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine_demo.cs.meta
  23. 69
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/0-0.jpg
  24. 69
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/1-0.jpg
  25. 45
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/10-0.jpg
  26. 48
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/11-0.jpg
  27. 55
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/12-0.jpg
  28. 57
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/13-0.jpg
  29. 47
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/14-0.jpg
  30. 59
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/15-0.jpg
  31. 51
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/16-0.jpg
  32. 37
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/17-0.jpg
  33. 62
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/18-0.jpg
  34. 51
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/19-0.jpg
  35. 59
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2-0.jpg
  36. 211
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/0-0.jpg
  37. 146
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/1-0.jpg
  38. 144
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/10-0.jpg
  39. 129
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/11-0.jpg
  40. 173
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/12-0.jpg
  41. 126
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/13-0.jpg
  42. 116
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/14-0.jpg
  43. 178
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/15-0.jpg
  44. 138
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/16-0.jpg
  45. 105
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/17-0.jpg
  46. 211
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/18-0.jpg
  47. 167
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/19-0.jpg
  48. 162
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/2-0.jpg
  49. 132
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/20-0.jpg
  50. 191
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/21-0.jpg
  51. 168
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/22-0.jpg
  52. 128
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/23-0.jpg
  53. 143
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/24-0.jpg
  54. 150
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/25-0.jpg
  55. 144
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/26-0.jpg
  56. 174
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/27-0.jpg
  57. 122
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/28-0.jpg
  58. 198
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/29-0.jpg
  59. 147
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/3-0.jpg
  60. 160
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/30-0.jpg
  61. 146
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/31-0.jpg
  62. 194
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/32-0.jpg
  63. 148
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/33-0.jpg
  64. 189
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/34-0.jpg
  65. 220
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/35-0.jpg
  66. 173
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/36-0.jpg
  67. 181
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/37-0.jpg
  68. 146
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/4-0.jpg
  69. 126
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/5-0.jpg
  70. 155
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/6-0.jpg
  71. 130
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/7-0.jpg
  72. 136
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/8-0.jpg
  73. 137
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/9-0.jpg
  74. 9
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/diamond.png
  75. 4
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/slanted_menu.png
  76. 52
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/20-0.jpg
  77. 51
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/21-0.jpg
  78. 56
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/22-0.jpg
  79. 51
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/23-0.jpg
  80. 62
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/24-0.jpg
  81. 61
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/25-0.jpg
  82. 54
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/26-0.jpg
  83. 60
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/27-0.jpg
  84. 45
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/28-0.jpg
  85. 75
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/29-0.jpg
  86. 49
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3-0.jpg
  87. 437
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/0-0.jpg
  88. 263
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/1-0.jpg
  89. 290
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/10-0.jpg
  90. 218
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/11-0.jpg
  91. 290
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/12-0.jpg
  92. 222
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/13-0.jpg
  93. 247
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/14-0.jpg
  94. 492
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/15-0.jpg
  95. 317
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/16-0.jpg
  96. 231
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/17-0.jpg

4
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs


decoration: new BoxDecoration(
image: new DecorationImage(
image: new FileImage(
file: "test.png"
file: "people/square/trevor.png"
)
),
shape: BoxShape.circle

decoration: new BoxDecoration(
image: new DecorationImage(
image: new FileImage(
"test.png"
"people/square/sandra.png"
)
),
shape: BoxShape.circle

2
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/model/app_state_model.cs


private Dictionary<int, int> _productsInCart = new Dictionary<int, int> { };
private Dictionary<int, int> productsInCart => new Dictionary<int, int>(this._productsInCart);
public Dictionary<int, int> productsInCart => new Dictionary<int, int>(this._productsInCart);
public int totalCartQuantity => this._productsInCart.Values.Sum();

4
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/model/product.cs


public readonly string name;
public readonly int price;
private string assetName => $"{this.id}-0.jpg";
private string assetPackage => "shrine_images";
public string assetName => $"shrine_images/{this.id}-0.jpg";
public string assetPackage => "shrine_images";
public override string ToString()

7
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/model/scoped_model.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
namespace UIWidgetsGallery.demo.shrine.model
{

Type type = typeof(_InheritedModel<T>);
Widget widget = rebuildOnChange
? context.inheritFromWidgetOfExactType(type)
: context.ancestorWidgetOfExactType(type);
? context.dependOnInheritedWidgetOfExactType<_InheritedModel<T>>()
: context.findAncestorWidgetOfExactType<_InheritedModel<T>>();
if (widget == null) {
throw new ScopedModelError();

public class ScopedModelError : UIWidgetsError
{
public ScopedModelError() : base("")
public ScopedModelError() : base("ScopedModelError")
{
}

2
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/backdrop.cs


}
}
internal class Backdrop : StatefulWidget
public class Backdrop : StatefulWidget
{
public Backdrop(
Widget frontAction = null,

9
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demos.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgetsGallery.demo;
using UIWidgetsGallery.demo.material;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.widgets;

{
List<GalleryDemo> galleryDemos = new List<GalleryDemo>
{
new GalleryDemo(
title: "Shrine",
subtitle: "Basic shopping app",
icon: GalleryIcons.shrine,
category: GalleryDemoCategory._kDemos,
routeName: ShrineDemo.routeName,
buildRoute: (BuildContext context) => new ShrineDemo()
),
new GalleryDemo(
title: "Backdrop",
subtitle: $"Select a front layer from back layer",

4
com.unity.uiwidgets/Runtime/animation/tween_sequence.cs


using Transform = Unity.UIWidgets.widgets.Transform;
namespace Unity.UIWidgets.animation {
class TweenSequence<T> : Animatable<T> {
public class TweenSequence<T> : Animatable<T> {
public TweenSequence(List<TweenSequenceItem<T>> items) {
D.assert(items != null);
D.assert(items.isNotEmpty);

public override float transform(float t) => 1 - base.transform(1 - t);
}
class TweenSequenceItem<T> {
public class TweenSequenceItem<T> {
public TweenSequenceItem(
Animatable<T> tween = null,

2
com.unity.uiwidgets/Runtime/material/button_theme.cs


hashCode = (hashCode * 397) ^ (_hoverColor != null ? _hoverColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (_highlightColor != null ? _highlightColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (_splashColor != null ? _splashColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ colorScheme.GetHashCode();
hashCode = (hashCode * 397) ^ (colorScheme != null ? colorScheme.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ _materialTapTargetSize.GetHashCode();
return hashCode;
}

2
com.unity.uiwidgets/Runtime/painting/image_provider.cs


}
Future<Codec> _loadAsync(FileImage key, DecoderCallback decode) {
byte[] bytes = File.ReadAllBytes(Path.Combine(Application.dataPath, key.file));
byte[] bytes = File.ReadAllBytes(Path.Combine(Application.streamingAssetsPath, key.file));
if (bytes.Length > 0) {
return decode(bytes);
}

4
com.unity.uiwidgets/Runtime/widgets/animated_list.cs


public readonly GlobalKey<SliverAnimatedListState> _sliverAnimatedListKey =
GlobalKey<SliverAnimatedListState>.key();
void insertItem(int index, TimeSpan? duration = null ) {
public void insertItem(int index, TimeSpan? duration = null ) {
void removeItem(int index, AnimatedListRemovedItemBuilder builder, TimeSpan? duration = null ) {
public void removeItem(int index, AnimatedListRemovedItemBuilder builder, TimeSpan? duration = null ) {
duration = duration ?? _kDuration;
_sliverAnimatedListKey.currentState.removeItem(index, builder, duration: duration);
}

2
com.unity.uiwidgets/Runtime/widgets/heroes.cs


}
}
foreach (object tag in toHeroes.Keys) {
_HeroState heroState = new _HeroState();
_HeroState heroState = null;
if (!fromHeroes.TryGetValue(tag, out heroState)) {
toHeroes[tag].ensurePlaceholderIsHidden();
}

5
com.unity.uiwidgets/Runtime/widgets/navigator.cs


public static void pop<T>(BuildContext context, T result = default(T) ) {
of(context).pop<T>(result);
}
public static void pop(BuildContext context, object result = null ) {
of(context).pop(result);
}
public static void popUntil(BuildContext context, RoutePredicate predicate) {
of(context).popUntil(predicate);

130
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/app.cs


using System;
using UIWidgetsGallery.demo.shrine;
using UIWidgetsGallery.demo.shrine.supplemental;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.shrine
{
public class appUtils
{
public static Route _getRoute(RouteSettings settings) {
if (settings.name != "/login") {
return null;
}
return new MaterialPageRoute(
settings: settings,
builder: (BuildContext context) => new LoginPage(),
fullscreenDialog: true
);
}
public static readonly ThemeData _kShrineTheme = _buildShrineTheme();
static IconThemeData _customIconTheme(IconThemeData original) {
return original.copyWith(color: shrineColorsUtils.kShrineBrown900);
}
static ThemeData _buildShrineTheme() {
ThemeData _base = ThemeData.light();
return _base.copyWith(
colorScheme: kShrineColorScheme,
accentColor: shrineColorsUtils.kShrineBrown900,
primaryColor: shrineColorsUtils.kShrinePink100,
buttonColor: shrineColorsUtils.kShrinePink100,
scaffoldBackgroundColor: shrineColorsUtils.kShrineBackgroundWhite,
cardColor: shrineColorsUtils.kShrineBackgroundWhite,
textSelectionColor: shrineColorsUtils.kShrinePink100,
errorColor: shrineColorsUtils.kShrineErrorRed,
buttonTheme: new ButtonThemeData(
colorScheme: kShrineColorScheme,
textTheme: ButtonTextTheme.normal
),
primaryIconTheme: _customIconTheme(_base.iconTheme),
inputDecorationTheme: new InputDecorationTheme(border: new CutCornersBorder()),
textTheme: _buildShrineTextTheme(_base.textTheme),
primaryTextTheme: _buildShrineTextTheme(_base.primaryTextTheme),
accentTextTheme: _buildShrineTextTheme(_base.accentTextTheme),
iconTheme: _customIconTheme(_base.iconTheme)
);
}
static TextTheme _buildShrineTextTheme(TextTheme _base) {
return _base.copyWith(
headline5: _base.headline5.copyWith(fontWeight: FontWeight.w500),
headline6: _base.headline6.copyWith(fontSize: 18.0f),
caption: _base.caption.copyWith(fontWeight: FontWeight.w400, fontSize: 14.0f),
bodyText1: _base.bodyText1.copyWith(fontWeight: FontWeight.w500, fontSize: 16.0f),
button: _base.button.copyWith(fontWeight: FontWeight.w500, fontSize: 14.0f)
).apply(
fontFamily: "Raleway",
displayColor: shrineColorsUtils.kShrineBrown900,
bodyColor: shrineColorsUtils.kShrineBrown900
);
}
static ColorScheme kShrineColorScheme = new ColorScheme(
primary: shrineColorsUtils.kShrinePink100,
primaryVariant: shrineColorsUtils.kShrineBrown900,
secondary: shrineColorsUtils.kShrinePink50,
secondaryVariant: shrineColorsUtils.kShrineBrown900,
surface: shrineColorsUtils.kShrineSurfaceWhite,
background: shrineColorsUtils.kShrineBackgroundWhite,
error: shrineColorsUtils.kShrineErrorRed,
onPrimary: shrineColorsUtils.kShrineBrown900,
onSecondary: shrineColorsUtils.kShrineBrown900,
onSurface: shrineColorsUtils.kShrineBrown900,
onBackground: shrineColorsUtils.kShrineBrown900,
onError: shrineColorsUtils.kShrineSurfaceWhite,
brightness: Brightness.light
);
}
public class ShrineApp : StatefulWidget {
public override State createState() => new _ShrineAppState();
}
public class _ShrineAppState : SingleTickerProviderStateMixin<ShrineApp> {
AnimationController _controller;
public override void initState() {
base.initState();
_controller = new AnimationController(
vsync: this,
duration: TimeSpan.FromMilliseconds(450),
value: 1.0f
);
}
public override Widget build(BuildContext context) {
return new MaterialApp(
title: "Shrine",
home: new HomePage(
backdrop: new Backdrop(
frontLayer: new ProductPage(),
backLayer: new CategoryMenuPage(onCategoryTap: () => _controller.forward()),
frontTitle: new Text("SHRINE"),
backTitle: new Text("MENU"),
controller: _controller
),
expandingBottomSheet: new ExpandingBottomSheet(hideController: _controller)
),
initialRoute: "/login",
onGenerateRoute: appUtils._getRoute,
theme: appUtils._kShrineTheme.copyWith(platform: Theme.of(context).platform)
);
}
}
}

421
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/backdrop.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.shrine
{
public class backdropUtils
{
public static readonly Cubic _kAccelerateCurve = new Cubic(0.548f, 0.0f, 0.757f, 0.464f);
public static readonly Cubic _kDecelerateCurve = new Cubic(0.23f, 0.94f, 0.41f, 1.0f);
public static readonly float _kPeakVelocityTime = 0.248210f;
public static readonly float _kPeakVelocityProgress = 0.379146f;
}
public class _TappableWhileStatusIs : StatefulWidget {
public _TappableWhileStatusIs(
AnimationStatus status,
Key key = null,
AnimationController controller = null,
Widget child = null
) : base(key: key)
{
this.status = status;
this.controller = controller;
this.child = child;
}
public readonly AnimationController controller;
public readonly AnimationStatus status;
public readonly Widget child;
public override State createState() => new _TappableWhileStatusIsState();
}
public class _TappableWhileStatusIsState : State<_TappableWhileStatusIs> {
bool _active;
public override void initState() {
base.initState();
widget.controller.addStatusListener(_handleStatusChange);
_active = widget.controller.status == widget.status;
}
public override void dispose() {
widget.controller.removeStatusListener(_handleStatusChange);
base.dispose();
}
void _handleStatusChange(AnimationStatus status) {
bool value = widget.controller.status == widget.status;
if (_active != value) {
setState(() => {
_active = value;
});
}
}
public override Widget build(BuildContext context) {
Widget child = new AbsorbPointer(
absorbing: !_active,
child: widget.child
);
if (!_active) {
child = new FocusScope(
canRequestFocus: false,
debugLabel: "_TappableWhileStatusIs",
child: child
);
}
return child;
}
}
public class _FrontLayer : StatelessWidget {
public _FrontLayer(
Key key = null,
VoidCallback onTap = null,
Widget child = null
) : base(key: key)
{
this.onTap = onTap;
this.child = child;
}
public readonly VoidCallback onTap;
public readonly Widget child;
public override Widget build(BuildContext context) {
return new Material(
elevation: 16.0f,
shape: new BeveledRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(46.0f))
),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget>{
new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => { onTap?.Invoke();},
child: new Container(
height: 40.0f,
alignment: AlignmentDirectional.centerStart
)
),
new Expanded(
child: child
),
}
)
);
}
}
public delegate void OnPress();
public class _BackdropTitle : AnimatedWidget {
public _BackdropTitle(
Key key = null,
Animation<float> listenable = null,
OnPress onPress = null,
Widget frontTitle = null,
Widget backTitle = null
) : base(key: key, listenable: listenable)
{
D.assert(frontTitle != null);
D.assert(backTitle != null);
this.backTitle = backTitle;
this.frontTitle = frontTitle;
this.onPress = onPress;
}
public readonly OnPress onPress;
public readonly Widget frontTitle;
public readonly Widget backTitle;
protected override Widget build(BuildContext context) {
Animation<float> animation = new CurvedAnimation(
parent: listenable as Animation<float>,
curve: new Interval(0.0f, 0.78f)
);
return new DefaultTextStyle(
style: Theme.of(context).primaryTextTheme.headline6,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: new Row(children: new List<Widget>{
new SizedBox(
width: 72.0f,
child: new IconButton(
padding: EdgeInsets.only(right: 8.0f),
onPressed: ()=> { onPress?.Invoke();},
icon: new Stack(children: new List<Widget>{
new Opacity(
opacity: animation.value,
child: new Container(
width: 44.0f,
height: 44.0f,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new FileImage(
file: "logo.png"
)
),
shape: BoxShape.circle
)
)
),
new FractionalTranslation(
translation: new OffsetTween(
begin: Offset.zero,
end: new Offset(1.0f, 0.0f)).evaluate(animation),
child: new Container(
width: 44.0f,
height: 44.0f,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new FileImage(
file: "logo.png"
)
),
shape: BoxShape.circle
)
)
)
})
)
),
new Stack(
children: new List<Widget>{
new Opacity(
opacity: new CurvedAnimation(
parent: new ReverseAnimation(animation),
curve: new Interval(0.5f, 1.0f)
).value,
child: new FractionalTranslation(
translation: new OffsetTween(
begin: Offset.zero,
end: new Offset(0.5f, 0.0f)).evaluate(animation),
child: backTitle
)
),
new Opacity(
opacity: new CurvedAnimation(
parent: animation,
curve: new Interval(0.5f, 1.0f)).value,
child: new FractionalTranslation(
translation: new OffsetTween(
begin: new Offset(-0.25f, 0.0f),
end: Offset.zero).evaluate(animation),
child: frontTitle
)
),
}
),
})
);
}
}
public class Backdrop : StatefulWidget {
public Backdrop(
Widget frontLayer,
Widget backLayer,
Widget frontTitle,
Widget backTitle,
AnimationController controller
) {
D.assert(frontLayer != null);
D.assert(backLayer != null);
D.assert(frontTitle != null);
D.assert(backTitle != null);
D.assert(controller != null);
this.frontLayer = frontLayer;
this.backLayer = backLayer;
this.frontTitle = frontTitle;
this.backTitle = backTitle;
this.controller = controller;
}
public readonly Widget frontLayer;
public readonly Widget backLayer;
public readonly Widget frontTitle;
public readonly Widget backTitle;
public readonly AnimationController controller;
public override State createState() => new _BackdropState();
}
public class _BackdropState : SingleTickerProviderStateMixin<Backdrop> {
public readonly GlobalKey _backdropKey = GlobalKey.key(debugLabel: "Backdrop");
AnimationController _controller;
Animation<RelativeRect> _layerAnimation;
public override void initState() {
base.initState();
_controller = widget.controller;
}
public override void dispose() {
_controller.dispose();
base.dispose();
}
bool _frontLayerVisible {
get
{
AnimationStatus status = _controller.status;
return status == AnimationStatus.completed || status == AnimationStatus.forward;
}
}
void _toggleBackdropLayerVisibility() { //[!!!]
setState(() => {
var visible = _frontLayerVisible ? _controller.reverse() : _controller.forward();
});
}
Animation<RelativeRect> _getLayerAnimation(Size layerSize, float layerTop) {
Curve firstCurve;
Curve secondCurve;
float firstWeight;
float secondWeight;
Animation<float> animation;
if (_frontLayerVisible) {
firstCurve = backdropUtils._kAccelerateCurve;
secondCurve = backdropUtils._kDecelerateCurve;
firstWeight = backdropUtils._kPeakVelocityTime;
secondWeight = 1.0f - backdropUtils._kPeakVelocityTime;
animation = new CurvedAnimation(
parent: _controller.view,
curve: new Interval(0.0f, 0.78f)
);
} else {
firstCurve = backdropUtils._kDecelerateCurve.flipped;
secondCurve = backdropUtils._kAccelerateCurve.flipped;
firstWeight = 1.0f - backdropUtils._kPeakVelocityTime;
secondWeight = backdropUtils._kPeakVelocityTime;
animation = _controller.view;
}
return new TweenSequence<RelativeRect>(
new List<TweenSequenceItem<RelativeRect>>{
new TweenSequenceItem<RelativeRect>(
tween: new RelativeRectTween(
begin: RelativeRect.fromLTRB(
0.0f,
layerTop,
0.0f,
layerTop - layerSize.height
),
end: RelativeRect.fromLTRB(
0.0f,
layerTop * backdropUtils._kPeakVelocityProgress,
0.0f,
(layerTop - layerSize.height) * backdropUtils._kPeakVelocityProgress
)
).chain(new CurveTween(curve: firstCurve)),
weight: firstWeight
),
new TweenSequenceItem<RelativeRect>(
tween: new RelativeRectTween(
begin: RelativeRect.fromLTRB(
0.0f,
layerTop * backdropUtils._kPeakVelocityProgress,
0.0f,
(layerTop - layerSize.height) * backdropUtils._kPeakVelocityProgress
),
end: RelativeRect.fill
).chain(new CurveTween(curve: secondCurve)),
weight: secondWeight
),
}
).animate(animation);
}
Widget _buildStack(BuildContext context, BoxConstraints constraints) {
float layerTitleHeight = 48.0f;
Size layerSize = constraints.biggest;
float layerTop = layerSize.height - layerTitleHeight;
_layerAnimation = _getLayerAnimation(layerSize, layerTop);
return new Stack(
key: _backdropKey,
children: new List<Widget>{
new _TappableWhileStatusIs(
AnimationStatus.dismissed,
controller: _controller,
child: widget.backLayer
),
new PositionedTransition(
rect: _layerAnimation,
child: new _FrontLayer(
onTap: _toggleBackdropLayerVisibility,
child: new _TappableWhileStatusIs(
AnimationStatus.completed,
controller: _controller,
child: widget.frontLayer
)
)
),
}
);
}
public override Widget build(BuildContext context) {
AppBar appBar = new AppBar(
brightness: Brightness.light,
elevation: 0.0f,
titleSpacing: 0.0f,
title: new _BackdropTitle(
listenable: _controller.view,
onPress: _toggleBackdropLayerVisibility,
frontTitle: widget.frontTitle,
backTitle: widget.backTitle
),
actions: new List<Widget>{
new IconButton(
icon: new Icon(Icons.search),
onPressed: () => {
Navigator.push<object>(
context,
new MaterialPageRoute(builder: (BuildContext context2) => new LoginPage())
);
}
),
new IconButton(
icon: new Icon(Icons.tune),
onPressed: () => {
Navigator.push<object>(
context,
new MaterialPageRoute(builder: (BuildContext context2) => new LoginPage())
);
}
),
}
);
return new Scaffold(
appBar: appBar,
body: new LayoutBuilder(
builder: _buildStack
)
);
}
}
}

95
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/category_menu_page.cs


using System;
using System.Collections.Generic;
using UIWidgetsGallery.demo.shrine.model;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.shrine
{
public class CategoryMenuPage : StatelessWidget {
public CategoryMenuPage(
Key key = null,
VoidCallback onCategoryTap = null
) : base(key: key)
{
this.onCategoryTap = onCategoryTap;
}
public readonly VoidCallback onCategoryTap;
Widget _buildCategory(Category category, BuildContext context)
{
string categoryString = category.ToString().Replace("Category", "").ToUpper();
ThemeData theme = Theme.of(context);
return new ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context2, Widget child, AppStateModel model) =>
new GestureDetector(
onTap: () =>
{
model.setCategory(category);
if (onCategoryTap != null)
{
onCategoryTap();
}
},
child: model.selectedCategory == category
? new Container(
child:new Column(
children: new List<Widget>
{
new SizedBox(height: 16.0f),
new Text(
categoryString,
style: theme.textTheme.bodyText1,
textAlign: TextAlign.center
),
new SizedBox(height: 14.0f),
new Container(
width: 70.0f,
height: 2.0f,
color: shrineColorsUtils.kShrinePink400
),
}
)
)
: new Container(
child: new Padding(
padding: EdgeInsets.symmetric(vertical: 16.0f),
child: new Text(
categoryString,
style: theme.textTheme.bodyText1.copyWith(
color: shrineColorsUtils.kShrineBrown900.withAlpha(153)
),
textAlign: TextAlign.center
)
)
)
)
);
}
public override Widget build(BuildContext context) {
var count = Enum.GetNames(typeof(Category)).Length;
List<Widget> widgets = new List<Widget>();
for (int i = 0;i<count;i++)
{
widgets.Add( _buildCategory((Category)i, context));
}
return new Center(
child: new Container(
padding: EdgeInsets.only(top: 40.0f),
color: shrineColorsUtils.kShrinePink100,
child: new ListView(
children: widgets
)
)
);
}
}
}

22
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/colors.cs


using uiwidgets;
using Unity.UIWidgets.ui;
namespace UIWidgetsGallery.demo.shrine
{
public class shrineColorsUtils
{
public static readonly Color kShrinePink50 = new Color(0xFFFEEAE6);
public static readonly Color kShrinePink100 = new Color(0xFFFEDBD0);
public static readonly Color kShrinePink300 = new Color(0xFFFBB8AC);
public static readonly Color kShrinePink400 = new Color(0xFFEAA4A4);
public static readonly Color kShrineBrown900 = new Color(0xFF442B2D);
public static readonly Color kShrineBrown600 = new Color(0xFF7D4F52);
public static readonly Color kShrineErrorRed = new Color(0xFFC5032B);
public static readonly Color kShrineSurfaceWhite = new Color(0xFFFFFBFA);
public static readonly Color kShrineBackgroundWhite = Colors.white;
}
}

697
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/expanding_bottom_sheet.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using UIWidgetsGallery.demo.shrine.model;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.async2;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.shrine
{
public class expanding_buttom_sheetUtils
{
public static readonly Cubic _kAccelerateCurve = new Cubic(0.548f, 0.0f, 0.757f, 0.464f);
public static readonly Cubic _kDecelerateCurve = new Cubic(0.23f, 0.94f, 0.41f, 1.0f);
public static readonly float _kPeakVelocityTime = 0.248210f;
public static readonly float _kPeakVelocityProgress = 0.379146f;
public static readonly float _kCartHeight = 56.0f;
public static readonly float _kCornerRadius = 24.0f;
public static readonly float _kWidthForCartIcon = 64.0f;
public static Animation<float> _getFloatEmphasizedEasingAnimation(
float begin,
float peak,
float end,
bool isForward,
Animation<float> parent
) {
Curve firstCurve;
Curve secondCurve;
float firstWeight;
float secondWeight;
if (isForward) {
firstCurve = _kAccelerateCurve;
secondCurve = _kDecelerateCurve;
firstWeight = _kPeakVelocityTime;
secondWeight = 1.0f - _kPeakVelocityTime;
} else {
firstCurve = _kDecelerateCurve.flipped;
secondCurve = _kAccelerateCurve.flipped;
firstWeight = 1.0f - _kPeakVelocityTime;
secondWeight = _kPeakVelocityTime;
}
return new TweenSequence<float>(
new List<TweenSequenceItem<float>>{
new TweenSequenceItem<float>(
weight: firstWeight,
tween: new FloatTween(
begin: begin,
end: peak
).chain(new CurveTween(curve: firstCurve))
),
new TweenSequenceItem<float>(
weight: secondWeight,
tween: new FloatTween(
begin: peak,
end: end
).chain(new CurveTween(curve: secondCurve))
),
}
).animate(parent);
}
public static Animation<Offset> _getOffsetEmphasizedEasingAnimation(
Offset begin,
Offset peak,
Offset end,
bool isForward,
Animation<float> parent
) {
Curve firstCurve;
Curve secondCurve;
float firstWeight;
float secondWeight;
if (isForward) {
firstCurve = _kAccelerateCurve;
secondCurve = _kDecelerateCurve;
firstWeight = _kPeakVelocityTime;
secondWeight = 1.0f - _kPeakVelocityTime;
} else {
firstCurve = _kDecelerateCurve.flipped;
secondCurve = _kAccelerateCurve.flipped;
firstWeight = 1.0f - _kPeakVelocityTime;
secondWeight = _kPeakVelocityTime;
}
return new TweenSequence<Offset>(
new List<TweenSequenceItem<Offset>>{
new TweenSequenceItem<Offset>(
weight: firstWeight,
tween: new OffsetTween(
begin: begin,
end: peak
).chain(new CurveTween(curve: firstCurve))
),
new TweenSequenceItem<Offset>(
weight: secondWeight,
tween: new OffsetTween(
begin: peak,
end: end
).chain(new CurveTween(curve: secondCurve))
),
}
).animate(parent);
}
public static float _getPeakPoint(float begin, float end) {
return begin + (end - begin) * _kPeakVelocityProgress;
}
}
public class ExpandingBottomSheet : StatefulWidget {
public ExpandingBottomSheet(Key key = null, AnimationController hideController = null)
: base(key: key)
{
D.assert(hideController != null);
this.hideController = hideController;
}
public readonly AnimationController hideController;
public override State createState() => new _ExpandingBottomSheetState();
public static _ExpandingBottomSheetState of(BuildContext context, bool isNullOk = false) {
D.assert(context != null);
_ExpandingBottomSheetState result = context.findAncestorStateOfType<_ExpandingBottomSheetState>();
if (isNullOk || result != null) {
return result;
}
throw new UIWidgetsError(
"ExpandingBottomSheet.of() called with a context that does not contain a ExpandingBottomSheet.\n");
}
}
public class _ExpandingBottomSheetState : TickerProviderStateMixin<ExpandingBottomSheet> {
public readonly GlobalKey _expandingBottomSheetKey = GlobalKey.key(debugLabel: "Expanding bottom sheet");
float _width = expanding_buttom_sheetUtils._kWidthForCartIcon;
AnimationController _controller;
Animation<float> _widthAnimation;
Animation<float> _heightAnimation;
Animation<float> _thumbnailOpacityAnimation;
Animation<float> _cartOpacityAnimation;
Animation<float> _shapeAnimation;
Animation<Offset> _slideAnimation;
public override void initState() {
base.initState();
_controller = new AnimationController(
duration: TimeSpan.FromMilliseconds(500),
vsync: this
);
}
public override void dispose() {
_controller.dispose();
base.dispose();
}
Animation<float> _getWidthAnimation(float screenWidth) {
if (_controller.status == AnimationStatus.forward) {
return new FloatTween(begin: _width, end: screenWidth).animate(
new CurvedAnimation(
parent: _controller.view,
curve: new Interval(0.0f, 0.3f, curve: Curves.fastOutSlowIn)
)
);
} else {
return expanding_buttom_sheetUtils._getFloatEmphasizedEasingAnimation(
begin: _width,
peak: expanding_buttom_sheetUtils._getPeakPoint(begin: _width, end: screenWidth),
end: screenWidth,
isForward: false,
parent: new CurvedAnimation(parent: _controller.view, curve: new Interval(0.0f, 0.87f))
);
}
}
Animation<float> _getHeightAnimation(float screenHeight) {
if (_controller.status == AnimationStatus.forward) {
return expanding_buttom_sheetUtils._getFloatEmphasizedEasingAnimation(
begin: expanding_buttom_sheetUtils._kCartHeight,
peak: expanding_buttom_sheetUtils._kCartHeight + (screenHeight - expanding_buttom_sheetUtils._kCartHeight) * expanding_buttom_sheetUtils._kPeakVelocityProgress,
end: screenHeight,
isForward: true,
parent: _controller.view
);
} else {
return new FloatTween(
begin: expanding_buttom_sheetUtils._kCartHeight,
end: screenHeight
).animate(
new CurvedAnimation(
parent: _controller.view,
curve: new Interval(0.434f, 1.0f, curve: Curves.linear),
reverseCurve: new Interval(0.434f, 1.0f, curve: Curves.fastOutSlowIn.flipped)
)
);
}
}
// Animation of the cut corner. It's cut when closed and not cut when open.
Animation<float> _getShapeAnimation() {
if (_controller.status == AnimationStatus.forward) {
return new FloatTween(begin: expanding_buttom_sheetUtils._kCornerRadius, end: 0.0f).animate(
new CurvedAnimation(
parent: _controller.view,
curve: new Interval(0.0f, 0.3f, curve: Curves.fastOutSlowIn)
)
);
} else {
return expanding_buttom_sheetUtils._getFloatEmphasizedEasingAnimation(
begin: expanding_buttom_sheetUtils._kCornerRadius,
peak: expanding_buttom_sheetUtils._getPeakPoint(begin: expanding_buttom_sheetUtils._kCornerRadius, end: 0.0f),
end: 0.0f,
isForward: false,
parent: _controller.view
);
}
}
Animation<float> _getThumbnailOpacityAnimation() {
return new FloatTween(begin: 1.0f, end: 0.0f).animate(
new CurvedAnimation(
parent: _controller.view,
curve: _controller.status == AnimationStatus.forward
? new Interval(0.0f, 0.3f)
: new Interval(0.532f, 0.766f)
)
);
}
Animation<float> _getCartOpacityAnimation() {
return new CurvedAnimation(
parent: _controller.view,
curve: _controller.status == AnimationStatus.forward
? new Interval(0.3f, 0.6f)
: new Interval(0.766f, 1.0f)
);
}
// Returns the correct width of the ExpandingBottomSheet based on the number of
// products in the cart.
float _widthFor(int numProducts) {
switch (numProducts) {
case 0:
return expanding_buttom_sheetUtils._kWidthForCartIcon;
case 1:
return 136.0f;
case 2:
return 192.0f;
case 3:
return 248.0f;
default:
return 278.0f;
}
}
// Returns true if the cart is open or opening and false otherwise.
bool _isOpen {
get
{
AnimationStatus status = _controller.status;
return status == AnimationStatus.completed || status == AnimationStatus.forward;
}
}
// Opens the ExpandingBottomSheet if it's closed, otherwise does nothing.
void open() {
if (!_isOpen) {
_controller.forward();
}
}
// Closes the ExpandingBottomSheet if it's open or opening, otherwise does nothing.
public void close() {
if (_isOpen) {
_controller.reverse();
}
}
// Changes the padding between the start edge of the Material and the cart icon
// based on the number of products in the cart (padding increases when > 0
// products.)
EdgeInsetsDirectional _cartPaddingFor(int numProducts) {
return (numProducts == 0)
? EdgeInsetsDirectional.only(start: 20.0f, end: 8.0f)
: EdgeInsetsDirectional.only(start: 32.0f, end: 8.0f);
}
bool _cartIsVisible
{
get
{
return _thumbnailOpacityAnimation.value == 0.0;
}
}
Widget _buildThumbnails(int numProducts) {
return new Container(
child: new Opacity(
opacity: _thumbnailOpacityAnimation.value,
child: new Column(
children: new List<Widget>{
new Row(
children: new List<Widget>{
new AnimatedPadding(
padding: _cartPaddingFor(numProducts),
child: new Icon(Icons.shopping_cart),
duration: TimeSpan.FromMilliseconds(225)
),
new Container(
// Accounts for the overflow number
width: numProducts > 3 ? _width - 94.0f: _width - 64.0f,
height: expanding_buttom_sheetUtils._kCartHeight,
padding: EdgeInsets.symmetric(vertical: 8.0f),
child: new ProductThumbnailRow()
),
new ExtraProductsNumber(),
}
),
}
)
)
);
}
Widget _buildShoppingCartPage() {
return new Opacity(
opacity: _cartOpacityAnimation.value,
child: new ShoppingCartPage()
);
}
Widget _buildCart(BuildContext context, Widget child) {
AppStateModel model = ScopedModel<AppStateModel>.of(context);
int numProducts = model.productsInCart.Keys.Count;
int totalCartQuantity = model.totalCartQuantity;
Size screenSize = MediaQuery.of(context).size;
float screenWidth = screenSize.width;
float screenHeight = screenSize.height;
_width = _widthFor(numProducts);
_widthAnimation = _getWidthAnimation(screenWidth);
_heightAnimation = _getHeightAnimation(screenHeight);
_shapeAnimation = _getShapeAnimation();
_thumbnailOpacityAnimation = _getThumbnailOpacityAnimation();
_cartOpacityAnimation = _getCartOpacityAnimation();
return new Container(
width: _widthAnimation.value,
height: _heightAnimation.value,
child: new Material(
animationDuration: TimeSpan.FromMilliseconds(0),
shape: new BeveledRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(_shapeAnimation.value)
)
),
elevation: 4.0f,
color: shrineColorsUtils.kShrinePink50,
child: _cartIsVisible
? _buildShoppingCartPage()
: _buildThumbnails(numProducts)
)
);
}
// Builder for the hide and reveal animation when the backdrop opens and closes
Widget _buildSlideAnimation(BuildContext context, Widget child) {
_slideAnimation = expanding_buttom_sheetUtils._getOffsetEmphasizedEasingAnimation(
begin: new Offset(1.0f, 0.0f),
peak: new Offset(expanding_buttom_sheetUtils._kPeakVelocityProgress, 0.0f),
end: new Offset(0.0f, 0.0f),
isForward: widget.hideController.status == AnimationStatus.forward,
parent: widget.hideController
);
return new SlideTransition(
position: _slideAnimation,
child: child
);
}
// Closes the cart if the cart is open, otherwise exits the app (this should
// only be relevant for Android).
Future<bool> _onWillPop() {
if (!_isOpen) {
//SystemNavigator.pop();
return Future.value(true).to<bool>();
}
close();
return Future.value(true).to<bool>();
}
public override Widget build(BuildContext context) {
return new AnimatedSize(
key: _expandingBottomSheetKey,
duration: TimeSpan.FromMilliseconds(225),
curve: Curves.easeInOut,
vsync: this,
alignment: FractionalOffset.topLeft,
child: new WillPopScope(
onWillPop: _onWillPop,
child: new AnimatedBuilder(
animation: widget.hideController,
builder: _buildSlideAnimation,
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: open,
child: new ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context2, Widget child, AppStateModel model)=> {
return new AnimatedBuilder(
builder: _buildCart,
animation: _controller
);
}
)
)
)
)
);
}
}
public class ProductThumbnailRow : StatefulWidget {
public override State createState() => new _ProductThumbnailRowState();
}
public class _ProductThumbnailRowState : State<ProductThumbnailRow> {
public readonly GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>.key();
_ListModel _list;
List<int> _internalList;
public override void initState() {
base.initState();
_list = new _ListModel(
listKey: _listKey,
initialItems: ScopedModel<AppStateModel>.of(context).productsInCart.Keys.ToList(),
removedItemBuilder: _buildRemovedThumbnail
);
_internalList = new List<int>(_list.list);
}
Product _productWithId(int productId) {
AppStateModel model = ScopedModel<AppStateModel>.of(context);
Product product = model.getProductById(productId);
D.assert(product != null);
return product;
}
Widget _buildRemovedThumbnail(int item, BuildContext context, Animation<float> animation) {
return new ProductThumbnail(animation, animation, _productWithId(item));
}
Widget _buildThumbnail(BuildContext context, int index, Animation<float> animation) {
Animation<float> thumbnailSize = new FloatTween(begin: 0.8f, end: 1.0f).animate(
new CurvedAnimation(
curve: new Interval(0.33f, 1.0f, curve: Curves.easeIn),
parent: animation
)
);
Animation<float> opacity = new CurvedAnimation(
curve: new Interval(0.33f, 1.0f, curve: Curves.linear),
parent: animation
);
return new ProductThumbnail(thumbnailSize, opacity, _productWithId(_list.ElementAt(index)));
}
void _updateLists() {
_internalList = ScopedModel<AppStateModel>.of(context).productsInCart.Keys.ToList();
HashSet<int> internalSet = new HashSet<int>(_internalList);
HashSet<int> listSet = new HashSet<int>(_list.list);
HashSet<int> difference = new HashSet<int>();
foreach (var _set in internalSet)
{
if (!listSet.Contains(_set))
{
difference.Add(_set);
}
}
if (difference.isEmpty()) {
return;
}
foreach (int product in difference) {
if (_internalList.Count < _list.length) {
_list.remove(product);
} else if (_internalList.Count > _list.length) {
_list.add(product);
}
}
while (_internalList.Count != _list.length) {
int index = 0;
// Check bounds and that the list elements are the same
while (_internalList.isNotEmpty() &&
_list.length > 0 &&
index < _internalList.Count &&
index < _list.length &&
_internalList[index] == _list.ElementAt(index)) {
index++;
}
}
}
Widget _buildAnimatedList() {
return new AnimatedList(
key: _listKey,
shrinkWrap: true,
itemBuilder: _buildThumbnail,
initialItemCount: _list.length,
scrollDirection: Axis.horizontal,
physics: new NeverScrollableScrollPhysics() // Cart shouldn't scroll
);
}
public override Widget build(BuildContext context) {
_updateLists();
return new ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context2, Widget child, AppStateModel model) => _buildAnimatedList()
);
}
}
public class ExtraProductsNumber : StatelessWidget {
int _calculateOverflow(AppStateModel model) {
Dictionary<int, int> productMap = model.productsInCart;
List<int> products = productMap.Keys.ToList();
int overflow = 0;
int numProducts = products.Count;
if (numProducts > 3) {
for (int i = 3; i < numProducts; i++) {
overflow += productMap[products[i]];
}
}
return overflow;
}
Widget _buildOverflow(AppStateModel model, BuildContext context) {
if (model.productsInCart.Count <= 3)
return new Container();
int numOverflowProducts = _calculateOverflow(model);
int displayedOverflowProducts = numOverflowProducts <= 99 ? numOverflowProducts : 99;
return new Container(
child: new Text(
$"+{displayedOverflowProducts}",
style: Theme.of(context).primaryTextTheme.button
)
);
}
public override Widget build(BuildContext context) {
return new ScopedModelDescendant<AppStateModel>(
builder: (BuildContext builder, Widget child, AppStateModel model) => _buildOverflow(model, context)
);
}
}
public class ProductThumbnail : StatelessWidget {
public ProductThumbnail(Animation<float> animation, Animation<float> opacityAnimation, Product product)
{
this.animation = animation;
this.opacityAnimation = opacityAnimation;
this.product = product;
}
public readonly Animation<float> animation;
public readonly Animation<float> opacityAnimation;
public readonly Product product;
public override Widget build(BuildContext context) {
return new FadeTransition(
opacity: opacityAnimation,
child: new ScaleTransition(
scale: animation,
child: new Container(
width: 40.0f,
height: 40.0f,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new FileImage(
product.assetName
),
fit: BoxFit.cover
),
borderRadius: BorderRadius.all(Radius.circular(10.0f))
),
margin: EdgeInsets.only(left: 16.0f)
)
)
);
}
}
public delegate Widget RemovedItemBuilder(int item, BuildContext context, Animation<float> animation) ;
public class _ListModel {
public _ListModel(
GlobalKey<AnimatedListState> listKey,
RemovedItemBuilder removedItemBuilder,
IEnumerable<int> initialItems = null
)
{
D.assert(listKey != null);
D.assert(removedItemBuilder != null);
_items = initialItems?.ToList() ?? new List<int>();
this.listKey = listKey;
this.removedItemBuilder = removedItemBuilder;
}
public readonly GlobalKey<AnimatedListState> listKey;
//public readonly Delegate removedItemBuilder;
public RemovedItemBuilder removedItemBuilder;
public readonly List<int> _items;
AnimatedListState _animatedList
{
get
{
return listKey.currentState;
}
}
public void add(int product) {
_insert(_items.Count, product);
}
public void _insert(int index, int item) {
_items.Insert(index, item);
_animatedList.insertItem(index, duration: TimeSpan.FromMilliseconds(225));
}
public void remove(int product) {
int index = _items.IndexOf(product);
if (index >= 0) {
_removeAt(index);
}
}
public void _removeAt(int index)
{
int removedItem = _items.ElementAt(index);
_items.RemoveAt(index);
_animatedList.removeItem(index, (BuildContext context, Animation<float> animation) =>{
return removedItemBuilder(removedItem, context, animation);
});
}
public int length
{
get
{
return _items.Count;
}
}
public int ElementAt(int index) => _items[index];
int indexOf(int item) => _items.IndexOf(item);
public List<int> list
{
get
{
return _items;
}
}
}
}

54
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/home.cs


using System.Collections.Generic;
using UIWidgetsGallery.demo.shrine.model;
using UIWidgetsGallery.demo.shrine.supplemental;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.shrine
{
public class ProductPage : StatelessWidget {
public ProductPage(Category category = Category.all)
{
this.category = category;
}
public readonly Category category;
public override Widget build(BuildContext context) {
return new ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context1, Widget child, AppStateModel model) => {
return new AsymmetricView(products: model.getProducts());
});
}
}
public class HomePage : StatelessWidget {
public HomePage(
ExpandingBottomSheet expandingBottomSheet = null,
Backdrop backdrop = null,
Key key = null
) : base(key: key)
{
this.expandingBottomSheet = expandingBottomSheet;
this.backdrop = backdrop;
}
public readonly ExpandingBottomSheet expandingBottomSheet;
public readonly Backdrop backdrop;
public override Widget build(BuildContext context) {
return new Stack(
children: new List<Widget>
{
backdrop,
new Align(child: expandingBottomSheet, alignment: Alignment.bottomRight),
}
);
}
}
}

136
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/login.cs


using System.Collections.Generic;
using uiwidgets;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using Image = Unity.UIWidgets.widgets.Image;
namespace UIWidgetsGallery.demo.shrine
{
public class LoginPage : StatefulWidget {
public override State createState() => new _LoginPageState();
}
public class _LoginPageState : State<LoginPage> {
public readonly TextEditingController _usernameController = new TextEditingController();
public readonly TextEditingController _passwordController = new TextEditingController();
static ShapeDecoration _decoration = new ShapeDecoration(
shape: new BeveledRectangleBorder(
side: new BorderSide(color: shrineColorsUtils.kShrineBrown900, width: 0.5f),
borderRadius: BorderRadius.all(Radius.circular(7.0f))
)
);
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
elevation: 0.0f,
backgroundColor: Colors.white,
brightness: Brightness.light,
leading: new IconButton(
icon: new BackButtonIcon(),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
onPressed: () => {
Navigator.of(context, rootNavigator: true).pop<object>();
}
)
),
body: new SafeArea(
child: new ListView(
padding: EdgeInsets.symmetric(horizontal: 24.0f),
children: new List<Widget>{
new SizedBox(height: 80.0f),
new Column(
children: new List<Widget>
{
Image.file("shrine_images/diamond.png"),
new SizedBox(height: 16.0f),
new Text(
"SHRINE",
style: Theme.of(context).textTheme.headline5
),
}
),
new SizedBox(height: 120.0f),
new PrimaryColorOverride(
color: shrineColorsUtils.kShrineBrown900,
child: new Container(
decoration: _decoration,
child: new TextField(
controller: _usernameController,
decoration: new InputDecoration(
labelText: "Username"
)
)
)
),
new SizedBox(height: 12.0f),
new PrimaryColorOverride(
color: shrineColorsUtils.kShrineBrown900,
child: new Container(
decoration: _decoration,
child: new TextField(
controller: _passwordController,
decoration: new InputDecoration(
labelText: "Password"
)
)
)
),
new Wrap(
children: new List<Widget>{
new ButtonBar(
children:new List<Widget>{
new FlatButton(
child: new Text("CANCEL"),
shape: new BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0f))
),
onPressed: () => {
Navigator.of(context, rootNavigator: true).pop<object>();
}
),
new RaisedButton(
child: new Text("NEXT"),
elevation: 8.0f,
shape: new BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0f))
),
onPressed: () => {
Navigator.pop(context);
}
)
}
),
}
),
}
)
)
);
}
}
public class PrimaryColorOverride : StatelessWidget {
public PrimaryColorOverride(Key key = null, Color color = null, Widget child = null) : base(key: key)
{
this.child = child;
this.color = color;
}
public readonly Color color;
public readonly Widget child;
public override Widget build(BuildContext context) {
return new Theme(
child: child,
data: Theme.of(context).copyWith(primaryColor: color)
);
}
}
}

283
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine/shopping_cart.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgetsGallery.demo.shrine.model;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using Image = Unity.UIWidgets.widgets.Image;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsGallery.demo.shrine
{
public class shopping_cartUtils
{
public static readonly float _leftColumnWidth = 60.0f;
}
public class ShoppingCartPage : StatefulWidget {
public override State createState() => new _ShoppingCartPageState();
}
public class _ShoppingCartPageState : State<ShoppingCartPage> {
List<Widget> _createShoppingCartRows(AppStateModel model)
{
List<Widget> widgets = null;
for (int id = 0; id < model.productsInCart.Count; id++)
{
widgets.Add(new ShoppingCartRow(
product: model.getProductById(id),
quantity: model.productsInCart[id],
onPressed: ()=> {
model.removeItemFromCart(id);
}
));
}
return widgets;
}
public override Widget build(BuildContext context) {
ThemeData localTheme = Theme.of(context);
return new Scaffold(
backgroundColor: shrineColorsUtils.kShrinePink50,
body: new SafeArea(
child: new Container(
child: new ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context2, Widget child, AppStateModel model) => {
return new Stack(
children: new List<Widget>{
new ListView(
children: new List<Widget>{
new Row(
children: new List<Widget>{
new SizedBox(
width: shopping_cartUtils._leftColumnWidth,
child: new IconButton(
icon: new Icon(Icons.keyboard_arrow_down),
onPressed: () => ExpandingBottomSheet.of(context).close()
)
),
new Text(
"CART",
style: localTheme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.w600)
),
new SizedBox(width: 16.0f),
new Text($"{model.totalCartQuantity} ITEMS")
}
),
new SizedBox(height: 16.0f),
new Column(
children: _createShoppingCartRows(model)
),
new ShoppingCartSummary(model: model),
new SizedBox(height: 100.0f)
}
),
new Positioned(
bottom: 16.0f,
left: 16.0f,
right: 16.0f,
child: new RaisedButton(
shape: new BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0f))
),
color: shrineColorsUtils.kShrinePink100,
splashColor: shrineColorsUtils.kShrineBrown600,
child: new Padding(
padding: EdgeInsets.symmetric(vertical: 12.0f),
child: new Text("CLEAR CART")
),
onPressed: () => {
model.clearCart();
ExpandingBottomSheet.of(context).close();
}
)
)
}
);
}
)
)
)
);
}
}
public class ShoppingCartSummary : StatelessWidget {
public ShoppingCartSummary(AppStateModel model)
{
this.model = model;
}
public readonly AppStateModel model;
public override Widget build(BuildContext context) {
TextStyle smallAmountStyle = Theme.of(context).textTheme.bodyText2.copyWith(color: shrineColorsUtils.kShrineBrown600);
TextStyle largeAmountStyle = Theme.of(context).textTheme.headline4;
return new Row(
children: new List<Widget>
{
new SizedBox(width: shopping_cartUtils._leftColumnWidth),
new Expanded(
child: new Padding(
padding: EdgeInsets.only(right: 16.0f),
child: new Column(
children: new List<Widget>
{
new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: new List<Widget>
{
new Expanded(
child: new Text("TOTAL")
),
new Text(
$"${model.totalCost:F}",
style: largeAmountStyle
)
}
),
new SizedBox(height: 16.0f),
new Row(
children: new List<Widget>
{
new Expanded(
child: new Text("Subtotal:")
),
new Text(
$" $ {model.subtotalCost:F}",
style: smallAmountStyle
)
}
),
new SizedBox(height: 4.0f),
new Row(
children: new List<Widget>
{
new Expanded(
child: new Text("Shipping:")
),
new Text(
$" $ {model.shippingCost:F}",
style: smallAmountStyle
)
}
),
new SizedBox(height: 4.0f),
new Row(
children: new List<Widget>
{
new Expanded(
child: new Text("Tax:")
),
new Text(
$"${model.tax:F}",
style: smallAmountStyle
)
}
)
}
)
)
)
}
);
}
}
public class ShoppingCartRow : StatelessWidget {
public ShoppingCartRow(
Product product = null,
int? quantity = null,
VoidCallback onPressed = null
)
{
this.product = product;
this.quantity = quantity?? 0;
this.onPressed = onPressed;
}
public readonly Product product;
public readonly int quantity;
public readonly VoidCallback onPressed;
public override Widget build(BuildContext context) {
ThemeData localTheme = Theme.of(context);
return new Padding(
padding: EdgeInsets.only(bottom: 16.0f),
child: new Row(
key: new ValueKey<int>(product.id),
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget>{
new SizedBox(
width: shopping_cartUtils._leftColumnWidth,
child: new IconButton(
icon: new Icon(Icons.remove_circle_outline),
onPressed: onPressed
)
),
new Expanded(
child: new Padding(
padding: EdgeInsets.only(right: 16.0f),
child: new Column(
children: new List<Widget>{
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget>{
Image.asset(
product.assetName,
package: product.assetPackage,
fit: BoxFit.cover,
width: 75.0f,
height: 75.0f
),
new SizedBox(width: 16.0f),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget>{
new Row(
children: new List<Widget>{
new Expanded(
child: new Text($"Quantity: {quantity}")
),
new Text($"x $ {product.price : D} ")
}
),
new Text(
product.name,
style: localTheme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.w600)
)
}
)
)
}
),
new SizedBox(height: 16.0f),
new Divider(
color: shrineColorsUtils.kShrineBrown900,
height: 10.0f
)
}
)
)
)
}
)
);
}
}
}

15
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine_demo.cs


using System;
using UIWidgetsGallery.demo.shrine;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo
{
class ShrineDemo : StatelessWidget {
public ShrineDemo(Key key = null) : base(key: key){}
public static readonly string routeName = "/shrine"; // Used by the Gallery app.
public override Widget build(BuildContext context) => new ShrineApp();
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/shrine_demo.cs.meta


fileFormatVersion: 2
guid: b5da65292c17429ba697ebdefb05c8e4
timeCreated: 1612512022

69
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/0-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 18 KiB

69
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/1-0.jpg

之前 之后
宽度: 329  |  高度: 247  |  大小: 13 KiB

45
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/10-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 14 KiB

48
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/11-0.jpg

之前 之后
宽度: 329  |  高度: 247  |  大小: 12 KiB

55
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/12-0.jpg

之前 之后
宽度: 329  |  高度: 213  |  大小: 14 KiB

57
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/13-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 12 KiB

47
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/14-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 13 KiB

59
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/15-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 18 KiB

51
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/16-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 17 KiB

37
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/17-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 11 KiB

62
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/18-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 20 KiB

51
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/19-0.jpg

之前 之后
宽度: 329  |  高度: 219  |  大小: 15 KiB

59
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2-0.jpg

之前 之后
宽度: 329  |  高度: 228  |  大小: 16 KiB

211
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/0-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 60 KiB

146
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/1-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 24 KiB

144
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/10-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 35 KiB

129
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/11-0.jpg

之前 之后
宽度: 659  |  高度: 496  |  大小: 24 KiB

173
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/12-0.jpg

之前 之后
宽度: 659  |  高度: 427  |  大小: 38 KiB

126
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/13-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 24 KiB

116
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/14-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 32 KiB

178
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/15-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 50 KiB

138
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/16-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 40 KiB

105
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/17-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 22 KiB

211
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/18-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 56 KiB

167
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/19-0.jpg

之前 之后
宽度: 659  |  高度: 440  |  大小: 41 KiB

162
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/2-0.jpg

之前 之后
宽度: 659  |  高度: 457  |  大小: 40 KiB

132
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/20-0.jpg

之前 之后
宽度: 659  |  高度: 443  |  大小: 29 KiB

191
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/21-0.jpg

之前 之后
宽度: 441  |  高度: 659  |  大小: 51 KiB

168
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/22-0.jpg

之前 之后
宽度: 439  |  高度: 659  |  大小: 44 KiB

128
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/23-0.jpg

之前 之后
宽度: 659  |  高度: 443  |  大小: 33 KiB

143
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/24-0.jpg

之前 之后
宽度: 442  |  高度: 659  |  大小: 35 KiB

150
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/25-0.jpg

之前 之后
宽度: 659  |  高度: 439  |  大小: 32 KiB

144
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/26-0.jpg

之前 之后
宽度: 442  |  高度: 659  |  大小: 37 KiB

174
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/27-0.jpg

之前 之后
宽度: 439  |  高度: 659  |  大小: 42 KiB

122
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/28-0.jpg

之前 之后
宽度: 659  |  高度: 439  |  大小: 29 KiB

198
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/29-0.jpg

之前 之后
宽度: 439  |  高度: 659  |  大小: 62 KiB

147
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/3-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 28 KiB

160
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/30-0.jpg

之前 之后
宽度: 442  |  高度: 659  |  大小: 43 KiB

146
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/31-0.jpg

之前 之后
宽度: 659  |  高度: 448  |  大小: 37 KiB

194
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/32-0.jpg

之前 之后
宽度: 443  |  高度: 659  |  大小: 50 KiB

148
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/33-0.jpg

之前 之后
宽度: 659  |  高度: 439  |  大小: 32 KiB

189
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/34-0.jpg

之前 之后
宽度: 441  |  高度: 659  |  大小: 50 KiB

220
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/35-0.jpg

之前 之后
宽度: 446  |  高度: 659  |  大小: 54 KiB

173
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/36-0.jpg

之前 之后
宽度: 440  |  高度: 659  |  大小: 40 KiB

181
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/37-0.jpg

之前 之后
宽度: 439  |  高度: 659  |  大小: 49 KiB

146
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/4-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 42 KiB

126
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/5-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 33 KiB

155
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/6-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 40 KiB

130
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/7-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 30 KiB

136
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/8-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 38 KiB

137
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/9-0.jpg

之前 之后
宽度: 659  |  高度: 494  |  大小: 39 KiB

9
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/diamond.png

之前 之后
宽度: 68  |  高度: 68  |  大小: 2.9 KiB

4
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/2.0x/slanted_menu.png

之前 之后
宽度: 36  |  高度: 24  |  大小: 239 B

52
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/20-0.jpg

之前 之后
宽度: 329  |  高度: 221  |  大小: 13 KiB

51
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/21-0.jpg

之前 之后
宽度: 220  |  高度: 329  |  大小: 18 KiB

56
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/22-0.jpg

之前 之后
宽度: 219  |  高度: 329  |  大小: 16 KiB

51
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/23-0.jpg

之前 之后
宽度: 329  |  高度: 221  |  大小: 14 KiB

62
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/24-0.jpg

之前 之后
宽度: 220  |  高度: 329  |  大小: 15 KiB

61
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/25-0.jpg

之前 之后
宽度: 329  |  高度: 219  |  大小: 14 KiB

54
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/26-0.jpg

之前 之后
宽度: 220  |  高度: 329  |  大小: 14 KiB

60
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/27-0.jpg

之前 之后
宽度: 219  |  高度: 329  |  大小: 15 KiB

45
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/28-0.jpg

之前 之后
宽度: 329  |  高度: 219  |  大小: 12 KiB

75
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/29-0.jpg

之前 之后
宽度: 219  |  高度: 329  |  大小: 20 KiB

49
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3-0.jpg

之前 之后
宽度: 329  |  高度: 246  |  大小: 13 KiB

437
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/0-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 136 KiB

263
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/1-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 39 KiB

290
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/10-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 64 KiB

218
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/11-0.jpg

之前 之后
宽度: 988  |  高度: 744  |  大小: 40 KiB

290
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/12-0.jpg

之前 之后
宽度: 988  |  高度: 640  |  大小: 67 KiB

222
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/13-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 42 KiB

247
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/14-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 64 KiB

492
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/15-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 118 KiB

317
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/16-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 76 KiB

231
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/shrine_images/3.0x/17-0.jpg

之前 之后
宽度: 988  |  高度: 741  |  大小: 36 KiB

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存