Flutter自定义折叠组件
一、基础组件
-
import 'package:flutter/material.dart';
-
-
const Duration _kExpand = Duration(milliseconds: 200);
-
-
/* 折叠组件 */
-
class ExpansionCustom extends StatefulWidget {
-
const ExpansionCustom({
-
Key key,
-
this.title,
-
this.onExpansionChanged,
-
this.children = const <Widget>[],
-
this.initiallyExpanded = false,
-
this.isExpanded,
-
this.padding,
-
}) : assert(initiallyExpanded != null),
-
super(key: key);
-
-
final Widget title;
-
final ValueChanged<bool> onExpansionChanged;
-
final List<Widget> children;
-
final bool initiallyExpanded;
-
final bool isExpanded;
-
final EdgeInsetsGeometry padding;
-
-
-
_ExpansionCustomState createState() => _ExpansionCustomState();
-
}
-
-
class _ExpansionCustomState extends State<ExpansionCustom>
-
with SingleTickerProviderStateMixin {
-
static final Animatable<double> _easeInTween =
-
CurveTween(curve: Curves.easeIn);
-
-
AnimationController _controller;
-
Animation<double> _heightFactor;
-
-
bool _isExpanded = false;
-
-
-
void initState() {
-
super.initState();
-
_controller = AnimationController(duration: _kExpand, vsync: this);
-
_heightFactor = _controller.drive(_easeInTween);
-
-
_isExpanded =
-
PageStorage.of(context)?.readState(context) ?? widget.initiallyExpanded;
-
if (_isExpanded) _controller.value = 1.0;
-
}
-
-
diyHandle() {
-
if (widget.isExpanded != null) {
-
setState(() {
-
if (widget.isExpanded) {
-
_controller.forward();
-
} else {
-
_controller.reverse().then<void>((void value) {
-
if (!mounted) return;
-
setState(() {});
-
});
-
}
-
});
-
}
-
}
-
-
-
void dispose() {
-
_controller.dispose();
-
super.dispose();
-
}
-
-
void _handleTap() {
-
setState(() {
-
_isExpanded = !_isExpanded;
-
if (_isExpanded) {
-
_controller.forward();
-
} else {
-
_controller.reverse().then<void>((void value) {
-
if (!mounted) return;
-
setState(() {});
-
});
-
}
-
PageStorage.of(context)?.writeState(context, _isExpanded);
-
});
-
if (widget.onExpansionChanged != null)
-
widget.onExpansionChanged(_isExpanded);
-
}
-
-
Widget _buildChildren(BuildContext context, Widget child) {
-
return Container(
-
child: Column(
-
mainAxisSize: MainAxisSize.min,
-
children: <Widget>[
-
GestureDetector(
-
onTap: _handleTap,
-
child: Container(
-
color: Colors.transparent,
-
width: double.infinity,
-
padding: widget.padding ?? EdgeInsets.only(left: 10, right: 10),
-
child: widget.title ?? Container(),
-
),
-
),
-
ClipRect(
-
child: Align(
-
heightFactor: _heightFactor.value,
-
child: child,
-
),
-
),
-
],
-
),
-
);
-
}
-
-
-
Widget build(BuildContext context) {
-
diyHandle();
-
final bool closed = !_isExpanded && _controller.isDismissed;
-
return AnimatedBuilder(
-
animation: _controller.view,
-
builder: _buildChildren,
-
child: closed ? null : Column(children: widget.children),
-
);
-
}
-
}
二、拓展组件
对基础组件加以封装,可以实现更多功能的拓展组件,本文以折叠卡片和折叠信息为例。
折叠卡片
-
import 'package:flutter/material.dart';
-
import './expansion_custom.dart';
-
-
/* 折叠卡片 */
-
class ExpansionCard extends StatefulWidget {
-
final EdgeInsets margin; // 外边距
-
final Decoration cardDecoration; // 卡片样式
-
final Function onTap; // 点击标题的回调
-
final String tlText; // 左侧标题
-
final TextStyle tlStyle;
-
final Widget tlWidget;
-
final String trText; // 右侧标题
-
final TextStyle trStyle;
-
final Widget trWidget;
-
final List<Widget> contentWidget; // 折叠内容
-
-
ExpansionCard({
-
Key key,
-
this.margin,
-
this.cardDecoration,
-
this.onTap,
-
this.tlText,
-
this.tlStyle,
-
this.tlWidget,
-
this.trText,
-
this.trStyle,
-
this.trWidget,
-
this.contentWidget,
-
}) : super(key: key);
-
-
-
_ExpansionCardState createState() => _ExpansionCardState();
-
}
-
-
class _ExpansionCardState extends State<ExpansionCard> {
-
bool _isExpanded = false;
-
-
-
Widget build(BuildContext context) {
-
return Container(
-
margin: widget.margin ?? EdgeInsets.all(10),
-
padding: EdgeInsets.all(10),
-
decoration: widget.cardDecoration ??
-
BoxDecoration(
-
color: Colors.white,
-
borderRadius: BorderRadius.all(Radius.circular(10)),
-
),
-
child: Column(
-
children: <Widget>[
-
GestureDetector(
-
onTap: () {
-
this._isExpanded = !this._isExpanded;
-
if (mounted) {
-
setState(() {});
-
}
-
-
if (widget.onTap != null) {
-
widget.onTap(this._isExpanded);
-
}
-
},
-
child: Container(
-
color: Colors.transparent,
-
child: Row(
-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
-
children: <Widget>[
-
widget.tlWidget ??
-
Text(
-
'${widget.tlText ?? ""}',
-
style: widget.tlStyle ??
-
TextStyle(
-
fontSize: 16, fontWeight: FontWeight.bold),
-
),
-
Row(
-
children: <Widget>[
-
widget.trWidget ??
-
Text('${widget.trText ?? ""}',
-
style: widget.trStyle ??
-
TextStyle(
-
fontSize: 16,
-
fontWeight: FontWeight.bold)),
-
SizedBox(width: 4),
-
Icon(
-
this._isExpanded ? Icons.remove : Icons.add,
-
color: Colors.black,
-
size: 18,
-
),
-
],
-
)
-
],
-
),
-
),
-
),
-
ExpansionCustom(
-
children: <Widget>[
-
Divider(height: 10),
-
Column(
-
children: widget.contentWidget ?? [Container()],
-
)
-
],
-
initiallyExpanded: false,
-
isExpanded: this._isExpanded,
-
)
-
],
-
),
-
);
-
}
-
}
折叠信息
-
import 'package:flutter/material.dart';
-
import './expansion_custom.dart';
-
-
/* 折叠消息 */
-
class ExpansionMsg extends StatefulWidget {
-
final double width; //宽
-
final Color bgColor; //背景颜色
-
final Widget icon;//左侧icon
-
final String msgText; //文字提示
-
final TextStyle msgTextStyle; //文字提示样式
-
final Function onClose; //点击关闭时的回调
-
ExpansionMsg(
-
{Key key,
-
this.width,
-
this.bgColor,
-
this.icon,
-
this.msgText,
-
this.msgTextStyle,
-
this.onClose})
-
: super(key: key);
-
-
-
_ExpansionMsgState createState() => _ExpansionMsgState();
-
}
-
-
class _ExpansionMsgState extends State<ExpansionMsg> {
-
bool _showContent = true;
-
-
-
Widget build(BuildContext context) {
-
return ExpansionCustom(
-
title: Container(),
-
initiallyExpanded: true, //默认是否展开
-
isExpanded: this._showContent,
-
children: <Widget>[
-
MessageBox(
-
width: widget.width,
-
bgColor: widget.bgColor,
-
msgTextStyle: widget.msgTextStyle,
-
msgText: widget.msgText,
-
canClose: true,
-
onClose: () {
-
this._showContent = false;
-
-
if (mounted) {
-
setState(() {});
-
}
-
-
if (widget.onClose != null) {
-
widget.onClose();
-
}
-
},
-
),
-
],
-
);
-
}
-
}
-
-
/* 消息盒子 */
-
class MessageBox extends StatelessWidget {
-
final double width;
-
final Color bgColor;
-
final Widget icon;
-
final String msgText;
-
final TextStyle msgTextStyle;
-
final Function onClose;
-
final bool canClose;
-
const MessageBox(
-
{Key key,
-
this.width,
-
this.bgColor,
-
this.icon,
-
this.msgText,
-
this.msgTextStyle,
-
this.onClose,
-
this.canClose = true})
-
: super(key: key);
-
-
-
Widget build(BuildContext context) {
-
return Container(
-
padding: EdgeInsets.only(
-
top: 6,
-
bottom: 6,
-
left: 10,
-
right: 10,
-
),
-
width: width ?? double.infinity,
-
color: bgColor ?? Color.fromRGBO(253, 246, 236, 1),
-
child: Row(
-
crossAxisAlignment: CrossAxisAlignment.start,
-
children: <Widget>[
-
Container(
-
width: 20,
-
margin: EdgeInsets.only(right: 10),
-
child: icon ??
-
Icon(Icons.warning,
-
size: 20, color: Color.fromRGBO(230, 162, 60, 1)),
-
),
-
Expanded(
-
child: Container(
-
child: Text(
-
msgText ??
-
'这是一条消息提示',
-
style: msgTextStyle ??
-
TextStyle(
-
fontSize: 12, color: Color.fromRGBO(230, 162, 60, 1)),
-
),
-
)),
-
canClose
-
? GestureDetector(
-
onTap: onClose,
-
child: Container(
-
color: Colors.transparent,
-
width: 20,
-
height: 20,
-
child: Icon(
-
Icons.close,
-
size: 20,
-
),
-
),
-
)
-
: Container(width: 20)
-
],
-
),
-
);
-
}
-
}
三、组件使用
-
import 'package:flutter/material.dart';
-
import '../../compontents/expansion/expansion_custom.dart';
-
import '../../compontents/expansion/expansion_card.dart';
-
import '../../compontents/expansion/expansion_msg.dart';
-
-
/*组件演示*/
-
class Demo extends StatefulWidget {
-
Demo({Key key}) : super(key: key);
-
-
-
State<Demo> createState() => _DemoState();
-
}
-
-
class _DemoState extends State<Demo> {
-
-
Widget build(BuildContext context) {
-
return Scaffold(
-
appBar: AppBar(
-
title: Text('Demo'),
-
centerTitle: true,
-
),
-
body: Container(
-
child: Wrap(
-
spacing: 20,
-
crossAxisAlignment: WrapCrossAlignment.center,
-
children: <Widget>[
-
SizedBox(height: 10),
-
ExpansionCustom(
-
title: Container(
-
child: Text('标题'), alignment: Alignment.centerLeft),
-
children: <Widget>[Text('内容1'), Text('内容2'), Text('内容3')],
-
),
-
SizedBox(height: 10),
-
ExpansionCard(
-
tlText: '左侧标题',
-
trText: '右侧标题',
-
contentWidget: <Widget>[
-
Text('折叠内容1'),
-
Text('折叠内容2'),
-
Text('折叠内容3'),
-
Text('折叠内容4'),
-
Text('折叠内容5'),
-
],
-
),
-
SizedBox(height: 10),
-
ExpansionMsg(
-
msgText:
-
'这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示这是一条消息提示'),
-
]),
-
));
-
}
-
}
四、效果演示
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbkbeb
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13