slide animation in flutter - flutter

Does anyone have an opinion about handling this animation in flutter?
when u swipe left the front card goes left and left bottom then the behind card size becomes bigger and replace the first card.

I did something similar once. What you want to do is use a GestureDetector and listen to onPanUpdate, add a child with a AnimatedPositioned and if needed a Rotated widget.
You can take a look at this gist which is a class from a hackathon we did.
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) => GestureDetector(
onPanStart: _onPanStart,
onPanEnd: _onPanEnd,
onPanUpdate: _onPanUpdate,
child: Stack(
clipBehavior: Clip.none,
children: [
AnimatedPositioned(
duration: Duration(milliseconds: _duration),
top: _positionY,
left: _positionX,
child: Container(constraints: BoxConstraints(maxHeight: constraints.maxHeight, maxWidth: constraints.maxWidth), child: widget.child))
],
),
),
);
}

I would combine those two:
1 - AnimatedPositioned - to move the widget by some offset
2 - AnimatedRotation - so that you can turn the rotation while it is moving

Related

How to make FAB button location on screen responsive to different screen sizes?

I'm new to flutter and have a problem with FAB button which position has to be fixed for all device sizes. I used example from official documentation but the position is still not responsive for other device sizes and it comes out like this. fab button
Below are two chunks of code which do the location of button. I guess I need to change alignment in the first, and Positioned right and bottom in the second to be responsive. But I have no idea how to do that.
Widget build(BuildContext context) {
return SizedBox.expand(
child: Stack(
alignment: const Alignment(0.63, 0.213),
clipBehavior: Clip.none,
children: [
_buildTapToCloseFab(),
..._buildExpandingActionButtons(),
_buildTapToOpenFab(),
],
),
)},
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: progress,
builder: (context, child) {
final offset = Offset.fromDirection(
directionInDegrees * (math.pi / 170.0),
progress.value * maxDistance,
);
return Positioned(
right: 60 + offset.dx,
bottom: 270 + offset.dy,
child: Transform.rotate(
angle: (1.0 - progress.value) * math.pi / 2,
child: child!,
),
);
},
child: FadeTransition(
opacity: progress,
child: child,
),
);
}

Pick Value onTap in CupertinoPicker and CupertinoDatePicker

onSelectedItemChanged is working perfectly in CupertinoPicker/CupertinoDatePicker
But I also want to pick value when user clicked the value.
Currently, user must scroll in order to pick the value, and as far as I know CupertinoPicker/CupertinoDatePicker doesn't have onTap, onPressed functions
How can I solve this issue
Unfortunately, the gesture detection inside CupertinoPicker/CupertinoDatePicker is not supported for now. When you trace the code inside CupertinoPicker, it leads to use ListWheelScrollView at the end and it does not respond to the tap event.
Discussion thread on GitHub:
Tapping items is not working in CupertinoPicker
ListWheelScrollView children do not respond on gesture (onTap) events
There is a workaround solution by using package clickable_list_wheel_view (fixed height for the child widget, mentioned here)
I found a workaround by using flutter_portal.
final ScrollController scrollController = FixedExtentScrollController();
#override
Widget build(BuildContext context) {
return Container(
height: 100,
child: Portal(
child: CupertinoPicker.builder(
scrollController: scrollController,
childCount: itemCount,
itemBuilder: (context, index) {
return PortalTarget(
anchor: Aligned(
follower: Alignment.center,
target: Alignment.center,
),
portalFollower: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
scrollController.animateToItem(index,
duration: Duration(milliseconds: 250),
curve: Curves.decelerate);
},
),
child: Text(index.toString()),
);
},
),
)
);
}
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => // write what you want to do,
child: CupertinoPicker(),
),

Unable to disable dragable gesture on Spin Wheel in flutter by David Anaya

I am implementing the flutter_spinning_wheel 1.1.0 by David Anaya. I have implemented the spin using button click and I want to disable the default draggable gesture i.e. used to spin the wheel. Can anyone please help me how can I disable the draggable gesture on the spin wheel.
Below is the link for flutter_spinning_wheel 1.1.0 plugin:
https://pub.dev/packages/flutter_spinning_wheel
Fortunately, I found a solution to this by myself.
If we go to the above-mentioned plugin documentation correctly then we will find a Gesture detector in spinning_wheel.dart class.
Open your plugin class (spinning_wheel.dart)
Just commented the below code that I have shared and then rebuild your app again. Your draggable gesture will be disabled. (This is just for those who are seeking to spin the wheel using a button)
class SpinningWheel extends StatefulWidget {
-------
}
class _SpinningWheelState extends State<SpinningWheel>
with SingleTickerProviderStateMixin {
------------
------------
#override
Widget build(BuildContext context) {
return Container(
height: widget.height,
width: widget.width,
child: Stack(
children: [
// GestureDetector(
// onPanUpdate: _moveWheel,
// onPanEnd: _startAnimationOnPanEnd,
// onPanDown: (_details) => _stopAnimation(),
//child:
AnimatedBuilder(
animation: _animation,
child: Container(child: widget.image),
builder: (context, child) {
_updateAnimationValues();
widget.onUpdate(_currentDivider);
return Transform.rotate(
angle: _initialSpinAngle + _currentDistance,
child: child,
);
}),
//),
widget.secondaryImage != null
? Positioned(
top: topSecondaryImage,
left: leftSecondaryImage,
child: Container(
height: heightSecondaryImage,
width: widthSecondaryImage,
child: widget.secondaryImage,
))
: Container(),
],
),
);
}
-----------
-----------
}

