浏览代码

add more samples

/siyaoH-1.17-PlatformMessage
xingwei.zhu 4 年前
当前提交
757fc7f2
共有 6 个文件被更改,包括 1247 次插入345 次删除
  1. 732
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/slider_demo.cs
  2. 36
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demos.cs
  3. 111
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/snack_bar_demo.cs
  4. 240
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/tabs_demo.cs
  5. 387
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/text_form_field_demo.cs
  6. 86
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/tooltip_demo.cs

732
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/slider_demo.cs


namespace UIWidgetsGallery.demo.material
{
class SliderDemo : StatefulWidget {
public static readonly string routeName = "/material/slider";
internal class SliderDemo : StatefulWidget
{
public static readonly string routeName = "/material/slider";
public override State createState() => new _SliderDemoState();
public override State createState()
{
return new _SliderDemoState();
}
static class SliderDemoUtils
internal static class SliderDemoUtils
public static Path _downTriangle(float size, Offset thumbCenter, bool invert = false) {
Path thumbPath = new Path();
float height = Mathf.Sqrt(3.0f) / 2.0f;
float centerHeight = size * height / 3.0f;
float halfSize = size / 2.0f;
float sign = invert ? -1.0f : 1.0f;
thumbPath.moveTo(thumbCenter.dx - halfSize, thumbCenter.dy + sign * centerHeight);
thumbPath.lineTo(thumbCenter.dx, thumbCenter.dy - 2.0f * sign * centerHeight);
thumbPath.lineTo(thumbCenter.dx + halfSize, thumbCenter.dy + sign * centerHeight);
thumbPath.close();
return thumbPath;
}
public static Path _downTriangle(float size, Offset thumbCenter, bool invert = false)
{
Path thumbPath = new Path();
float height = Mathf.Sqrt(3.0f) / 2.0f;
float centerHeight = size * height / 3.0f;
float halfSize = size / 2.0f;
float sign = invert ? -1.0f : 1.0f;
thumbPath.moveTo(thumbCenter.dx - halfSize, thumbCenter.dy + sign * centerHeight);
thumbPath.lineTo(thumbCenter.dx, thumbCenter.dy - 2.0f * sign * centerHeight);
thumbPath.lineTo(thumbCenter.dx + halfSize, thumbCenter.dy + sign * centerHeight);
thumbPath.close();
return thumbPath;
}
public static Path _rightTriangle(float size, Offset thumbCenter, bool invert = false) {
Path thumbPath = new Path();
float halfSize = size / 2.0f;
float sign = invert ? -1.0f : 1.0f;
thumbPath.moveTo(thumbCenter.dx + halfSize * sign, thumbCenter.dy);
thumbPath.lineTo(thumbCenter.dx - halfSize * sign, thumbCenter.dy - size);
thumbPath.lineTo(thumbCenter.dx - halfSize * sign, thumbCenter.dy + size);
thumbPath.close();
return thumbPath;
}
public static Path _rightTriangle(float size, Offset thumbCenter, bool invert = false)
{
Path thumbPath = new Path();
float halfSize = size / 2.0f;
float sign = invert ? -1.0f : 1.0f;
thumbPath.moveTo(thumbCenter.dx + halfSize * sign, thumbCenter.dy);
thumbPath.lineTo(thumbCenter.dx - halfSize * sign, thumbCenter.dy - size);
thumbPath.lineTo(thumbCenter.dx - halfSize * sign, thumbCenter.dy + size);
thumbPath.close();
return thumbPath;
}
public static Path _upTriangle(float size, Offset thumbCenter) => _downTriangle(size, thumbCenter, invert: true);
public static Path _upTriangle(float size, Offset thumbCenter)
{
return _downTriangle(size, thumbCenter, invert: true);
}
public static Path _leftTriangle(float size, Offset thumbCenter) => _rightTriangle(size, thumbCenter, invert: true);
public static Path _leftTriangle(float size, Offset thumbCenter)
{
return _rightTriangle(size, thumbCenter, invert: true);
}
class _CustomRangeThumbShape : RangeSliderThumbShape {
const float _thumbSize = 4.0f;
const float _disabledThumbSize = 3.0f;
public override Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return isEnabled ? Size.fromRadius(_thumbSize) : Size.fromRadius(_disabledThumbSize);
}
internal class _CustomRangeThumbShape : RangeSliderThumbShape
{
private const float _thumbSize = 4.0f;
private const float _disabledThumbSize = 3.0f;
public override Size getPreferredSize(bool isEnabled, bool isDiscrete)
{
return isEnabled ? Size.fromRadius(_thumbSize) : Size.fromRadius(_disabledThumbSize);
}
static readonly Animatable<float> sizeTween = new FloatTween(
begin: _disabledThumbSize,
end: _thumbSize
);
private static readonly Animatable<float> sizeTween = new FloatTween(
begin: _disabledThumbSize,
end: _thumbSize
);
public override void paint(

TextDirection? textDirection = null,
SliderThemeData sliderTheme = null,
Thumb? thumb = null
) {
Canvas canvas = context.canvas;
ColorTween colorTween = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.thumbColor
);
)
{
Canvas canvas = context.canvas;
ColorTween colorTween = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.thumbColor
);
float size = _thumbSize * sizeTween.evaluate(enableAnimation);
Path thumbPath = null;
switch (textDirection) {
case TextDirection.rtl:
switch (thumb) {
case Thumb.start:
thumbPath = SliderDemoUtils._rightTriangle(size, center);
break;
case Thumb.end:
thumbPath = SliderDemoUtils._leftTriangle(size, center);
break;
float size = _thumbSize * sizeTween.evaluate(enableAnimation);
Path thumbPath = null;
switch (textDirection)
{
case TextDirection.rtl:
switch (thumb)
{
case Thumb.start:
thumbPath = SliderDemoUtils._rightTriangle(size, center);
break;
case Thumb.end:
thumbPath = SliderDemoUtils._leftTriangle(size, center);
break;
}
break;
case TextDirection.ltr:
switch (thumb)
{
case Thumb.start:
thumbPath = SliderDemoUtils._leftTriangle(size, center);
break;
case Thumb.end:
thumbPath = SliderDemoUtils._rightTriangle(size, center);
break;
}
break;
}
canvas.drawPath(thumbPath, new Paint {color = colorTween.evaluate(enableAnimation)});
break;
case TextDirection.ltr:
switch (thumb) {
case Thumb.start:
thumbPath = SliderDemoUtils._leftTriangle(size, center);
break;
case Thumb.end:
thumbPath = SliderDemoUtils._rightTriangle(size, center);
break;
}
break;
canvas.drawPath(thumbPath, new Paint{color = colorTween.evaluate(enableAnimation)});
}
}
class _CustomThumbShape : SliderComponentShape {
const float _thumbSize = 4.0f;
const float _disabledThumbSize = 3.0f;
public override Size getPreferredSize(bool isEnabled, bool isDiscrete, TextPainter textPainter) {
return isEnabled ? Size.fromRadius(_thumbSize) : Size.fromRadius(_disabledThumbSize);
}
internal class _CustomThumbShape : SliderComponentShape
{
private const float _thumbSize = 4.0f;
private const float _disabledThumbSize = 3.0f;
static readonly Animatable<float> sizeTween = new FloatTween(
begin: _disabledThumbSize,
end: _thumbSize
);
public override Size getPreferredSize(bool isEnabled, bool isDiscrete, TextPainter textPainter)
{
return isEnabled ? Size.fromRadius(_thumbSize) : Size.fromRadius(_disabledThumbSize);
}
private static readonly Animatable<float> sizeTween = new FloatTween(
begin: _disabledThumbSize,
end: _thumbSize
);
public override void paint(
PaintingContext context,

RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
TextDirection? textDirection = null,
float? value = null) {
Canvas canvas = context.canvas;
ColorTween colorTween = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.thumbColor
);
float size = _thumbSize * sizeTween.evaluate(enableAnimation);
Path thumbPath = SliderDemoUtils._downTriangle(size, center);
canvas.drawPath(thumbPath, new Paint{color = colorTween.evaluate(enableAnimation)});
float? value = null)
{
Canvas canvas = context.canvas;
ColorTween colorTween = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.thumbColor
);
float size = _thumbSize * sizeTween.evaluate(enableAnimation);
Path thumbPath = SliderDemoUtils._downTriangle(size, center);
canvas.drawPath(thumbPath, new Paint {color = colorTween.evaluate(enableAnimation)});
}
}
class _CustomValueIndicatorShape : SliderComponentShape {
const float _indicatorSize = 4.0f;
const float _disabledIndicatorSize = 3.0f;
const float _slideUpHeight = 40.0f;
public override Size getPreferredSize(bool isEnabled, bool isDiscrete, TextPainter textPainter) {
return Size.fromRadius(isEnabled ? _indicatorSize : _disabledIndicatorSize);
}
internal class _CustomValueIndicatorShape : SliderComponentShape
{
private const float _indicatorSize = 4.0f;
private const float _disabledIndicatorSize = 3.0f;
private const float _slideUpHeight = 40.0f;
static readonly Animatable<float> sizeTween = new FloatTween(
begin: _disabledIndicatorSize,
end: _indicatorSize
);
public override Size getPreferredSize(bool isEnabled, bool isDiscrete, TextPainter textPainter)
{
return Size.fromRadius(isEnabled ? _indicatorSize : _disabledIndicatorSize);
}
private static readonly Animatable<float> sizeTween = new FloatTween(
begin: _disabledIndicatorSize,
end: _indicatorSize
);
public override void paint(
PaintingContext context,

RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
TextDirection? textDirection = null,
float? value = null){
Canvas canvas = context.canvas;
ColorTween enableColor = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.valueIndicatorColor
);
float? value = null)
{
Canvas canvas = context.canvas;
ColorTween enableColor = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.valueIndicatorColor
);
begin: 0.0f,
end: _slideUpHeight
);
float size = _indicatorSize * sizeTween.evaluate(enableAnimation);
Offset slideUpOffset = new Offset(0.0f, -slideUpTween.evaluate(activationAnimation));
Path thumbPath = SliderDemoUtils._upTriangle(size, center + slideUpOffset);
Color paintColor = enableColor.evaluate(enableAnimation).withAlpha((255.0f * activationAnimation.value).round());
canvas.drawPath(
thumbPath,
new Paint{color = paintColor}
);
begin: 0.0f,
end: _slideUpHeight
);
float size = _indicatorSize * sizeTween.evaluate(enableAnimation);
Offset slideUpOffset = new Offset(0.0f, -slideUpTween.evaluate(activationAnimation));
Path thumbPath = SliderDemoUtils._upTriangle(size, center + slideUpOffset);
Color paintColor = enableColor.evaluate(enableAnimation)
.withAlpha((255.0f * activationAnimation.value).round());
canvas.drawPath(
thumbPath,
new Paint {color = paintColor}
);
canvas.drawLine(
center,
center + slideUpOffset,

style = PaintingStyle.stroke,
strokeWidth = 2.0f
});
labelPainter.paint(canvas, center + slideUpOffset + new Offset(-labelPainter.width / 2.0f, -labelPainter.height - 4.0f));
labelPainter.paint(canvas,
center + slideUpOffset + new Offset(-labelPainter.width / 2.0f, -labelPainter.height - 4.0f));
}
}
class _SliderDemoState : State<SliderDemo> {
public override Widget build(BuildContext context) {
List<ComponentDemoTabData> demos = new List<ComponentDemoTabData>{
new ComponentDemoTabData(
tabName: "SINGLE",
description: "Sliders containing 1 thumb",
demoWidget: new _Sliders(),
documentationUrl: "https://docs.flutter.io/flutter/material/Slider-class.html"
),
new ComponentDemoTabData(
tabName: "RANGE",
description: "Sliders containing 2 thumbs",
demoWidget: new _RangeSliders(),
documentationUrl: "https://docs.flutter.io/flutter/material/RangeSlider-class.html"
)
internal class _SliderDemoState : State<SliderDemo>
{
public override Widget build(BuildContext context)
{
List<ComponentDemoTabData> demos = new List<ComponentDemoTabData>
{
new ComponentDemoTabData(
tabName: "SINGLE",
description: "Sliders containing 1 thumb",
demoWidget: new _Sliders(),
documentationUrl: "https://docs.flutter.io/flutter/material/Slider-class.html"
),
new ComponentDemoTabData(
tabName: "RANGE",
description: "Sliders containing 2 thumbs",
demoWidget: new _RangeSliders(),
documentationUrl: "https://docs.flutter.io/flutter/material/RangeSlider-class.html"
)
return new TabbedComponentDemoScaffold(
title: "Sliders",
demos: demos,
isScrollable: false,
showExampleCodeAction: false
);
return new TabbedComponentDemoScaffold(
title: "Sliders",
demos: demos,
isScrollable: false,
showExampleCodeAction: false
);
}
internal class _Sliders : StatefulWidget
{
public override State createState()
{
return new _SlidersState();
}
class _Sliders : StatefulWidget {
public override State createState() => new _SlidersState();
}
class _SlidersState : State<_Sliders> {
float _continuousValue = 25.0f;
float _discreteValue = 20.0f;
float _discreteCustomValue = 25.0f;
internal class _SlidersState : State<_Sliders>
{
private float _continuousValue = 25.0f;
private float _discreteValue = 20.0f;
private float _discreteCustomValue = 25.0f;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Padding(
padding: EdgeInsets.symmetric(horizontal: 40.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: new List<Widget>{
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new SizedBox(
width: 64,
height: 48,
child: new TextField(
textAlign: TextAlign.center,
onSubmitted: (string value) => {
float.TryParse(value, out float newValue);
if (newValue != null && newValue != _continuousValue) {
setState(() => {
_continuousValue = newValue.clamp(0.0f, 100.0f);
});
}
},
keyboardType: TextInputType.number,
controller: new TextEditingController(
text: $"{_continuousValue:F0}"
)
)
),
Slider.adaptive(
value: _continuousValue,
min: 0.0f,
max: 100.0f,
onChanged: (float value) => {
setState(() => {
_continuousValue = value;
});
}
),
new Text("Continuous with Editable Numerical Value")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
Slider.adaptive(value: 0.25f, onChanged: null),
new Text("Disabled")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
Slider.adaptive(
value: _discreteValue,
min: 0.0f,
max: 200.0f,
divisions: 5,
label: $"{_discreteValue.round()}",
onChanged: (float value) => {
setState(() => {
_discreteValue = value;
});
}
),
new Text("Discrete")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new SliderTheme(
data: theme.sliderTheme.copyWith(
activeTrackColor: Colors.deepPurple,
inactiveTrackColor: theme.colorScheme.onSurface.withOpacity(0.5f),
activeTickMarkColor: theme.colorScheme.onSurface.withOpacity(0.7f),
inactiveTickMarkColor: theme.colorScheme.surface.withOpacity(0.7f),
overlayColor: theme.colorScheme.onSurface.withOpacity(0.12f),
thumbColor: Colors.deepPurple,
valueIndicatorColor: Colors.deepPurpleAccent,
thumbShape: new _CustomThumbShape(),
valueIndicatorShape: new _CustomValueIndicatorShape(),
valueIndicatorTextStyle: theme.accentTextTheme.bodyText1.copyWith(color: theme.colorScheme.onSurface)
),
child: new Slider(
value: _discreteCustomValue,
min: 0.0f,
max: 200.0f,
divisions: 5,
label: $"{_discreteCustomValue.round()}",
onChanged: (float value) => {
setState(() => {
_discreteCustomValue = value;
});
}
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
return new Padding(
padding: EdgeInsets.symmetric(horizontal: 40.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: new List<Widget>
{
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
new SizedBox(
width: 64,
height: 48,
child: new TextField(
textAlign: TextAlign.center,
onSubmitted: (string value) =>
{
float.TryParse(value, out float newValue);
if (newValue != null && newValue != _continuousValue)
setState(() => { _continuousValue = newValue.clamp(0.0f, 100.0f); });
},
keyboardType: TextInputType.number,
controller: new TextEditingController(
text: $"{_continuousValue:F0}"
)
)
),
Slider.adaptive(
value: _continuousValue,
min: 0.0f,
max: 100.0f,
onChanged: (float value) => { setState(() => { _continuousValue = value; }); }
),
new Text("Continuous with Editable Numerical Value")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
Slider.adaptive(value: 0.25f, onChanged: null),
new Text("Disabled")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
Slider.adaptive(
value: _discreteValue,
min: 0.0f,
max: 200.0f,
divisions: 5,
label: $"{_discreteValue.round()}",
onChanged: (float value) => { setState(() => { _discreteValue = value; }); }
),
new Text("Discrete")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
new SliderTheme(
data: theme.sliderTheme.copyWith(
activeTrackColor: Colors.deepPurple,
inactiveTrackColor: theme.colorScheme.onSurface.withOpacity(0.5f),
activeTickMarkColor: theme.colorScheme.onSurface.withOpacity(0.7f),
inactiveTickMarkColor: theme.colorScheme.surface.withOpacity(0.7f),
overlayColor: theme.colorScheme.onSurface.withOpacity(0.12f),
thumbColor: Colors.deepPurple,
valueIndicatorColor: Colors.deepPurpleAccent,
thumbShape: new _CustomThumbShape(),
valueIndicatorShape: new _CustomValueIndicatorShape(),
valueIndicatorTextStyle: theme.accentTextTheme.bodyText1.copyWith(
color: theme.colorScheme.onSurface)
),
child: new Slider(
value: _discreteCustomValue,
min: 0.0f,
max: 200.0f,
divisions: 5,
label: $"{_discreteCustomValue.round()}",
onChanged: (float value) =>
{
setState(() => { _discreteCustomValue = value; });
}
)
),
new Text("Discrete with Custom Theme")
}
)
}
),
new Text("Discrete with Custom Theme")
}
)
);
)
);
}
}
class _RangeSliders : StatefulWidget {
public override State createState() => new _RangeSlidersState();
class _RangeSlidersState : State<_RangeSliders> {
RangeValues _continuousValues = new RangeValues(25.0f, 75.0f);
RangeValues _discreteValues = new RangeValues(40.0f, 120.0f);
RangeValues _discreteCustomValues = new RangeValues(40.0f, 160.0f);
internal class _RangeSliders : StatefulWidget
{
public override State createState()
{
return new _RangeSlidersState();
}
}
internal class _RangeSlidersState : State<_RangeSliders>
{
private RangeValues _continuousValues = new RangeValues(25.0f, 75.0f);
private RangeValues _discreteValues = new RangeValues(40.0f, 120.0f);
private RangeValues _discreteCustomValues = new RangeValues(40.0f, 160.0f);
public override Widget build(BuildContext context) {
return new Padding(
padding: EdgeInsets.symmetric(horizontal: 40.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: new List<Widget>{
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new RangeSlider(
values: _continuousValues,
min: 0.0f,
max: 100.0f,
onChanged: (RangeValues values) => {
setState(() => {
_continuousValues = values;
});
}
),
new Text("Continuous")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new RangeSlider(values: new RangeValues(0.25f, 0.75f), onChanged: null),
new Text("Disabled")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new RangeSlider(
values: _discreteValues,
min: 0.0f,
max: 200.0f,
//divisions: 5,
labels: new RangeLabels($"{_discreteValues.start.round()}", $"{_discreteValues.end.round()}"),
onChanged: (RangeValues values) => {
setState(() => {
_discreteValues = values;
});
}
),
new Text("Discrete")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new SliderTheme(
data: new SliderThemeData(
activeTrackColor: Colors.deepPurple,
inactiveTrackColor: Colors.black26,
activeTickMarkColor: Colors.white70,
inactiveTickMarkColor: Colors.black,
overlayColor: Colors.black12,
thumbColor: Colors.deepPurple,
rangeThumbShape: new _CustomRangeThumbShape(),
showValueIndicator: ShowValueIndicator.never
),
child: new RangeSlider(
values: _discreteCustomValues,
min: 0.0f,
max: 200.0f,
divisions: 5,
labels: new RangeLabels($"{_discreteCustomValues.start.round()}", $"{_discreteCustomValues.end.round()}"),
onChanged: (RangeValues values) => {
setState(() => {
_discreteCustomValues = values;
});
}
public override Widget build(BuildContext context)
{
return new Padding(
padding: EdgeInsets.symmetric(horizontal: 40.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: new List<Widget>
{
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
new RangeSlider(
values: _continuousValues,
min: 0.0f,
max: 100.0f,
onChanged: (RangeValues values) =>
{
setState(() => { _continuousValues = values; });
}
),
new Text("Continuous")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
new RangeSlider(values: new RangeValues(0.25f, 0.75f), onChanged: null),
new Text("Disabled")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
new RangeSlider(
values: _discreteValues,
min: 0.0f,
max: 200.0f,
//divisions: 5,
labels: new RangeLabels($"{_discreteValues.start.round()}",
$"{_discreteValues.end.round()}"),
onChanged: (RangeValues values) =>
{
setState(() => { _discreteValues = values; });
}
),
new Text("Discrete")
}
),
new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>
{
new SliderTheme(
data: new SliderThemeData(
activeTrackColor: Colors.deepPurple,
inactiveTrackColor: Colors.black26,
activeTickMarkColor: Colors.white70,
inactiveTickMarkColor: Colors.black,
overlayColor: Colors.black12,
thumbColor: Colors.deepPurple,
rangeThumbShape: new _CustomRangeThumbShape(),
showValueIndicator: ShowValueIndicator.never
),
child: new RangeSlider(
values: _discreteCustomValues,
min: 0.0f,
max: 200.0f,
divisions: 5,
labels: new RangeLabels($"{_discreteCustomValues.start.round()}",
$"{_discreteCustomValues.end.round()}"),
onChanged: (RangeValues values) =>
{
setState(() => { _discreteCustomValues = values; });
}
)
),
new Text("Discrete with Custom Theme")
}
)
}
),
new Text("Discrete with Custom Theme")
}
)
);
)
);
}
}
}
}

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


buildRoute: (BuildContext context) => new SliderDemo()
),
new GalleryDemo(
title: "Snackbar",
subtitle: "Temporary messaging",
icon: GalleryIcons.snackbar,
category: GalleryDemoCategory._kMaterialComponents,
routeName: SnackBarDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/ScaffoldState/showSnackBar.html",
buildRoute: (BuildContext context) => new SnackBarDemo()
),
new GalleryDemo(
title: "Tabs",
subtitle: "Tabs with independently scrollable views",
icon: GalleryIcons.tabs,
category: GalleryDemoCategory._kMaterialComponents,
routeName: TabsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/TabBarView-class.html",
buildRoute: (BuildContext context) => new TabsDemo()
),
new GalleryDemo(
title: "Dialogs",
subtitle: "Simple, alert, and fullscreen",
icon: GalleryIcons.dialogs,

routeName: ScrollableTabsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/TabBar-class.html",
buildRoute: (BuildContext context) => new ScrollableTabsDemo()
),
new GalleryDemo(
title: "Text fields",
subtitle: "Single line of editable text and numbers",
icon: GalleryIcons.text_fields_alt,
category: GalleryDemoCategory._kMaterialComponents,
routeName: TextFormFieldDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/TextFormField-class.html",
buildRoute: (BuildContext context) => new TextFormFieldDemo()
),
new GalleryDemo(
title: "Tooltips",
subtitle: "Short message displayed on long-press",
icon: GalleryIcons.tooltip,
category: GalleryDemoCategory._kMaterialComponents,
routeName: TooltipDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/Tooltip-class.html",
buildRoute: (BuildContext context) => new TooltipDemo()
)
};

111
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/snack_bar_demo.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
using UnityEngine;
namespace UIWidgetsGallery.demo.material
{
internal static class SnackBarDemoUtils
{
public static readonly string _text1 =
"Snackbars provide lightweight feedback about an operation by " +
"showing a brief message at the bottom of the screen. Snackbars " +
"can contain an action.";
public static readonly string _text2 =
"Snackbars should contain a single line of text directly related " +
"to the operation performed. They cannot contain icons.";
public static readonly string _text3 =
"By default snackbars automatically disappear after a few seconds ";
}
internal class SnackBarDemo : StatefulWidget
{
public SnackBarDemo(Key key = null) : base(key: key)
{
}
public static readonly string routeName = "/material/snack-bar";
public override State createState()
{
return new _SnackBarDemoState();
}
}
internal class _SnackBarDemoState : State<SnackBarDemo>
{
private int _snackBarIndex = 1;
private Widget buildBody(BuildContext context)
{
return new SafeArea(
top: false,
bottom: false,
child: new ListView(
padding: EdgeInsets.all(24.0f),
children: new List<Widget>
{
new Text(SnackBarDemoUtils._text1),
new Text(SnackBarDemoUtils._text2),
new Center(
child: new RaisedButton(
child: new Text("SHOW A SNACKBAR"),
onPressed: () =>
{
int thisSnackBarIndex = _snackBarIndex++;
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text($"This is snackbar #{thisSnackBarIndex}."),
action: new SnackBarAction(
label: "ACTION",
onPressed: () =>
{
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text(
$"You pressed snackbar {thisSnackBarIndex}'s action.")
));
}
)
));
}
)
),
new Text(SnackBarDemoUtils._text3)
}
.Select<Widget, Widget>((Widget child) =>
{
return new Container(
margin: EdgeInsets.symmetric(vertical: 12.0f),
child: child
);
})
.ToList()
)
);
}
public override Widget build(BuildContext context)
{
return new Scaffold(
appBar: new AppBar(
title: new Text("Snackbar"),
actions: new List<Widget> {new MaterialDemoDocumentationButton(SnackBarDemo.routeName)}
),
body: new Builder(
builder: buildBody
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
tooltip: "Create",
onPressed: () => { Debug.Log("Floating Action Button was pressed"); }
)
);
}
}
}

