浏览代码

add expansion example (WIP)

/siyaoH-1.17-PlatformMessage
xingweizhu 4 年前
当前提交
11cab4cd
共有 6 个文件被更改,包括 547 次插入97 次删除
  1. 175
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demos.cs
  2. 12
      com.unity.uiwidgets/Runtime/material/radio.cs
  3. 4
      com.unity.uiwidgets/Runtime/material/ratio_list_tile.cs
  4. 8
      com.unity.uiwidgets/Runtime/widgets/form.cs
  5. 442
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/expansion_panels_demo.cs
  6. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/expansion_panels_demo.cs.meta

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


public static List<GalleryDemo> _buildGalleryDemos()
{
List<GalleryDemo> cupertinoDemos = new List<GalleryDemo>()
{
new GalleryDemo(
title: "Activity Indicator",
icon: GalleryIcons.cupertino_progress,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoProgressIndicatorDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoActivityIndicator-class.html",
buildRoute: (BuildContext context) => new CupertinoProgressIndicatorDemo()
),
new GalleryDemo(
title: "Alerts",
icon: GalleryIcons.dialogs,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoAlertDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/showCupertinoDialog.html",
buildRoute: (BuildContext context) => new CupertinoAlertDemo()
),
new GalleryDemo(
title: "Buttons",
icon: GalleryIcons.generic_buttons,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoButtonsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoButton-class.html",
buildRoute: (BuildContext context) => new CupertinoButtonsDemo()
),
new GalleryDemo(
title: "Navigation",
icon: GalleryIcons.bottom_navigation,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoNavigationDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoTabScaffold-class.html",
buildRoute: (BuildContext context) => new CupertinoNavigationDemo()
),
new GalleryDemo(
title: "Pickers",
icon: GalleryIcons.cards,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoPickerDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoPicker-class.html",
buildRoute: (BuildContext context) => new CupertinoPickerDemo()
),
new GalleryDemo(
title: "Pull to refresh",
icon: GalleryIcons.cupertino_pull_to_refresh,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoRefreshControlDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSliverRefreshControl-class.html",
buildRoute: (BuildContext context) => new CupertinoRefreshControlDemo()
),
new GalleryDemo(
title: "Segmented Control",
icon: GalleryIcons.tabs,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoSegmentedControlDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSegmentedControl-class.html",
buildRoute: (BuildContext context) => new CupertinoSegmentedControlDemo()
),
new GalleryDemo(
title: "Sliders",
icon: GalleryIcons.sliders,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoSliderDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSlider-class.html",
buildRoute: (BuildContext context) => new CupertinoSliderDemo()
),
new GalleryDemo(
title: "Switches",
icon: GalleryIcons.cupertino_switch,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoSwitchDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSwitch-class.html",
buildRoute: (BuildContext context) => new CupertinoSwitchDemo()
),
new GalleryDemo(
title: "Text Fields",
icon: GalleryIcons.text_fields_alt,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoTextFieldDemo.routeName,
buildRoute: (BuildContext context) => new CupertinoTextFieldDemo()
)
};
List<GalleryDemo> galleryDemos = new List<GalleryDemo>
{
new GalleryDemo(

documentationUrl: "https://docs.flutter.io/flutter/material/Drawer-class.html",
buildRoute: (BuildContext context) => new DrawerDemo()
),
new GalleryDemo(
title: "Expansion panels",
subtitle: "List of expanding panels",
icon: GalleryIcons.expand_all,
category: GalleryDemoCategory._kMaterialComponents,
routeName: ExpansionPanelsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/ExpansionPanel-class.html",
buildRoute: (BuildContext context) => new ExpansionPanelsDemo()
),
new GalleryDemo(
title: "Activity Indicator",
icon: GalleryIcons.cupertino_progress,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoProgressIndicatorDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoActivityIndicator-class.html",
buildRoute: (BuildContext context) => new CupertinoProgressIndicatorDemo()
),
new GalleryDemo(
title: "Alerts",
icon: GalleryIcons.dialogs,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoAlertDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/showCupertinoDialog.html",
buildRoute: (BuildContext context) => new CupertinoAlertDemo()
),
new GalleryDemo(
title: "Buttons",
icon: GalleryIcons.generic_buttons,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoButtonsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoButton-class.html",
buildRoute: (BuildContext context) => new CupertinoButtonsDemo()
),
new GalleryDemo(
title: "Navigation",
icon: GalleryIcons.bottom_navigation,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoNavigationDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoTabScaffold-class.html",
buildRoute: (BuildContext context) => new CupertinoNavigationDemo()
),
new GalleryDemo(
title: "Pickers",
icon: GalleryIcons.cards,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoPickerDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoPicker-class.html",
buildRoute: (BuildContext context) => new CupertinoPickerDemo()
),
new GalleryDemo(
title: "Pull to refresh",
icon: GalleryIcons.cupertino_pull_to_refresh,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoRefreshControlDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSliverRefreshControl-class.html",
buildRoute: (BuildContext context) => new CupertinoRefreshControlDemo()
),
new GalleryDemo(
title: "Segmented Control",
icon: GalleryIcons.tabs,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoSegmentedControlDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSegmentedControl-class.html",
buildRoute: (BuildContext context) => new CupertinoSegmentedControlDemo()
),
new GalleryDemo(
title: "Sliders",
icon: GalleryIcons.sliders,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoSliderDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSlider-class.html",
buildRoute: (BuildContext context) => new CupertinoSliderDemo()
),
new GalleryDemo(
title: "Switches",
icon: GalleryIcons.cupertino_switch,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoSwitchDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSwitch-class.html",
buildRoute: (BuildContext context) => new CupertinoSwitchDemo()
),
new GalleryDemo(
title: "Text Fields",
icon: GalleryIcons.text_fields_alt,
category:GalleryDemoCategory._kCupertinoComponents,
routeName: CupertinoTextFieldDemo.routeName,
buildRoute: (BuildContext context) => new CupertinoTextFieldDemo()
)
return cupertinoDemos;
return galleryDemos;
}
public static readonly List<GalleryDemo> kAllGalleryDemos = _buildGalleryDemos();

12
com.unity.uiwidgets/Runtime/material/radio.cs


public const float _kInnerRadius = 4.5f;
}
public class Radio<T> : StatefulWidget where T : class {
public class Radio<T> : StatefulWidget {
T value = null,
T groupValue = null,
T value = default,
T groupValue = default,
ValueChanged<T> onChanged = null,
bool toggleable = false,
Color activeColor = null,

}
}
class _RadioState<T> : TickerProviderStateMixin<Radio<T>> where T : class {
class _RadioState<T> : TickerProviderStateMixin<Radio<T>> {
bool enabled {
get { return widget.onChanged != null; }
}

void _handleChanged(bool? selected) {
if (selected == null) {
widget.onChanged(null);
widget.onChanged(default);
return;
}
if (selected == true) {

child: new Builder(
builder: (BuildContext subContext) => {
return new _RadioRenderObjectWidget(
selected: widget.value == widget.groupValue,
selected: widget.value.Equals(widget.groupValue),
activeColor: widget.activeColor ?? themeData.toggleableActiveColor,
inactiveColor: _getInactiveColor(themeData),
focusColor: widget.focusColor ?? themeData.focusColor,

4
com.unity.uiwidgets/Runtime/material/ratio_list_tile.cs


using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class RadioListTile<T> : StatelessWidget where T : class {
public class RadioListTile<T> : StatelessWidget {
public RadioListTile(
Key key = null,
T value = default,

onTap: onChanged != null
? () => {
if (toggleable && isChecked) {
onChanged(null);
onChanged(default);
return;
}

8
com.unity.uiwidgets/Runtime/widgets/form.cs


public delegate void FormFieldSetter<T>(T newValue);
public delegate Widget FormFieldBuilder<T>(FormFieldState<T> field) where T : class;
public delegate Widget FormFieldBuilder<T>(FormFieldState<T> field);
public class FormField<T> : StatefulWidget where T : class {
public class FormField<T> : StatefulWidget {
T initialValue = null,
T initialValue = default,
bool autovalidate = false,
bool enabled = true
) : base(key: key) {

void reset();
}
public class FormFieldState<T> : State<FormField<T>>, FormFieldState where T : class {
public class FormFieldState<T> : State<FormField<T>>, FormFieldState {
T _value;
string _errorText;

442
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/expansion_panels_demo.cs


using System;
using System.Collections.Generic;
using System.Linq;
using uiwidgets;
using UIWidgets.Runtime.material;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsGallery.demo.material
{
enum Location {
Barbados,
Bahamas,
Bermuda
}
delegate Widget DemoItemBodyBuilder(DemoItem item);
delegate string ValueToString<T>(T value);
class DualHeaderWithHint : StatelessWidget {
public DualHeaderWithHint(
string name = null,
string value = null,
string hint = null,
bool showHint = false
)
{
this.name = name;
this.value = value;
this.hint = hint;
this.showHint = showHint;
}
public readonly string name;
public readonly string value;
public readonly string hint;
public readonly bool showHint;
Widget _crossFade(Widget first, Widget second, bool isExpanded) {
return new AnimatedCrossFade(
firstChild: first,
secondChild: second,
firstCurve: new Interval(0.0f, 0.6f, curve: Curves.fastOutSlowIn),
secondCurve: new Interval(0.4f, 1.0f, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: isExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: new TimeSpan(0,0,0,0, 200)
);
}
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextTheme textTheme = theme.textTheme;
return new Row(
children: new List<Widget>{
new Expanded(
flex: 2,
child: new Container(
margin: EdgeInsets.only(left: 24.0f),
child: new FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: new Text(
name,
style: textTheme.bodyText2.copyWith(fontSize: 15.0f)
)
)
)
),
new Expanded(
flex: 3,
child: new Container(
margin: EdgeInsets.only(left: 24.0f),
child: _crossFade(
new Text(value, style: textTheme.caption.copyWith(fontSize: 15.0f)),
new Text(hint, style: textTheme.caption.copyWith(fontSize: 15.0f)),
showHint
)
)
)
}
);
}
}
class CollapsibleBody : StatelessWidget {
public CollapsibleBody(
EdgeInsets margin = null,
Widget child = null,
VoidCallback onSave = null,
VoidCallback onCancel = null
)
{
margin = margin ?? EdgeInsets.zero;
this.margin = margin;
this.child = child;
this.onSave = onSave;
this.onCancel = onCancel;
}
public readonly EdgeInsets margin;
public readonly Widget child;
public readonly VoidCallback onSave;
public readonly VoidCallback onCancel;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextTheme textTheme = theme.textTheme;
return new Column(
children: new List<Widget>{
new Container(
margin: EdgeInsets.only(
left: 24.0f,
right: 24.0f,
bottom: 24.0f
) - margin,
child: new Center(
child: new DefaultTextStyle(
style: textTheme.caption.copyWith(fontSize: 15.0f),
child: child
)
)
),
new Divider(height: 1.0f),
new Container(
padding: EdgeInsets.symmetric(vertical: 16.0f),
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: new List<Widget>{
new Container(
margin: EdgeInsets.only(right: 8.0f),
child: new FlatButton(
onPressed: onCancel,
child: new Text("CANCEL", style: new TextStyle(
color: Colors.black54,
fontSize: 15.0f,
fontWeight: FontWeight.w500
))
)
),
new Container(
margin: EdgeInsets.only(right: 8.0f),
child: new FlatButton(
onPressed: onSave,
textTheme: ButtonTextTheme.accent,
child: new Text("SAVE")
)
)
}
)
)
}
);
}
}
abstract class DemoItem
{
public bool isExpanded { get; set; }
internal ExpansionPanelHeaderBuilder headerBuilder { get; }
internal abstract Widget build();
}
class DemoItem<T> : DemoItem {
public DemoItem(
string name = null,
T value = default,
string hint = null,
DemoItemBodyBuilder builder = null,
ValueToString<T> valueToString = null
) {
textController = new TextEditingController(text: valueToString(value));
this.name = name;
this.value = value;
this.hint = hint;
this.builder = builder;
this.valueToString = valueToString;
}
public readonly string name;
public readonly string hint;
public readonly TextEditingController textController;
public readonly DemoItemBodyBuilder builder;
public readonly ValueToString<T> valueToString;
internal T value;
bool _isExpanded = false;
public new bool isExpanded
{
get { return this._isExpanded; }
set { this._isExpanded = value; }
}
internal new ExpansionPanelHeaderBuilder headerBuilder {
get
{
return (BuildContext context, bool isExpanded) => {
return new DualHeaderWithHint(
name: name,
value: valueToString(value),
hint: hint,
showHint: isExpanded
);
};
}
}
internal override Widget build() => builder(this);
}
class ExpansionPanelsDemo : StatefulWidget {
public static readonly string routeName = "/material/expansion_panels";
public override State createState() => new _ExpansionPanelsDemoState();
}
class _ExpansionPanelsDemoState : State<ExpansionPanelsDemo> {
List<DemoItem> _demoItems;
public override void initState() {
base.initState();
_demoItems = new List<DemoItem>
{
new DemoItem<string>(
name: "Trip",
value: "Caribbean cruise",
hint: "Change trip name",
valueToString: (string value) => value,
builder: (DemoItem _item) =>
{
var item = (DemoItem<string>) _item;
void close()
{
setState(() => { item.isExpanded = false; });
}
return new Form(
child: new Builder(
builder: (BuildContext subContext) =>
{
return new CollapsibleBody(
margin: EdgeInsets.symmetric(horizontal: 16.0f),
onSave: () =>
{
Form.of(subContext).save();
close();
},
onCancel: () =>
{
Form.of(subContext).reset();
close();
},
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0f),
child: new TextFormField(
controller: item.textController,
decoration: new InputDecoration(
hintText: item.hint,
labelText: item.name
),
onSaved: (string value) => { item.value = value; }
)
)
);
}
)
);
}
),
new DemoItem<Location>(
name: "Location",
value: Location.Bahamas,
hint: "Select location",
valueToString: (Location location) => location.ToString(),
builder: (DemoItem _item) =>
{
var item = (DemoItem<Location>) _item;
void close()
{
setState(() => { item.isExpanded = false; });
}
return new Form(
child: new Builder(
builder: (BuildContext subContext) =>
{
return new CollapsibleBody(
onSave: () =>
{
Form.of(subContext).save();
close();
},
onCancel: () =>
{
Form.of(subContext).reset();
close();
},
child: new FormField<Location>(
initialValue: item.value,
onSaved: (Location result) => { item.value = result; },
builder: (FormFieldState<Location> field) =>
{
return new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget>
{
new RadioListTile<Location>(
value: Location.Bahamas,
title: new Text("Bahamas"),
groupValue: field.value,
onChanged: field.didChange
),
new RadioListTile<Location>(
value: Location.Barbados,
title: new Text("Barbados"),
groupValue: field.value,
onChanged: field.didChange
),
new RadioListTile<Location>(
value: Location.Bermuda,
title: new Text("Bermuda"),
groupValue: field.value,
onChanged: field.didChange
)
}
);
}
)
);
}
)
);
}
),
new DemoItem<float>(
name: "Sun",
value: 80.0f,
hint: "Select sun level",
valueToString: (float amount) => $"{amount.round()}",
builder: (DemoItem _item) =>
{
var item = (DemoItem<float>) _item;
void close()
{
setState(() => { item.isExpanded = false; });
}
return new Form(
child: new Builder(
builder: (BuildContext subContext) =>
{
return new CollapsibleBody(
onSave: () =>
{
Form.of(subContext).save();
close();
},
onCancel: () =>
{
Form.of(subContext).reset();
close();
},
child: new FormField<float>(
initialValue: item.value,
onSaved: (float value) => { item.value = value; },
builder: (FormFieldState<float> field) =>
{
return new Container(
// Allow room for the value indicator.
padding: EdgeInsets.only(top: 44.0f),
child: new Slider(
min: 0.0f,
max: 100.0f,
divisions: 5,
activeColor: Colors.orange[(uint) (100 + (field.value * 5.0f).round())],
label: $"{field.value.round()}",
value: field.value,
onChanged: field.didChange
)
);
}
)
);
}
)
);
}
)
};
}
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Expansion panels"),
actions: new List<Widget>{
new MaterialDemoDocumentationButton(ExpansionPanelsDemo.routeName)
}
),
body: new SingleChildScrollView(
child: new SafeArea(
top: false,
bottom: false,
child: new Container(
margin: EdgeInsets.all(24.0f),
child: new ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) => {
setState(() => {
_demoItems[index].isExpanded = !isExpanded;
});
},
children: _demoItems.Select<DemoItem, ExpansionPanel>((DemoItem item) => {
return new ExpansionPanel(
isExpanded: item.isExpanded,
headerBuilder: item.headerBuilder,
body: item.build()
);
}).ToList()
)
)
)
)
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/expansion_panels_demo.cs.meta


fileFormatVersion: 2
guid: 92ffe7d5a2974716b862693f3ec80bfb
timeCreated: 1612518641
正在加载...
取消
保存