Flutter 常见问题解答下拉列表
Dropdown for FAQ for flutter
嘿,谁能告诉我一个与我提供的图像相似的 flutter 小部件或库。
我想要这个作为常见问题解答部分。最初只有问题应该是可见的,点击它应该显示答案的组件。
enter image description here
我会选择 this library,或者如果您愿意,这里是我为自己的目的创建的小部件的片段:
import 'package:flutter/material.dart';
/// [CustomCollapsable] is collapsable widget which shows a [preview]
/// and a trailing with a [trailingText] by default. On tap the trailing or
/// its [trailingText], it animates to show the [child].
/// NOTE: [ExpansionTile] doesn't support layout changes, for example
/// moving trailing down or to hide the [preview] after expand the content.
/// [CustomCollapsable] is inspired on [ExpansionTile] with additional features.
class CustomCollapsable extends StatefulWidget {
/// [Widget] shown when expanded
final Widget child;
/// [Widget] shown only when it is not expanded
final Widget preview;
/// [String] that goes on top of the trailing arrow
final String trailingText;
/// Callback [ValueChanged] function fired after animation
final ValueChanged<bool> onExpansionChanged;
const CustomCollapsable({
Key key,
@required this.preview,
@required this.child,
@required this.trailingText,
this.onExpansionChanged,
});
@override
_CustomCollapsableState createState() => _CustomCollapsableState();
}
class _CustomCollapsableState extends State<CustomCollapsable>
with SingleTickerProviderStateMixin {
static final Animatable<double> _easeInTween = CurveTween(
curve: Curves.easeIn,
);
static final Animatable<double> _halfTween = Tween<double>(
begin: 0.0,
end: 0.5,
);
AnimationController _controller;
Animation<double> _heightFactor;
Animation<double> _iconTurns;
bool _isExpanded = false;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this,
);
_iconTurns = _controller.drive(_halfTween.chain(_easeInTween));
_heightFactor = _controller.drive(_easeInTween);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
bool get isClosed => !_isExpanded && _controller.isDismissed;
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 _buildTralling() {
return GestureDetector(
onTap: _handleTap,
child: Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
isClosed
? Text(widget.trailingText.toUpperCase())
: const SizedBox(),
RotationTransition(
turns: _iconTurns,
child: const Icon(Icons.expand_more),
),
],
),
),
);
}
Widget _buildChild(BuildContext context, Widget child) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// Preview widget is visible only when the parent is closed
isClosed ? widget.preview : const SizedBox(),
ClipRect(
child: Align(
heightFactor: _heightFactor.value,
child: child,
),
),
_buildTralling()
],
);
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller.view,
builder: _buildChild,
child: isClosed ? null : widget.child,
);
}
}
您可以根据需要定义 child
和 preview
小部件。
嘿,谁能告诉我一个与我提供的图像相似的 flutter 小部件或库。 我想要这个作为常见问题解答部分。最初只有问题应该是可见的,点击它应该显示答案的组件。
enter image description here
我会选择 this library,或者如果您愿意,这里是我为自己的目的创建的小部件的片段:
import 'package:flutter/material.dart';
/// [CustomCollapsable] is collapsable widget which shows a [preview]
/// and a trailing with a [trailingText] by default. On tap the trailing or
/// its [trailingText], it animates to show the [child].
/// NOTE: [ExpansionTile] doesn't support layout changes, for example
/// moving trailing down or to hide the [preview] after expand the content.
/// [CustomCollapsable] is inspired on [ExpansionTile] with additional features.
class CustomCollapsable extends StatefulWidget {
/// [Widget] shown when expanded
final Widget child;
/// [Widget] shown only when it is not expanded
final Widget preview;
/// [String] that goes on top of the trailing arrow
final String trailingText;
/// Callback [ValueChanged] function fired after animation
final ValueChanged<bool> onExpansionChanged;
const CustomCollapsable({
Key key,
@required this.preview,
@required this.child,
@required this.trailingText,
this.onExpansionChanged,
});
@override
_CustomCollapsableState createState() => _CustomCollapsableState();
}
class _CustomCollapsableState extends State<CustomCollapsable>
with SingleTickerProviderStateMixin {
static final Animatable<double> _easeInTween = CurveTween(
curve: Curves.easeIn,
);
static final Animatable<double> _halfTween = Tween<double>(
begin: 0.0,
end: 0.5,
);
AnimationController _controller;
Animation<double> _heightFactor;
Animation<double> _iconTurns;
bool _isExpanded = false;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this,
);
_iconTurns = _controller.drive(_halfTween.chain(_easeInTween));
_heightFactor = _controller.drive(_easeInTween);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
bool get isClosed => !_isExpanded && _controller.isDismissed;
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 _buildTralling() {
return GestureDetector(
onTap: _handleTap,
child: Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
isClosed
? Text(widget.trailingText.toUpperCase())
: const SizedBox(),
RotationTransition(
turns: _iconTurns,
child: const Icon(Icons.expand_more),
),
],
),
),
);
}
Widget _buildChild(BuildContext context, Widget child) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// Preview widget is visible only when the parent is closed
isClosed ? widget.preview : const SizedBox(),
ClipRect(
child: Align(
heightFactor: _heightFactor.value,
child: child,
),
),
_buildTralling()
],
);
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller.view,
builder: _buildChild,
child: isClosed ? null : widget.child,
);
}
}
您可以根据需要定义 child
和 preview
小部件。