您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

523 行
19 KiB

using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Material = Unity.UIWidgets.material.Material;
using Rect = Unity.UIWidgets.ui.Rect;
namespace UIWidgetsGallery.gallery {
public class BottomAppBarDemo : StatefulWidget {
public const string routeName = "/material/bottom_app_bar";
public override State createState() {
return new _BottomAppBarDemoState();
}
}
class _BottomAppBarDemoState : State<BottomAppBarDemo> {
static readonly GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
static readonly _ChoiceValue<Widget> kNoFab = new _ChoiceValue<Widget>(
title: "None",
label: "do not show a floating action button",
value: null
);
static readonly _ChoiceValue<Widget> kCircularFab = new _ChoiceValue<Widget>(
title: "Circular",
label: "circular floating action button",
value: new FloatingActionButton(
onPressed: _showSnackbar,
child: new Icon(Icons.add),
backgroundColor: Colors.orange
)
);
static readonly _ChoiceValue<Widget> kDiamondFab = new _ChoiceValue<Widget>(
title: "Diamond",
label: "diamond shape floating action button",
value: new _DiamondFab(
onPressed: _showSnackbar,
child: new Icon(Icons.add)
)
);
static readonly _ChoiceValue<bool> kShowNotchTrue = new _ChoiceValue<bool>(
title: "On",
label: "show bottom appbar notch",
value: true
);
static readonly _ChoiceValue<bool> kShowNotchFalse = new _ChoiceValue<bool>(
title: "Off",
label: "do not show bottom appbar notch",
value: false
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabEndDocked =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Attached - End",
label: "floating action button is docked at the end of the bottom app bar",
value: FloatingActionButtonLocation.endDocked
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabCenterDocked =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Attached - Center",
label: "floating action button is docked at the center of the bottom app bar",
value: FloatingActionButtonLocation.centerDocked
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabEndFloat =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Free - End",
label: "floating action button floats above the end of the bottom app bar",
value: FloatingActionButtonLocation.endFloat
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabCenterFloat =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Free - Center",
label: "floating action button is floats above the center of the bottom app bar",
value: FloatingActionButtonLocation.centerFloat
);
static void _showSnackbar() {
const string text =
"When the Scaffold's floating action button location changes, " +
"the floating action button animates to its new position." +
"The BottomAppBar adapts its shape appropriately.";
_scaffoldKey.currentState.showSnackBar(
new SnackBar(content: new Text(text))
);
}
static readonly List<_NamedColor> kBabColors = new List<_NamedColor> {
new _NamedColor(null, "Clear"),
new _NamedColor(new Color(0xFFFFC100), "Orange"),
new _NamedColor(new Color(0xFF91FAFF), "Light Blue"),
new _NamedColor(new Color(0xFF00D1FF), "Cyan"),
new _NamedColor(new Color(0xFF00BCFF), "Cerulean"),
new _NamedColor(new Color(0xFF009BEE), "Blue")
};
_ChoiceValue<Widget> _fabShape = kCircularFab;
_ChoiceValue<bool> _showNotch = kShowNotchTrue;
_ChoiceValue<FloatingActionButtonLocation> _fabLocation = kFabEndDocked;
Color _babColor = kBabColors.First().color;
void _onShowNotchChanged(_ChoiceValue<bool> value) {
this.setState(() => { this._showNotch = value; });
}
void _onFabShapeChanged(_ChoiceValue<Widget> value) {
this.setState(() => { this._fabShape = value; });
}
void _onFabLocationChanged(_ChoiceValue<FloatingActionButtonLocation> value) {
this.setState(() => { this._fabLocation = value; });
}
void _onBabColorChanged(Color value) {
this.setState(() => { this._babColor = value; });
}
public override Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text("Bottom app bar"),
elevation: 0.0f,
actions: new List<Widget> {
new MaterialDemoDocumentationButton(BottomAppBarDemo.routeName),
new IconButton(
icon: new Icon(Icons.sentiment_very_satisfied),
onPressed: () => {
this.setState(() => {
this._fabShape = this._fabShape == kCircularFab ? kDiamondFab : kCircularFab;
});
}
)
}
),
body: new ListView(
padding: EdgeInsets.only(bottom: 88.0f),
children: new List<Widget> {
new _AppBarDemoHeading("FAB Shape"),
new _RadioItem<Widget>(kCircularFab, this._fabShape, this._onFabShapeChanged),
new _RadioItem<Widget>(kDiamondFab, this._fabShape, this._onFabShapeChanged),
new _RadioItem<Widget>(kNoFab, this._fabShape, this._onFabShapeChanged),
new Divider(),
new _AppBarDemoHeading("Notch"),
new _RadioItem<bool>(kShowNotchTrue, this._showNotch, this._onShowNotchChanged),
new _RadioItem<bool>(kShowNotchFalse, this._showNotch, this._onShowNotchChanged),
new Divider(),
new _AppBarDemoHeading("FAB Position"),
new _RadioItem<FloatingActionButtonLocation>(kFabEndDocked, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabCenterDocked, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabEndFloat, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabCenterFloat, this._fabLocation,
this._onFabLocationChanged),
new Divider(),
new _AppBarDemoHeading("App bar color"),
new _ColorsItem(kBabColors, this._babColor, this._onBabColorChanged)
}
),
floatingActionButton:
this._fabShape.value,
floatingActionButtonLocation:
this._fabLocation.value,
bottomNavigationBar: new _DemoBottomAppBar(
color: this._babColor,
fabLocation: this._fabLocation.value,
shape: this._selectNotch()
)
);
}
NotchedShape _selectNotch() {
if (!this._showNotch.value) {
return null;
}
if (this._fabShape == kCircularFab) {
return new CircularNotchedRectangle();
}
if (this._fabShape == kDiamondFab) {
return new _DiamondNotchedRectangle();
}
return null;
}
}
class _ChoiceValue<T> {
public _ChoiceValue(T value, string title, string label) {
this.value = value;
this.title = title;
this.label = label;
}
public readonly T value;
public readonly string title;
string label; // For the Semantics widget that contains title
public override string ToString() {
return $"{this.GetType()}('{this.title}')";
}
}
class _RadioItem<T> : StatelessWidget {
public _RadioItem(_ChoiceValue<T> value, _ChoiceValue<T> groupValue, ValueChanged<_ChoiceValue<T>> onChanged) {
this.value = value;
this.groupValue = groupValue;
this.onChanged = onChanged;
}
_ChoiceValue<T> value;
_ChoiceValue<T> groupValue;
ValueChanged<_ChoiceValue<T>> onChanged;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Container(
height: 56.0f,
padding: EdgeInsets.only(left: 16.0f),
alignment: Alignment.centerLeft,
child: new Row(
children: new List<Widget> {
new Radio<_ChoiceValue<T>>(
value: this.value,
groupValue: this.groupValue,
onChanged: this.onChanged
),
new Expanded(
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => { this.onChanged(this.value); },
child: new Text(this.value.title,
style: theme.textTheme.subhead
)
)
)
}
)
);
}
}
class _NamedColor {
public _NamedColor(Color color, string name) {
this.color = color;
this.name = name;
}
public readonly Color color;
public readonly string name;
}
class _ColorsItem : StatelessWidget {
public _ColorsItem(List<_NamedColor> colors, Color selectedColor, ValueChanged<Color> onChanged) {
this.colors = colors;
this.selectedColor = selectedColor;
this.onChanged = onChanged;
}
List<_NamedColor> colors;
public readonly Color selectedColor;
ValueChanged<Color> onChanged;
public override Widget build(BuildContext context) {
return new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: this.colors.Select<_NamedColor, Widget>((_NamedColor namedColor) => {
return new RawMaterialButton(
onPressed: () => { this.onChanged(namedColor.color); },
constraints: BoxConstraints.tightFor(
width: 32.0f,
height: 32.0f
),
fillColor: namedColor.color,
shape: new CircleBorder(
side: new BorderSide(
color: namedColor.color == this.selectedColor ? Colors.black : new Color(0xFFD5D7DA),
width: 2.0f
)
)
);
}).ToList()
);
}
}
class _AppBarDemoHeading : StatelessWidget {
public _AppBarDemoHeading(string text) {
this.text = text;
}
public readonly string text;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Container(
height: 48.0f,
padding: EdgeInsets.only(left: 56.0f),
alignment: Alignment.centerLeft,
child: new Text(this.text,
style: theme.textTheme.body1.copyWith(
color: theme.primaryColor
)
)
);
}
}
class _DemoBottomAppBar : StatelessWidget {
public _DemoBottomAppBar(
Color color = null,
FloatingActionButtonLocation fabLocation = null,
NotchedShape shape = null
) {
this.color = color;
this.fabLocation = fabLocation;
this.shape = shape;
}
public readonly Color color;
public readonly FloatingActionButtonLocation fabLocation;
public readonly NotchedShape shape;
static readonly List<FloatingActionButtonLocation> kCenterLocations = new List<FloatingActionButtonLocation> {
FloatingActionButtonLocation.centerDocked,
FloatingActionButtonLocation.centerFloat
};
public override Widget build(BuildContext context) {
List<Widget> rowContents = new List<Widget> {
new IconButton(
icon: new Icon(Icons.menu),
onPressed: () => {
BottomSheetUtils.showModalBottomSheet<object>(
context: context,
builder: (BuildContext _context) => new _DemoDrawer()
);
}
)
};
if (kCenterLocations.Contains(this.fabLocation)) {
rowContents.Add(
new Expanded(child: new SizedBox())
);
}
rowContents.AddRange(new List<Widget> {
new IconButton(
icon: new Icon(Icons.search),
onPressed: () => {
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("This is a dummy search action."))
);
}
),
new IconButton(
icon: new Icon(
Theme.of(context).platform == RuntimePlatform.Android
? Icons.more_vert
: Icons.more_horiz
),
onPressed: () => {
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("This is a dummy menu action."))
);
}
)
});
return new BottomAppBar(
color: this.color,
child: new Row(children: rowContents),
shape: this.shape
);
}
}
class _DemoDrawer : StatelessWidget {
public _DemoDrawer() {
}
public override Widget build(BuildContext context) {
return new Drawer(
child: new Column(
children: new List<Widget> {
new ListTile(
leading: new Icon(Icons.search),
title: new Text("Search")
),
new ListTile(
leading: new Icon(Icons.threed_rotation),
title: new Text("3D")
)
}
)
);
}
}
class _DiamondFab : StatelessWidget {
public _DiamondFab(
Widget child,
VoidCallback onPressed
) {
this.child = child;
this.onPressed = onPressed;
}
public readonly Widget child;
public readonly VoidCallback onPressed;
public override Widget build(BuildContext context) {
return new Material(
shape: new _DiamondBorder(),
color: Colors.orange,
child: new InkWell(
onTap: this.onPressed == null ? (GestureTapCallback) null : () => { this.onPressed(); },
child: new Container(
width: 56.0f,
height: 56.0f,
child: IconTheme.merge(
data: new IconThemeData(color: Theme.of(context).accentIconTheme.color),
child: this.child
)
)
),
elevation: 6.0f
);
}
}
class _DiamondNotchedRectangle : NotchedShape {
public _DiamondNotchedRectangle() {
}
public override Path getOuterPath(Rect host, Rect guest) {
if (!host.overlaps(guest)) {
Path path = new Path();
path.addRect(host);
return path;
}
D.assert(guest.width > 0.0f);
Rect intersection = guest.intersect(host);
float notchToCenter =
intersection.height * (guest.height / 2.0f)
/ (guest.width / 2.0f);
Path ret = new Path();
ret.moveTo(host.left, host.top);
ret.lineTo(guest.center.dx - notchToCenter, host.top);
ret.lineTo(guest.left + guest.width / 2.0f, guest.bottom);
ret.lineTo(guest.center.dx + notchToCenter, host.top);
ret.lineTo(host.right, host.top);
ret.lineTo(host.right, host.bottom);
ret.lineTo(host.left, host.bottom);
ret.close();
return ret;
}
}
class _DiamondBorder : ShapeBorder {
public _DiamondBorder() {
}
public override EdgeInsets dimensions {
get { return EdgeInsets.only(); }
}
public override Path getInnerPath(Rect rect) {
return this.getOuterPath(rect);
}
public override Path getOuterPath(Rect rect) {
Path path = new Path();
path.moveTo(rect.left + rect.width / 2.0f, rect.top);
path.lineTo(rect.right, rect.top + rect.height / 2.0f);
path.lineTo(rect.left + rect.width / 2.0f, rect.bottom);
path.lineTo(rect.left, rect.top + rect.height / 2.0f);
path.close();
return path;
}
public override void paint(Canvas canvas, Rect rect) {
}
public override ShapeBorder scale(float t) {
return null;
}
}
}