Comment puis-je développer et réduire le widget lorsque l'utilisateur appuie sur un widget différent (frère ou parent) avec une animation?
new Column(
children: <Widget>[
new header.IngridientHeader(
new Icon(
Icons.fiber_manual_record,
color: AppColors.primaryColor
),
'Voice Track 1'
),
new Grid()
],
)
Je veux que l'utilisateur puisse appuyer sur l'en-tête.IngridientHeader, puis le widget Grid doit basculer (masquer s'il est visible et inversement)
éditer:
im essayant de faire quelque chose qui dans bootstrap s'appelle Collapse. getbootstrap.com/docs/4.0/components/collapse
edit 2: header.IngridientHeader devrait rester en place tout le temps que le widget Grid () est déroulant (horizontal).
Si vous souhaitez réduire un widget à une hauteur ou une largeur nulle qui a un enfant qui déborde lorsqu'il est réduit, je recommanderais SizeTransition ou ScaleTransition .
Voici un exemple du widget ScaleTransition utilisé pour réduire le conteneur pour les quatre boutons noirs et le texte d'état. Mon widget ExpandedSection est utilisé avec une colonne pour obtenir la structure suivante.
Un exemple de widget qui utilise une animation avec le widget 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
);
}
}
AnimatedContainer fonctionne également mais Flutter peut se plaindre d'un débordement si l'enfant n'est pas redimensionnable à une largeur ou une hauteur zéro.
Alternativement, vous pouvez simplement utiliser un AnimatedContainer
pour imiter ce comportement.
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,
)
],
) ,
)
],
),
);
}
}
Je pense que vous cherchez ExpansionTile
widget. Cela prend une propriété title
qui est équivalente à l'en-tête et à la propriété children
à laquelle vous pouvez passer des widgets à afficher ou masquer lors de la bascule. Vous pouvez trouver un exemple de la façon de l'utiliser ici .
Exemple d'utilisation simple:
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")
],
),
J'espère que cela pourra aider!
Sortie:
Code:
class _HomePageState extends State<HomePage> {
Duration _duration = Duration(seconds: 1);
int _flex1 = 1, _flex2 = 1, _flex3 = 1;
@override
Widget build(BuildContext context) {
var data = MediaQuery.of(context);
double height = data.size.height - data.padding.top - kToolbarHeight;
var height1 = (_flex1 * height) / (_flex1 + _flex2 + _flex3);
var height2 = (_flex2 * height) / (_flex1 + _flex2 + _flex3);
var height3 = (_flex3 * height) / (_flex1 + _flex2 + _flex3);
return Scaffold(
appBar: AppBar(
title: Text("Awesome Effect"),
),
body: Column(
children: <Widget>[
AnimatedContainer(
duration: _duration,
color: Colors.blue,
height: height1,
alignment: Alignment.center,
child: Text("Flex: ${_flex1}", style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold)),
),
AnimatedContainer(
duration: _duration,
color: Colors.red,
height: height2,
alignment: Alignment.center,
child: Text("Flex: ${_flex2}", style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold)),
),
AnimatedContainer(
duration: _duration,
color: Colors.teal,
height: height3,
alignment: Alignment.center,
child: Text("Flex: ${_flex3}", style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold)),
),
],
),
);
}
}