Dar*_*arz 7 dart flutter flutter-layout
当用户使用动画点击不同的小部件(兄弟或父级)时,如何展开和折叠小部件?
new Column(
children: <Widget>[
new header.IngridientHeader(
new Icon(
Icons.fiber_manual_record,
color: AppColors.primaryColor
),
'Voice Track 1'
),
new Grid()
],
)
Run Code Online (Sandbox Code Playgroud)
我希望用户能够点击header.IngridientHeader然后Grid小部件应该切换(隐藏,如果可见和其他方式)
编辑:
我试图做一些在引导程序中称为崩溃的东西.getbootstrap.com/docs/4.0/components/collapse
编辑2:header.IngridientHeader应始终保持原位Grid()是可滚动(水平)小部件.
Ada*_*son 21
如果你想折叠小部件零高度,或者有一个孩子倒塌溢出的时候,我会建议零宽度SizeTransition或ScaleTransition。
这是ScaleTransition小部件用于折叠四个黑色按钮和状态文本的容器的示例。我的ExpandedSection小部件与一列一起使用,以获取以下结构。

一个将动画与SizeTransition小部件一起使用的小部件的示例:
class ExpandedSection extends StatefulWidget {
final Widget child;
final bool expand;
ExpandedSection({this.expand = false, this.child});
@override
_ExpandedSectionState createState() => _ExpandedSectionState();
}
class _ExpandedSectionState extends State<ExpandedSection> with SingleTickerProviderStateMixin {
AnimationController expandController;
Animation<double> animation;
@override
void initState() {
super.initState();
prepareAnimations();
}
///Setting up the animation
void prepareAnimations() {
expandController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 500)
);
Animation curve = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
animation = Tween(begin: 0.0, end: 1.0).animate(curve)
..addListener(() {
setState(() {
});
}
);
}
@override
void didUpdateWidget(ExpandedSection oldWidget) {
super.didUpdateWidget(oldWidget);
if(widget.expand) {
expandController.forward();
}
else {
expandController.reverse();
}
}
@override
void dispose() {
expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizeTransition(
axisAlignment: 1.0,
sizeFactor: animation,
child: widget.child
);
}
}
Run Code Online (Sandbox Code Playgroud)
AnimatedContainer也可以工作,但是如果不能将孩子的大小调整为零宽度或零高度,Flutter可能会抱怨溢出。
Hem*_*Raj 11
我认为您正在寻找ExpansionTile小部件。这需要一个title与标题和children属性等效的属性,您可以将要在切换时显示或隐藏的小部件传递给该属性。您可以在此处找到如何使用它的示例。
简单示例用法:
new ExpansionTile(title: new Text("Numbers"),
children: <Widget>[
new Text("Number: 1"),
new Text("Number: 2"),
new Text("Number: 3"),
new Text("Number: 4"),
new Text("Number: 5")
],
),
Run Code Online (Sandbox Code Playgroud)
希望有帮助!
或者,您可以使用AnimatedContainer模仿此行为.
class AnimateContentExample extends StatefulWidget {
@override
_AnimateContentExampleState createState() => new _AnimateContentExampleState();
}
class _AnimateContentExampleState extends State<AnimateContentExample> {
double _animatedHeight = 100.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("Animate Content"),),
body: new Column(
children: <Widget>[
new Card(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new GestureDetector(
onTap: ()=>setState((){
_animatedHeight!=0.0?_animatedHeight=0.0:_animatedHeight=100.0;}),
child: new Container(
child: new Text("CLICK ME"),
color: Colors.blueAccent,
height: 25.0,
width: 100.0,
),),
new AnimatedContainer(duration: const Duration(milliseconds: 120),
child: new Text("Toggle Me"),
height: _animatedHeight,
color: Colors.tealAccent,
width: 100.0,
)
],
) ,
)
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
代码:
class FooPageState extends State<SoPage> {
static const _duration = Duration(seconds: 1);
int _flex1 = 1, _flex2 = 2, _flex3 = 1;
@override
Widget build(BuildContext context) {
final total = _flex1 + _flex2 + _flex3;
final height = MediaQuery.of(context).size.height;
final height1 = (height * _flex1) / total;
final height2 = (height * _flex2) / total;
final height3 = (height * _flex3) / total;
return Scaffold(
body: Column(
children: [
AnimatedContainer(
height: height1,
duration: _duration,
color: Colors.red,
),
AnimatedContainer(
height: height2,
duration: _duration,
color: Colors.green,
),
AnimatedContainer(
height: height3,
duration: _duration,
color: Colors.blue,
),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
另一个不需要动画控制器的解决方案是使用AnimatedSwitcher小部件SizeTransition作为过渡构建器。
这是一个简单的例子:
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
transitionBuilder: (child, animation) {
return SizeTransition(sizeFactor: animation, child: child);
},
child: expanded ? YourWidget() : null,
)
Run Code Online (Sandbox Code Playgroud)
当然,您可以自定义动画的曲线和布局构建器。
小智 5
感谢@Adam Jonsson,他的回答解决了我的问题。这是关于如何使用ExpandedSection 的演示,希望对您有所帮助。
class ExpandedSection extends StatefulWidget {
final Widget child;
final bool expand;
ExpandedSection({this.expand = false, this.child});
@override
_ExpandedSectionState createState() => _ExpandedSectionState();
}
class _ExpandedSectionState extends State<ExpandedSection>
with SingleTickerProviderStateMixin {
AnimationController expandController;
Animation<double> animation;
@override
void initState() {
super.initState();
prepareAnimations();
_runExpandCheck();
}
///Setting up the animation
void prepareAnimations() {
expandController =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
animation = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
}
void _runExpandCheck() {
if (widget.expand) {
expandController.forward();
} else {
expandController.reverse();
}
}
@override
void didUpdateWidget(ExpandedSection oldWidget) {
super.didUpdateWidget(oldWidget);
_runExpandCheck();
}
@override
void dispose() {
expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizeTransition(
axisAlignment: 1.0, sizeFactor: animation, child: widget.child);
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Home(),
),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool _expand = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
Header(
onTap: () {
setState(() {
_expand = !_expand;
});
},
),
ExpandedSection(child: Content(), expand: _expand,)
],
);
}
}
class Header extends StatelessWidget {
final VoidCallback onTap;
Header({@required this.onTap});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
color: Colors.cyan,
height: 100,
width: double.infinity,
child: Center(
child: Text(
'Header -- Tap me to expand!',
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
);
}
}
class Content extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.lightGreen,
height: 400,
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7801 次 |
| 最近记录: |