Comment créer une animation Onbutton pressé. Par exemple, une animation rebondissante comme dans l'application refluctueusement.
4 Réponses :
Quelque chose comme ça devrait le faire:
class AnimatedButton extends StatefulWidget {
@override
_AnimatedButtonState createState() => _AnimatedButtonState();
}
class _AnimatedButtonState extends State<AnimatedButton>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 200),
lowerBound: 0.0,
upperBound: 0.1,
);
_animationController.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
double scale = 1 - _animationController.value;
return GestureDetector(
onTapUp: _onTapUp,
onTapDown: _onTapDown,
child: Transform.scale(
scale: scale,
child: Container(
width: 300,
height: 75,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(38.0),
boxShadow: [
BoxShadow(
color: Colors.black26,
offset: Offset(0.0, 2.0),
blurRadius: 5.0,
spreadRadius: 0.25,
),
],
),
),
),
);
}
void _onTapDown(TapDownDetails details) {
_animationController.forward();
}
void _onTapUp(TapUpDetails details) {
_animationController.reverse();
}
}
Y a-t-il un moyen de le faire avec un floatingyrbutton et l'effet d'altitude spécial?
Essayez celui-ci aussi. Cela pourrait aider :)
import 'package:flutter/material.dart';
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
double _scale;
AnimationController _controller;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: Duration(
milliseconds: 200,
),
lowerBound: 0.0,
upperBound: 0.1,
)..addListener(() {
setState(() {});
});
super.initState();
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
_scale = 1 - _controller.value;
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Tap on the Below Button',style: TextStyle(color: Colors.grey[400],fontSize: 20.0),),
SizedBox(
height: 20.0,
),
Center(
child: GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onLongPressMoveUpdate: _onMove,
child: Transform.scale(
scale: _scale,
child: _animatedButtonUI,
),
),
),
],
),
),
);
}
Widget get _animatedButtonUI => Container(
height: 70,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0),
boxShadow: [
BoxShadow(
color: Color(0x80000000),
blurRadius: 30.0,
offset: Offset(0.0, 5.0),
),
],
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0000FF),
Color(0xFFFF3500),
],
)),
child: Center(
child: Text(
'tap',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
);
void _onTapDown(TapDownDetails details) {
_controller.forward();
}
void _onTapUp(TapUpDetails details) {
_controller.reverse();
}
void _onMove(LongPressMoveUpdateDetails details){
_controller.reverse();
}
}
Les autres solutions utilisent GESTREDETector avec ONTAPUP et ONTAPDOWN. Cependant, ONTAPDOWN a un léger délai lorsque l'utilisateur tapote l'écran et les oblige à maintenir le bouton pour être exploité. Pour résoudre ce problème, utilisez le widget de l'écoute avec Onpoinderdown et OnpoinPerUp à la place.
import 'package:flutter/material.dart';
class BouncingButton extends StatefulWidget {
@override
_BouncingButtonState createState() => _BouncingButtonState();
}
class _BouncingButtonState extends State<BouncingButton>
with SingleTickerProviderStateMixin {
double _scale;
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 100),
lowerBound: 0.0,
upperBound: 0.1,
);
_controller.addListener(() {
setState(() {});
});
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
_scale = 1 - _controller.value;
return Listener(
onPointerDown: (PointerDownEvent event) {
_controller.forward();
},
onPointerUp: (PointerUpEvent event) {
_controller.reverse();
},
child: Transform.scale(
scale: _scale,
child: Container(
height: 180,
color: Colors.blue,
child: const Text("hello"),
),
),
);
}
}
Utilisez cette classe widget pour la même chose si vous souhaitez le faire désactiver l'animation, faites-la en train de le faire désactiver, puis faites-la tifimer NULL et de passer votre enfant.
Bouncing(
onPress: (){},
child: Container()
);