Flutter rende semplice il menu di Facebook
In Flutterche sto cercando di fare un semplice Facebookmenù, in seguito schermata abbiamo una widget di numero e quando scatto su questo, widget di cui cioè al di sotto del widget di corrente, deve essere ridimensionato e crescere e che mostra un altro icone in quella
questo codice sottostante che ho introdotto funziona bene, ma non ha un contenitore in background
in referenziato il collegamento Columnutilizzato e l'ho cambiato in Stacke non funziona correttamente
riferimento
import 'package:flutter/material.dart';
class FancyFab extends StatefulWidget {
final Function() onPressed;
final String tooltip;
final IconData icon;
FancyFab({this.onPressed, this.tooltip, this.icon});
@override
_FancyFabState createState() => _FancyFabState();
}
class _FancyFabState extends State<FancyFab>
with SingleTickerProviderStateMixin {
bool isOpened = false;
AnimationController _animationController;
Animation<Color> _buttonColor;
Animation<double> _animateIcon;
Animation<double> _translateButton;
Curve _curve = Curves.easeOut;
double _fabHeight = 56.0;
@override
initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 500))
..addListener(() {
setState(() {});
});
_animateIcon =
Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
_buttonColor = ColorTween(
begin: Colors.blue,
end: Colors.red,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.00,
1.00,
curve: Curves.linear,
),
));
_translateButton = Tween<double>(
begin: _fabHeight,
end: -14.0,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
0.75,
curve: _curve,
),
));
super.initState();
}
@override
dispose() {
_animationController.dispose();
super.dispose();
}
animate() {
if (!isOpened) {
_animationController.forward();
} else {
_animationController.reverse();
}
isOpened = !isOpened;
}
Widget add() {
return Container(
child: FloatingActionButton(
onPressed: null,
tooltip: 'Add',
child: Icon(Icons.add),
),
);
}
Widget image() {
return Container(
child: FloatingActionButton(
onPressed: null,
tooltip: 'Image',
child: Icon(Icons.image),
),
);
}
Widget inbox() {
return Container(
child: FloatingActionButton(
onPressed: null,
tooltip: 'Inbox',
child: Icon(Icons.inbox),
),
);
}
Widget toggle() {
return Container(
child: FloatingActionButton(
backgroundColor: _buttonColor.value,
onPressed: animate,
tooltip: 'Toggle',
child: AnimatedIcon(
icon: AnimatedIcons.menu_close,
progress: _animateIcon,
),
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value * 3.0,
0.0,
),
child: add(),
),
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value * 2.0,
0.0,
),
child: image(),
),
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value,
0.0,
),
child: inbox(),
),
toggle(),
],
);
}
}
Voglio usare questo widget in Flutterlistview, che dovrebbe apparire dove ho cliccato, per esempio supponi che io abbia io IconButtonnegli ListViewelementi, quando ci clicco sopra, questo widget dovrebbe apparire nella posizione cliccata e Buttondovrebbe essereFloatingActionButton
Risposte
L'ho implementato usando Stacke AnimatedContainer.
- usando
PositionedinStack, l'ho posizionato in basso. La ragione di ciò è allineare sia ilContainercheFABnella stessa posizione quando è animato. - usando
AnimatedContainer, ho creato una semplice animazione che cambia la sua altezza quandoFABtocchiamo usando il valore bool.
(Aggiungo un contenitore in più nella colonna, si nasconderà dietro FAB e lo allineerà perfettamente, ma puoi aggiungere SizedBox o Container senza colore e mantenere le sue dimensioni come 54.0 alla fine, se non stai usando list.generate)
Prova questo su DartPad
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Container(
width: 250,
height: 250,
color: Colors.white,
child: YellowBird(),
)),
),
);
}
}
class YellowBird extends StatefulWidget {
const YellowBird({Key key}) : super(key: key);
@override
_YellowBirdState createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
bool animate = true;
@override
Widget build(BuildContext context) {
return Stack(
alignment: AlignmentDirectional.topCenter,
children: [
Positioned(
bottom: 0,
child: AnimatedContainer(
width: 54.0,
decoration: BoxDecoration(
color: Colors.redAccent,
borderRadius: BorderRadius.all(Radius.circular(360))
),
height: animate ? 56.0 : 250.0,
duration: Duration(milliseconds: 300),
child: animate
? Container()
: Column(
children: List.generate(
4,
(i) => Expanded(
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
),
),
),
),
),
Positioned(
bottom: 0,
child: FloatingActionButton(
backgroundColor: Colors.grey,
child: Icon(animate ? Icons.menu : Icons.close, size: 30),
onPressed: () {
setState(() {
animate = !animate;
});
})),
]);
}
}
fammi sapere se funziona o c'è qualcosa da cambiare da questo.
ciao per favore guarda questa libreria ... https://pub.dev/packages/flutter_portal questo è il modo più semplice per creare una sovrapposizione in Flutter ...
PortalEntry(
visible: isMenuVisible, //true Or False
portalAnchor: Alignment.topLeft,
childAnchor: Alignment.topRight,
portal: TheMenuWidget, // option 1 + option 2 (White)
child: MyButton, // show Menu Button (Grey)
)