Translating a widget isn't smooth

I am using a widget which starts off from the centre of the screen. I want the widget to move from centre to the top and vice-versa as user drags the widget.
I have wrapped my widget with Gesture detector and also with Transform widget whose Y value gets changed as user drags.
I am using value notifier when the Y position changes as user drags. The widget drags as expected.
The problem is that the scroll of the widget is not smooth. I have tried using Animation controller but I am not very sure how that would fit here.
Is there a way I could use scroll animation on my widget so that its smooth?
Below is my widget that I want to translate on drag:
Transform(
transform: Matrix4.translationValues(0, widget.verticalOffset, 0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Container(
color: Theme.of(context).primaryColor,
child: GestureDetector(
onVerticalDragUpdate: widget.handleDragUpdate,
onVerticalDragEnd: _handleVerticalDragEnd,
child: ListView.builder(
controller: controller,
physics: _getScrollPhysics(context),
itemCount: widget.songs.length,
itemBuilder: (BuildContext context, int index) {
return buildSongRow(widget.songs[index]);
}
)
)
),
),
)
If you're running things in debug mode this is a likely result. To make sure your animation is running as smooth as you hope then you'll want to run things in profile mode.

OnPressed not working inside Stack widget after Transforming a widget

In the given code,onPressed on the raised button works and translate FlatButton to the top. But onPressed on FlatButton is not working
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value,
0.0,
),
child: FlatButton(
onPressed: () {
print('tapped Flat button');
},
child: Text('upper'),
),
),
RaisedButton(
onPressed: () {
animate();
print('tapped Raised button');
},
child: Text('lower'))
],
);
}
Here _translatebutton value changes from 0 to -60 when animate() is called
_animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 500))
..addListener(() {
setState(() {});
});
_translateButton = Tween<double>(
begin: 0,
end: -60,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
0.75,
curve: _curve,
),
));
Wrap the Transform widget in a SizedBox (expanded or from size, depending on your requirement.
I came across this problem last week and in my case, the composition was like this:
Stack(
children: [
Widget0,
Widget1,
Opacity(
opacity: sth,
child: Transform.translate(
offset: Offset(sth),
child: Transform.rotate(
angle:sth,
child: FlatButton(
onPressed: (){sth},
child: Text("sth"),
),
),
),
),
],
)
Based on the suggestion of rahulthakur319 on the issue number
27587
I wrapped my Transform.translate composition inside a new Stack and I wrapped the stack inside a Container. Remember that the new Container should have enough width and height to show its child. I personally used MediaQuery.of(context).size.
it's working even during the complex series of animations.
The final code:
Stack(
children: [
Widget0,
Widget1,
Opacity(
opacity: sth,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
children: [
Transform.translate(
offset: Offset(sth),
child: Transform.rotate(
angle: sth,
child: FlatButton(
onPressed: (){sth},
child: Text("sth"),
),
),
),
],
),
),
),
],
)
If your translation moves the button outside the area of the stack, the button no longer reacts to clicks. A simple way to test this is to wrap your Stack widget in a container and color it blue (or anything obvious), and if your button is moved outside the blue area, you know it's losing its clickability because it's outside of the Stack.
If this indeed is the issue, the solution is to keep the Stack inside the container, and then either set the container dimensions such that the button still stays within the border after translation, or reposition widgets relative to the container such that the translation stays within the border.
If someone is still trying to solve this issue, I solved it by wrapping the widget with IgnorePointer widget on which I don't want the pointer to reach.
reference from here
The answer I got was that in a View if an element is translated then the animation works correct but the click property is altered in someway that we can't use it after translating the element
I had this same issue my Switch widget was not working in the Stack.
The solution i found was to include it in SizeBox or Container with fixed width and height.
if your switch widget is in Row try to add Constraints on Row with SizeBox rather than adding it in every widget.