240
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/tabs_demo.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
static class TabsDemoUtils
{
public static readonly string _kGalleryAssetsPackage = "flutter_gallery_assets";
public static readonly Dictionary<_TabPage, List<_CardData>> _allPages =
new Dictionary<_TabPage, List<_CardData>>
{
{
new _TabPage(label: "HOME"), new List<_CardData>
{
new _CardData(
title: "Flatwear",
imageAsset: "products/flatwear.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Pine Table",
imageAsset: "products/table.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Blue Cup",
imageAsset: "products/cup.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Tea Set",
imageAsset: "products/teaset.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Desk Set",
imageAsset: "products/deskset.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Blue Linen Napkins",
imageAsset: "products/napkins.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Planters",
imageAsset: "products/planters.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Kitchen Quattro",
imageAsset: "products/kitchen_quattro.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Platter",
imageAsset: "products/platter.png",
imageAssetPackage: _kGalleryAssetsPackage
),
}
},
{
new _TabPage(label: "APPAREL"), new List<_CardData>
{
new _CardData(
title: "Cloud-White Dress",
imageAsset: "products/dress.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Ginger Scarf",
imageAsset: "products/scarf.png",
imageAssetPackage: _kGalleryAssetsPackage
),
new _CardData(
title: "Blush Sweats",
imageAsset: "products/sweats.png",
imageAssetPackage: _kGalleryAssetsPackage
),
}
}
};
}
internal class _TabPage {
public _TabPage(string label)
{
this.label = label;
}
public readonly string label;
public string id => label.Substring(0, 1);
public override string ToString() => $"{GetType()}(\"{label}\")";
}
internal class _CardData {
public _CardData(string title, string imageAsset, string imageAssetPackage)
{
this.title = title;
this.imageAsset = imageAsset;
this.imageAssetPackage = imageAssetPackage;
}
public readonly string title;
public readonly string imageAsset;
public readonly string imageAssetPackage;
}
class _CardDataItem : StatelessWidget {
public _CardDataItem(_TabPage page, _CardData data)
{
this.page = page;
this.data = data;
}
internal const float height = 272.0f;
public readonly _TabPage page;
public readonly _CardData data;
public override Widget build(BuildContext context) {
return new Card(
child: new Padding(
padding: EdgeInsets.all(16.0f),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: new List<Widget>{
new Align(
alignment: page.id == "H"
? Alignment.centerLeft
: Alignment.centerRight,
child: new CircleAvatar(child: new Text(page.id))
),
new SizedBox(
width: 144.0f,
height: 144.0f,
child: Image.file(
data.imageAssetPackage + data.imageAsset,
fit: BoxFit.contain
)
),
new Center(
child: new Text(
data.title,
style: Theme.of(context).textTheme.headline6
)
)
}
)
)
);
}
}
class TabsDemo : StatelessWidget {
public static readonly string routeName = "/material/tabs";
public override Widget build(BuildContext context) {
return new DefaultTabController(
length: TabsDemoUtils._allPages.Count,
child: new Scaffold(
body: new NestedScrollView(
headerSliverBuilder: (BuildContext subContext, bool innerBoxIsScrolled) => {
return new List<Widget>{
new SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(subContext),
sliver: new SliverAppBar(
title: new Text("Tabs and scrolling"),
actions: new List<Widget>{new MaterialDemoDocumentationButton(routeName)},
pinned: true,
expandedHeight: 150.0f,
forceElevated: innerBoxIsScrolled,
bottom: new TabBar(
tabs: TabsDemoUtils._allPages.Keys.Select<_TabPage, Widget>(
(_TabPage page) => new Tab(text: page.label)
).ToList()
)
)
)
};
},
body: new TabBarView(
children: TabsDemoUtils._allPages.Keys.Select<_TabPage, Widget>((_TabPage page) => {
return new SafeArea(
top: false,
bottom: false,
child: new Builder(
builder: (BuildContext subContext) => {
return new CustomScrollView(
key: new PageStorageKey<_TabPage>(page),
slivers: new List<Widget>{
new SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(subContext)
),
new SliverPadding(
padding: EdgeInsets.symmetric(
vertical: 8.0f,
horizontal: 16.0f
),
sliver: new SliverFixedExtentList(
itemExtent: _CardDataItem.height,
del: new SliverChildBuilderDelegate(
(BuildContext subsubContext, int index) => {
_CardData data = TabsDemoUtils._allPages[page][index];
return new Padding(
padding: EdgeInsets.symmetric(
vertical: 8.0f
),
child: new _CardDataItem(
page: page,
data: data
)
);
},
childCount: TabsDemoUtils._allPages[page].Count
)
)
)
}
);
}
)
);
}).ToList()
)
)
)
);
}
}
}

