Commit 8fed9d9e authored by Dragoș Tiselice's avatar Dragoș Tiselice Committed by GitHub

Added expansion panels demo to gallery. (#5539)

parent 023b7de1
......@@ -12,6 +12,7 @@ export 'colors_demo.dart';
export 'data_table_demo.dart';
export 'date_picker_demo.dart';
export 'dialog_demo.dart';
export 'expansion_panels_demo.dart';
export 'grid_list_demo.dart';
export 'icons_demo.dart';
export 'leave_behind_demo.dart';
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
enum _Location {
Barbados,
Bahamas,
Bermuda
}
const TextStyle text54 = const TextStyle(
color: Colors.black54,
fontSize: 15.0
);
const TextStyle text87 = const TextStyle(
color: Colors.black87,
fontSize: 15.0
);
typedef Widget DemoItemBodyBuilder(DemoItem<dynamic> item);
typedef String ValueToString<T>(T value);
class DualHeaderWithHint extends StatelessWidget {
DualHeaderWithHint({
this.name,
this.value,
this.hint,
this.showHint
});
final String name;
final String value;
final String hint;
final bool showHint;
Widget _crossFade(Widget first, Widget second, bool isExpanded) {
return new AnimatedCrossFade(
firstChild: first,
secondChild: second,
firstCurve: new Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve: new Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: isExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: const Duration(milliseconds: 200),
);
}
@override
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
new Flexible(
flex: 2,
child: new Container(
margin: const EdgeInsets.only(left: 24.0),
child: new Text(name, style: text87)
)
),
new Flexible(
flex: 3,
child: new Container(
margin: const EdgeInsets.only(left: 24.0),
child: _crossFade(
new Text(value, style: text54),
new Text(hint, style: text54),
showHint
)
)
)
]
);
}
}
class CollapsibleBody extends StatelessWidget {
CollapsibleBody({
this.margin: EdgeInsets.zero,
this.child,
this.onSave,
this.onCancel
});
final EdgeInsets margin;
final Widget child;
final VoidCallback onSave;
final VoidCallback onCancel;
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new Container(
margin: const EdgeInsets.only(
left: 24.0,
right: 24.0,
bottom: 24.0
) - margin,
child: new Center(
child: new DefaultTextStyle(
style: text54,
child: child
)
)
),
new Divider(height: 1.0),
new Container(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Container(
margin: const EdgeInsets.only(right: 8.0),
child: new FlatButton(
onPressed: onCancel,
child: new Text('CANCEL', style: new TextStyle(
color: Colors.black54,
fontSize: 15.0,
fontWeight: FontWeight.w500
))
)
),
new Container(
margin: const EdgeInsets.only(right: 8.0),
child: new FlatButton(
onPressed: onSave,
textTheme: ButtonTextTheme.accent,
child: new Text('SAVE')
)
)
]
)
)
]
);
}
}
class DemoItem<T> {
DemoItem({
this.name,
this.value,
this.hint,
this.builder,
this.valueToString
});
final String name;
final String hint;
final DemoItemBodyBuilder builder;
final ValueToString<T> valueToString;
T value;
bool isExpanded = false;
ExpansionPanelHeaderBuilder get headerBuilder {
return (BuildContext context, bool isExpanded) {
return new DualHeaderWithHint(
name: name,
value: valueToString(value),
hint: hint,
showHint: isExpanded
);
};
}
}
class ExpasionPanelsDemo extends StatefulWidget {
static const String routeName = '/expansion_panels';
@override
_ExpansionPanelsDemoState createState() => new _ExpansionPanelsDemoState();
}
class _ExpansionPanelsDemoState extends State<ExpasionPanelsDemo> {
List<DemoItem<dynamic>> _demoItems;
@override
void initState() {
super.initState();
_demoItems = <DemoItem<dynamic>>[
new DemoItem<String>(
name: 'Trip name',
value: 'Caribbean cruise',
hint: 'Change trip name',
valueToString: (String value) => value,
builder: (DemoItem<String> item) {
void close() {
setState(() {
item.isExpanded = false;
});
}
return new CollapsibleBody(
margin: const EdgeInsets.symmetric(horizontal: 16.0),
child: new Input(
hintText: item.hint,
labelText: item.name,
value: new InputValue(
text: item.value
),
onSubmitted: (InputValue val) {
setState(() {
item.value = val.text;
});
}
),
onSave: close,
onCancel: close
);
}
),
new DemoItem<_Location>(
name: 'Location',
value: _Location.Bahamas,
hint: 'Select location',
valueToString: (_Location location) => location.toString().split(".")[1],
builder: (DemoItem<_Location> item) {
void close() {
setState(() {
item.isExpanded = false;
});
}
void changeLocation(_Location newLocation) {
setState(() {
item.value = newLocation;
});
}
return new CollapsibleBody(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Radio<_Location>(
value: _Location.Bahamas,
groupValue: item.value,
onChanged: changeLocation
),
new Text('Bahamas')
]
),
new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Radio<_Location>(
value: _Location.Barbados,
groupValue: item.value,
onChanged: changeLocation
),
new Text('Barbados')
]
),
new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Radio<_Location>(
value: _Location.Bermuda,
groupValue: item.value,
onChanged: changeLocation
),
new Text('Bermuda')
]
)
]
),
onSave: close,
onCancel: close
);
}
),
new DemoItem<double>(
name: 'Sun amount',
value: 80.0,
hint: 'Select amount of sun',
valueToString: (double amount) => '${amount.round()}',
builder: (DemoItem<double> item) {
void close() {
setState(() {
item.isExpanded = false;
});
}
return new CollapsibleBody(
child: new Slider(
value: item.value,
min: 0.0,
max: 100.0,
divisions: 5,
activeColor: Colors.orange[100 + (item.value * 5.0).round()],
label: '${item.value.round()}',
onChanged: (double value) {
setState(() {
item.value = value;
});
}
),
onSave: close,
onCancel: close
);
}
)
];
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Expansion panels')),
body: new ScrollableViewport(
child: new Container(
margin: const EdgeInsets.all(24.0),
child: new ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
_demoItems[index].isExpanded = !isExpanded;
});
},
children: _demoItems.map((DemoItem<dynamic> item) {
return new ExpansionPanel(
isExpanded: item.isExpanded,
headerBuilder: item.headerBuilder,
body: item.builder(item)
);
}).toList()
)
)
)
);
}
}
......@@ -102,6 +102,12 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
routeName: TwoLevelListDemo.routeName,
buildRoute: (BuildContext context) => new TwoLevelListDemo()
),
new GalleryItem(
title: 'Expansion panels',
subtitle: 'A list of expanding panels',
routeName: ExpasionPanelsDemo.routeName,
buildRoute: (BuildContext context) => new ExpasionPanelsDemo()
),
new GalleryItem(
title: 'Floating action button',
subtitle: 'Demos action button transitions',
......
......@@ -33,6 +33,7 @@ final List<String> demoTitles = <String>[
'Date picker',
'Dialog',
'Expand/collapse list control',
'Expansion panels',
'Floating action button',
'Grid',
'Icons',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment