本文介绍了Flutter-折叠后的ExpileingTile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试选择一个项目后使 ExpansionTile
折叠,但是它不会关闭打开的列表。
I'm trying to get ExpansionTile
to collapse after I choose an item, but it does not close the list that was opened.
我尝试使用 onExpansionChanged
属性,但是我没有成功
I tried to use the onExpansionChanged
property but I did not succeed
解决这个问题?
插入一个gif,表明 ExpansionTile
在选择项目后不会崩溃,并且下面也是
Insert a gif demonstrating that ExpansionTile
does not collapse after choosing an item, and below is also the code used.
import 'package:flutter/material.dart';
void main() {
runApp(new ExpansionTileSample());
}
class ExpansionTileSample extends StatefulWidget {
@override
ExpansionTileSampleState createState() => new ExpansionTileSampleState();
}
class ExpansionTileSampleState extends State<ExpansionTileSample> {
String foos = 'One';
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('ExpansionTile'),
),
body: new ExpansionTile(
title: new Text(this.foos),
backgroundColor: Theme.of(context).accentColor.withOpacity(0.025),
children: <Widget>[
new ListTile(
title: const Text('One'),
onTap: () {
setState(() {
this.foos = 'One';
});
},
),
new ListTile(
title: const Text('Two'),
onTap: () {
setState(() {
this.foos = 'Two';
});
},
),
new ListTile(
title: const Text('Three'),
onTap: () {
setState(() {
this.foos = 'Three';
});
},
),
]
),
),
);
}
}
推荐答案
此处是一个解决方案。我们只需添加扩展
,折叠
和切换
功能即可 ExpansionTile
。
Here is a solution. We just add a expand
, collapse
and toggle
functionality to ExpansionTile
.
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
void main() {
runApp(new ExpansionTileSample());
}
class ExpansionTileSample extends StatefulWidget {
@override
ExpansionTileSampleState createState() => new ExpansionTileSampleState();
}
class ExpansionTileSampleState extends State<ExpansionTileSample> {
final GlobalKey<AppExpansionTileState> expansionTile = new GlobalKey();
String foos = 'One';
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('ExpansionTile'),
),
body: new AppExpansionTile(
key: expansionTile,
title: new Text(this.foos),
backgroundColor: Theme
.of(context)
.accentColor
.withOpacity(0.025),
children: <Widget>[
new ListTile(
title: const Text('One'),
onTap: () {
setState(() {
this.foos = 'One';
expansionTile.currentState.collapse();
});
},
),
new ListTile(
title: const Text('Two'),
onTap: () {
setState(() {
this.foos = 'Two';
expansionTile.currentState.collapse();
});
},
),
new ListTile(
title: const Text('Three'),
onTap: () {
setState(() {
this.foos = 'Three';
expansionTile.currentState.collapse();
});
},
),
]
),
),
);
}
}
// --- Copied and slightly modified version of the ExpansionTile.
const Duration _kExpand = const Duration(milliseconds: 200);
class AppExpansionTile extends StatefulWidget {
const AppExpansionTile({
Key key,
this.leading,
@required this.title,
this.backgroundColor,
this.onExpansionChanged,
this.children: const <Widget>[],
this.trailing,
this.initiallyExpanded: false,
})
: assert(initiallyExpanded != null),
super(key: key);
final Widget leading;
final Widget title;
final ValueChanged<bool> onExpansionChanged;
final List<Widget> children;
final Color backgroundColor;
final Widget trailing;
final bool initiallyExpanded;
@override
AppExpansionTileState createState() => new AppExpansionTileState();
}
class AppExpansionTileState extends State<AppExpansionTile> with SingleTickerProviderStateMixin {
AnimationController _controller;
CurvedAnimation _easeOutAnimation;
CurvedAnimation _easeInAnimation;
ColorTween _borderColor;
ColorTween _headerColor;
ColorTween _iconColor;
ColorTween _backgroundColor;
Animation<double> _iconTurns;
bool _isExpanded = false;
@override
void initState() {
super.initState();
_controller = new AnimationController(duration: _kExpand, vsync: this);
_easeOutAnimation = new CurvedAnimation(parent: _controller, curve: Curves.easeOut);
_easeInAnimation = new CurvedAnimation(parent: _controller, curve: Curves.easeIn);
_borderColor = new ColorTween();
_headerColor = new ColorTween();
_iconColor = new ColorTween();
_iconTurns = new Tween<double>(begin: 0.0, end: 0.5).animate(_easeInAnimation);
_backgroundColor = new ColorTween();
_isExpanded = PageStorage.of(context)?.readState(context) ?? widget.initiallyExpanded;
if (_isExpanded)
_controller.value = 1.0;
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void expand() {
_setExpanded(true);
}
void collapse() {
_setExpanded(false);
}
void toggle() {
_setExpanded(!_isExpanded);
}
void _setExpanded(bool isExpanded) {
if (_isExpanded != isExpanded) {
setState(() {
_isExpanded = isExpanded;
if (_isExpanded)
_controller.forward();
else
_controller.reverse().then<void>((Null value) {
setState(() {
// Rebuild without widget.children.
});
});
PageStorage.of(context)?.writeState(context, _isExpanded);
});
if (widget.onExpansionChanged != null) {
widget.onExpansionChanged(_isExpanded);
}
}
}
Widget _buildChildren(BuildContext context, Widget child) {
final Color borderSideColor = _borderColor.evaluate(_easeOutAnimation) ?? Colors.transparent;
final Color titleColor = _headerColor.evaluate(_easeInAnimation);
return new Container(
decoration: new BoxDecoration(
color: _backgroundColor.evaluate(_easeOutAnimation) ?? Colors.transparent,
border: new Border(
top: new BorderSide(color: borderSideColor),
bottom: new BorderSide(color: borderSideColor),
)
),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconTheme.merge(
data: new IconThemeData(color: _iconColor.evaluate(_easeInAnimation)),
child: new ListTile(
onTap: toggle,
leading: widget.leading,
title: new DefaultTextStyle(
style: Theme
.of(context)
.textTheme
.subhead
.copyWith(color: titleColor),
child: widget.title,
),
trailing: widget.trailing ?? new RotationTransition(
turns: _iconTurns,
child: const Icon(Icons.expand_more),
),
),
),
new ClipRect(
child: new Align(
heightFactor: _easeInAnimation.value,
child: child,
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
_borderColor.end = theme.dividerColor;
_headerColor
..begin = theme.textTheme.subhead.color
..end = theme.accentColor;
_iconColor
..begin = theme.unselectedWidgetColor
..end = theme.accentColor;
_backgroundColor.end = widget.backgroundColor;
final bool closed = !_isExpanded && _controller.isDismissed;
return new AnimatedBuilder(
animation: _controller.view,
builder: _buildChildren,
child: closed ? null : new Column(children: widget.children),
);
}
}
这篇关于Flutter-折叠后的ExpileingTile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!