387
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/text_form_field_demo.cs


using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using uiwidgets;
using UIWidgets.Runtime.material;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.async2;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
internal class TextFormFieldDemo : StatefulWidget
{
public TextFormFieldDemo(Key key = null) : base(key: key)
{
}
public static readonly string routeName = "/material/text-form-field";
public override State createState()
{
return new TextFormFieldDemoState();
}
}
internal class PersonData
{
public string name = "";
public string phoneNumber = "";
public string email = "";
public string password = "";
}
internal class PasswordField : StatefulWidget
{
public PasswordField(
Key fieldKey = null,
string hintText = null,
string labelText = null,
string helperText = null,
FormFieldSetter<string> onSaved = null,
FormFieldValidator<string> validator = null,
ValueChanged<string> onFieldSubmitted = null
)
{
this.fieldKey = fieldKey;
this.hintText = hintText;
this.labelText = labelText;
this.helperText = helperText;
this.onSaved = onSaved;
this.validator = validator;
this.onFieldSubmitted = onFieldSubmitted;
}
public readonly Key fieldKey;
public readonly string hintText;
public readonly string labelText;
public readonly string helperText;
public readonly FormFieldSetter<string> onSaved;
public readonly FormFieldValidator<string> validator;
public readonly ValueChanged<string> onFieldSubmitted;
public override State createState()
{
return new _PasswordFieldState();
}
}
internal class _PasswordFieldState : State<PasswordField>
{
private bool _obscureText = true;
public override Widget build(BuildContext context)
{
return new TextFormField(
key: widget.fieldKey,
obscureText: _obscureText,
maxLength: 8,
onSaved: widget.onSaved,
validator: widget.validator,
onFieldSubmitted: widget.onFieldSubmitted,
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
filled: true,
hintText: widget.hintText,
labelText: widget.labelText,
helperText: widget.helperText,
suffixIcon: new GestureDetector(
dragStartBehavior: DragStartBehavior.down,
onTap: () => { setState(() => { _obscureText = !_obscureText; }); },
child: new Icon(
_obscureText ? Icons.visibility : Icons.visibility_off
)
)
)
);
}
}
internal class TextFormFieldDemoState : State<TextFormFieldDemo>
{
private readonly GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
private PersonData person = new PersonData();
private void showInSnackBar(string value)
{
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(value)
));
}
private bool _autovalidate = false;
private bool _formWasEdited = false;
private readonly GlobalKey<FormState> _formKey = GlobalKey<FormState>.key();
private readonly GlobalKey<FormFieldState<string>> _passwordFieldKey = GlobalKey<FormFieldState<string>>.key();
private readonly _UsNumberTextInputFormatter _phoneNumberFormatter = new _UsNumberTextInputFormatter();
private void _handleSubmitted()
{
FormState form = _formKey.currentState;
if (!form.validate())
{
_autovalidate = true; // Start validating on every change"
showInSnackBar("Please fix the errors in red before submitting.");
}
else
{
form.save();
showInSnackBar($"{person.name}'s phone number is ${person.phoneNumber}");
}
}
private string _validateName(string value)
{
_formWasEdited = true;
if (value.isEmpty())
return "Name is required.";
if (!Regex.IsMatch(value, @"^[a-zA-Z]+$"))
return "Please enter only alphabetical characters.";
return null;
}
private string _validatePhoneNumber(string value)
{
_formWasEdited = true;
if (!Regex.IsMatch(value, @"^\(\d\d\d\) \d\d\d\-\d\d\d\d$"))
return "(###) ###-#### - Enter a US phone number.";
return null;
}
private string _validatePassword(string value)
{
_formWasEdited = true;
FormFieldState<string> passwordField = _passwordFieldKey.currentState;
if (passwordField.value == null || passwordField.value.isEmpty())
return "Please enter a password.";
if (passwordField.value != value)
return "The passwords don't match";
return null;
}
private Future<bool> _warnUserAboutInvalidData()
{
FormState form = _formKey.currentState;
if (form == null || !_formWasEdited || form.validate())
return Future.value(true).to<bool>();
return material_.showDialog<bool>(
context: context,
builder: (BuildContext context) =>
{
return new AlertDialog(
title: new Text("This form has errors"),
content: new Text("Really leave this form?"),
actions: new List<Widget>
{
new FlatButton(
child: new Text("YES"),
onPressed: () => { Navigator.of(context).pop(true); }
),
new FlatButton(
child: new Text("NO"),
onPressed: () => { Navigator.of(context).pop(false); }
)
}
);
}
);
}
public override Widget build(BuildContext context)
{
return new Scaffold(
drawerDragStartBehavior: DragStartBehavior.down,
key: _scaffoldKey,
appBar: new AppBar(
title: new Text("Text fields"),
actions: new List<Widget> {new MaterialDemoDocumentationButton(TextFormFieldDemo.routeName)}
),
body: new SafeArea(
top: false,
bottom: false,
child: new Form(
key: _formKey,
autovalidate: _autovalidate,
onWillPop: _warnUserAboutInvalidData,
child: new Scrollbar(
child: new SingleChildScrollView(
dragStartBehavior: DragStartBehavior.down,
padding: EdgeInsets.symmetric(horizontal: 16.0f),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget>
{
new SizedBox(height: 24.0f),
new TextFormField(
textCapitalization: TextCapitalization.words,
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
filled: true,
icon: new Icon(Icons.person),
hintText: "What do people call you?",
labelText: "Name *"
),
onSaved: (string value) => { person.name = value; },
validator: _validateName
),
new SizedBox(height: 24.0f),
new TextFormField(
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
filled: true,
icon: new Icon(Icons.phone),
hintText: "Where can we reach you?",
labelText: "Phone Number *",
prefixText: "+1"
),
keyboardType: TextInputType.phone,
onSaved: (string value) => { person.phoneNumber = value; },
validator: _validatePhoneNumber,
// TextInputFormatters are applied in sequence.
inputFormatters: new List<TextInputFormatter>
{
WhitelistingTextInputFormatter.digitsOnly,
// Fit the validating format.
_phoneNumberFormatter
}
),
new SizedBox(height: 24.0f),
new TextFormField(
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
filled: true,
icon: new Icon(Icons.email),
hintText: "Your email address",
labelText: "E-mail"
),
keyboardType: TextInputType.emailAddress,
onSaved: (string value) => { person.email = value; }
),
new SizedBox(height: 24.0f),
new TextFormField(
decoration: new InputDecoration(
border: new OutlineInputBorder(),
hintText:
"Tell us about yourself (e.g., write down what you do or what hobbies you have)",
helperText: "Keep it short, this is just a demo.",
labelText: "Life story"
),
maxLines: 3
),
new SizedBox(height: 24.0f),
new TextFormField(
keyboardType: TextInputType.number,
decoration: new InputDecoration(
border: new OutlineInputBorder(),
labelText: "Salary",
prefixText: "$",
suffixText: "USD",
suffixStyle: new TextStyle(color: Colors.green)
),
maxLines: 1
),
new SizedBox(height: 24.0f),
new PasswordField(
fieldKey: _passwordFieldKey,
helperText: "No more than 8 characters.",
labelText: "Password *",
onFieldSubmitted: (string value) =>
{
setState(() => { person.password = value; });
}
),
new SizedBox(height: 24.0f),
new TextFormField(
enabled: person.password != null && person.password.isNotEmpty(),
decoration: new InputDecoration(
border: new UnderlineInputBorder(),
filled: true,
labelText: "Re-type password"
),
maxLength: 8,
obscureText: true,
validator: _validatePassword
),
new SizedBox(height: 24.0f),
new Center(
child: new RaisedButton(
child: new Text("SUBMIT"),
onPressed: _handleSubmitted
)
),
new SizedBox(height: 24.0f),
new Text(
"* indicates required field",
style: Theme.of(context).textTheme.caption
),
new SizedBox(height: 24.0f)
}
)
)
)
)
)
);
}
}
internal class _UsNumberTextInputFormatter : TextInputFormatter
{
public override TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue
)
{
int newTextLength = newValue.text.Length;
int selectionIndex = newValue.selection.end;
int usedSubstringIndex = 0;
StringBuilder newText = new StringBuilder();
if (newTextLength >= 1)
{
newText.Append("(");
if (newValue.selection.end >= 1)
selectionIndex++;
}
if (newTextLength >= 4)
{
newText.Append(newValue.text.Substring(0, usedSubstringIndex = 3) + ") ");
if (newValue.selection.end >= 3)
selectionIndex += 2;
}
if (newTextLength >= 7)
{
newText.Append(newValue.text.Substring(3, usedSubstringIndex = 6) + "-");
if (newValue.selection.end >= 6)
selectionIndex++;
}
if (newTextLength >= 11)
{
newText.Append(newValue.text.Substring(6, usedSubstringIndex = 10) + " ");
if (newValue.selection.end >= 10)
selectionIndex++;
}
// Dump the rest.
if (newTextLength >= usedSubstringIndex)
newText.Append(newValue.text.Substring(usedSubstringIndex));
return new TextEditingValue(
text: newText.ToString(),
selection: TextSelection.collapsed(offset: selectionIndex)
);
}
}
}

