// 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'; @visibleForTesting enum Location { Barbados, Bahamas, Bermuda } typedef DemoItemBodyBuilder = Widget Function(DemoItem item); typedef ValueToString = String Function(T value); /* * google flutter 详情多个例子地址: * https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/expansion_panels_demo.dart */ class DualHeaderWithHint extends StatelessWidget { const 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 AnimatedCrossFade( firstChild: first, secondChild: second, firstCurve: const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn), secondCurve: const 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) { final ThemeData theme = Theme.of(context); final TextTheme textTheme = theme.textTheme; return Row( children: [ Expanded( flex: 2, child: Container( margin: const EdgeInsets.only(left: 24.0), child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( name, style: textTheme.body1.copyWith(fontSize: 15.0), ), ), ), ), Expanded( flex: 3, child: Container( margin: const EdgeInsets.only(left: 24.0), child: _crossFade( Text(value, style: textTheme.caption.copyWith(fontSize: 15.0)), Text(hint, style: textTheme.caption.copyWith(fontSize: 15.0)), showHint ) ) ) ] ); } } class DemoItem { DemoItem({ this.name, this.value, this.hint, this.builder, this.valueToString }) : textController = TextEditingController(text: valueToString(value)); final String name; final String hint; final TextEditingController textController; final DemoItemBodyBuilder builder; final ValueToString valueToString; T value; bool isExpanded = true; ExpansionPanelHeaderBuilder get headerBuilder { return (BuildContext context, bool isExpanded) { return DualHeaderWithHint( name: name, value: valueToString(value), hint: hint, showHint: isExpanded ); }; } Widget build() => builder(this); } class ExpansionPanelsDemo extends StatefulWidget { // static const String routeName = '/material/expansion_panels'; @override _ExpansionPanelsDemoState createState() => _ExpansionPanelsDemoState(); } class _ExpansionPanelsDemoState extends State { List> _demoItems; @override void initState() { super.initState(); _demoItems = >[ DemoItem( name: 'Location', value: Location.Bahamas, hint: 'Select location', valueToString: (Location location) => location.toString().split('.')[1], builder: (DemoItem item) { return Form( child: Builder( builder: (BuildContext context) { return FormField( initialValue: item.value, onSaved: (Location result) { item.value = result; }, builder: (FormFieldState field) { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ RadioListTile( value: Location.Bahamas, title: const Text('Bahamas'), groupValue: field.value, onChanged: field.didChange, ), RadioListTile( value: Location.Barbados, title: const Text('Barbados'), groupValue: field.value, onChanged: field.didChange, ), RadioListTile( value: Location.Bermuda, title: const Text('Bermuda'), groupValue: field.value, onChanged: field.didChange, ), ] ); } ); } ) ); } ), ]; } @override Widget build(BuildContext context) { return SingleChildScrollView( child: SafeArea( top: false, bottom: false, child: Container( margin: const EdgeInsets.all(24.0), child: ExpansionPanelList( expansionCallback: (int index, bool isExpanded) { setState(() { _demoItems[index].isExpanded = !isExpanded; }); }, children: _demoItems.map((DemoItem item) { return ExpansionPanel( isExpanded: true, headerBuilder: item.headerBuilder, body: item.build() ); }).toList() ), ), ), ); } }