I am trying to achieve a pretty simple animation in Flutter but I am stuck.
The current animation looks like this (iPhone Screen recording): https://drive.google.com/file/d/10pzUadQrSr85eLLpyh7v3lt-x8XjFNec/view?usp=sharing
I am currently doing this with Positioned but I can not do it precisely as I want. Is there any chance that I can do this animation with Align Widget.
I have tried using AnimatedAlign and Tweens but none of them allow me to modify the Images position by scrolling up or down on the bottom sheet.
The Code:
late AnimationController bottomSheetController;
double bsOffset = 1;
@override
void initState() {
super.initState();
bottomSheetController = BottomSheet.createAnimationController(this);
bottomSheetController.duration = Duration(milliseconds: 200);
bottomSheetController.addListener(() {
double size = (bottomSheetController.value.toDouble() - 1) * -1;
setState(() {
if (size != 0) {
bsOffset = size;
}
});
});
}
.
.
.
void _handleFABPressed() {
showModalBottomSheet(
backgroundColor: Colors.transparent,
barrierColor: Colors.transparent,
transitionAnimationController: bottomSheetController,
context: context,
builder: (context) {
return Popover(
child: Container(
height: 400,
// color: Colors.lightBlue,
),
);
},
);
}
.
.
.
child: Stack(
alignment: Alignment.topCenter,
children: [
Positioned(
bottom: 50 - (50 * bsOffset),
left: ((200 / 2) - 20) - (((200 / 2) - 20) * (bsOffset - 1) * -1),
child: Image.asset(
'assets/images/8.png',
width: 200,
),
),
],
),
Thank You!
CodePudding user response:
If I were to move the two widgets, both Align and the bottomsheet, I would do it like this:
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late AnimationController _animationController;
late Animation<Offset> _animationOffset;
var _alignment = Alignment.bottomCenter;
void _show() {
showModalBottomSheet(
backgroundColor: Colors.transparent,
barrierColor: Colors.transparent,
transitionAnimationController: _animationController,
context: context,
builder: (context) {
return Container(
height: 400,
color: Colors.red,
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo Home Page'),
),
body: Stack(
children: [
Align(
alignment: _alignment,
child: const SizedBox(
width: 100, height: 100, child: Card(color: Colors.red)))
],
),
floatingActionButton:
FloatingActionButton(onPressed: _show, child: const Icon(Icons.add)),
);
}
void _onListenerAnimation() {
setState(() {
_alignment =
Alignment(_animationOffset.value.dx, _animationOffset.value.dy);
});
}
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 200))
..addListener(_onListenerAnimation);
_animationOffset = Tween<Offset>(
begin: const Offset(0, 1),
end: const Offset(-1, -0.6),
).animate(_animationController);
}
@override
void dispose() {
super.dispose();
_animationController
..removeListener(_onListenerAnimation)
..dispose();
}
}