86
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/tooltip_demo.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
internal static class TooltipsDemoUtils
{
public static readonly string _introText =
"Tooltips are short identifying messages that briefly appear in response to " +
"a long press. Tooltip messages are also used by services that make Flutter " +
"apps accessible, like screen readers.";
}
internal class TooltipDemo : StatelessWidget
{
public static readonly string routeName =
"/material/tooltips";
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
return new Scaffold(
appBar: new AppBar(
title: new Text("Tooltips"),
actions: new List<Widget> {new MaterialDemoDocumentationButton(routeName)}
),
body: new Builder(
builder: (BuildContext subContext) =>
{
return new SafeArea(
top: false,
bottom: false,
child: new ListView(
children: new List<Widget>
{
new Text(TooltipsDemoUtils._introText, style: theme.textTheme.subtitle1),
new Row(
children: new List<Widget>
{
new Text("Long press the ", style: theme.textTheme.subtitle1),
new Tooltip(
message: "call icon",
child: new Icon(
Icons.call,
size: 18.0f,
color: theme.iconTheme.color
)
),
new Text(" icon.", style: theme.textTheme.subtitle1)
}
),
new Center(
child: new IconButton(
iconSize: 48.0f,
icon: new Icon(Icons.call),
color: theme.iconTheme.color,
tooltip: "Place a phone call",
onPressed: () =>
{
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text("That was an ordinary tap.")
));
}
)
)
}
.Select<Widget, Widget>((Widget widget) =>
{
return new Padding(
padding: EdgeInsets.only(top: 16.0f, left: 16.0f, right: 16.0f),
child: widget
);
})
.ToList()
)
);
}
)
);
}
}
}
正在加载...
取消
保存