I have a requirement where I need to hide/show a widget ocassionally.
The widget is sitting right at the bottom of my layout. Immediately, the app loads I initially hide the widget by calling _slideAnimationController?.forward(); and then I noticed the widget is hidden but a white background was left behind by the SlideTransition widget, how can I remove this white background?
I don't want my users to know that there is a widget at the bottom until it is actually necessary to display it again using the SlideTransition.
Here is my code:
void initControllers() {
_scrollController.addListener(_scrollHandler);
_slideAnimationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 100));
_slideAnimOffset = Tween<Offset>(begin: Offset.zero, end: Offset(0.0, 1.0))
.animate(_slideAnimationController!);
_slideAnimationController?.forward();
}
void _scrollHandler() {
if (_scrollController.position.atEdge) {
if (_scrollController.position.pixels != 0) {
_slideAnimationController?.reverse();
} else {
_slideAnimationController?.forward();
}
}
}
Here is my build method:
.....
SlideTransition(
position: _slideAnimOffset!,
child: Container(width:100,height:100), //When the animation runs and the container is hidden, a weird white background is left off. I don't want that white background at all. Once it is hidden, it should be fully transparent.
),
.....
And my initState is as below:
#override
initState() {
tintSystemChrome();
initControllers();
super.initState();
}
Any insights would be truly appreciated.
Thank you.
I have a similar problem to yours.
I ended up using the AnimatedAlign to achieve the slide in/out animation.
Here is the sample code:
AnimatedAlign(
duration: const Duration(milliseconds: 100),
alignment: Alignment.topCenter,
heightFactor: isVisible ? 1.0 : 0.0,
child: Container(width:100,height:100),
);
Related
I made an automatic scrolling bar in flutter, the way I made it scroll automatically by using a combination of a timer and scroll controller, and then I linked the scroll controller to a regular ListView.builder, blew is the implementation of my way to do it
#override
void initState() {
super.initState();
int _length = widget.items.length;
currentItems = widget.items;
// scroll smothly to the end of the list then reverse the scroll
bool isAscending = true;
_timer = Timer.periodic(const Duration(milliseconds: 3000), (timer) {
if (isAscending) {
_currentIndex++;
if (_currentIndex == currentItems.length) {
isAscending = !isAscending;
}
}
if (!isAscending) {
_currentIndex--;
if (_currentIndex == 0) {
isAscending = !isAscending;
}
}
_scrollController.animateTo(_currentIndex * 304.0,
duration: const Duration(milliseconds: 3000), curve: Curves.linear);
});
}
my problem here is when I navigate to another screen or press the phone's home button and stay away from this widget for a while and then come back, I'd find it scrolling so fast to catch the currentIndex ( which is far away from where I left it ) in a period of time that I specified for the .animateTo method, I'm guessing the solution is to somehow pause the timer when I'm not in the same route, but I didn't find any reference of how to implement that
I need to hide my FloatingActionButton when scrolling a SingleChildScrollView. I found something about how to hide it when the user scrolls down and then show it when the user scrolls up, but that's not what I'm looking for.
I want the button to remain hidden only during the scroll. I also tried playing with the NotificationListener but didn't come up with a solution
Hide until you don't get any more notifications.
NotificationListener<UserScrollNotification>(
onNotification: (notification) {
if (_show) setState(() => _show = false);
_timer?.cancel();
_timer = Timer(const Duration(milliseconds: 200), () => setState(() => _show = true));
return true;
},
child: <your widget>
)
I'm using the following code, yes its incomplete and pretty little sphagetti as:
WidgetsBinding.instance!.handlePointerEvent(PointerDownEvent(pointer: 0, position: Offset(Get.width/2,Get.height/2)));
WidgetsBinding.instance!.handlePointerEvent(PointerMoveEvent(
pointer: 0,
//timeStamp: Duration(seconds:10),
position: Offset(Get.width/2+10,Get.height/2),
// delta: Offset(-10,Get.height/2),
// distanceMax: 0.05,
));
WidgetsBinding.instance!.handlePointerEvent(PointerUpEvent(pointer: 0),);
I'm trying to simulate a pointer drag on the screen, considering the screen is in landscape mode, from the middle of screen, to probably 10pixels+, to scroll the content a bit on a button-press. But the scroll is happening very fast, and sometimes scrolls with variable speed.
Could anyone recommend something?
Thanks to #pskink, the code he provided has been very helpful, and does answer the question too
late Animation<Offset> animation;
#override
void initState() {
super.initState();
final controller = AnimationController(vsync: this, duration: Duration(milliseconds: 300));
controller.addListener(_listener);
animation = Tween(begin: Offset(100, 100), end: Offset(200, 150)).animate(controller);
print('handle down event');
controller.forward().then((value) => print('handle up event'));
}
_listener() {
print('handle move event ${animation.value}');
}
For my widget the animation I have is going down half way because I am using this:
TweenSequenceItem<Alignment>(
tween: AlignmentTween(
begin: Alignment.topCenter, end: Alignment.bottomCenter),
weight: 1.0),
I have determined when using topCenter to bottomCenter it seems to traverse down half way when the animation is running.
Result:
What I want it to do is to go down all the way on the screen, would I specify coordinates for that? If that is the way how would those coordinates beceome dynamic across different screen sizes?
Code:
class _BouncingBallState extends State<BouncingBall>
with TickerProviderStateMixin {
AnimationController controller;
Animation<Alignment> alignmentAnimation; // Create animation object
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(seconds: 60),
);
controller.repeat(); // Make animation repeat
// Initialize using TweenSequence, that contains TweenSequenceItem, we can add multiple TweenSequenceItem as per our animation requirement
alignmentAnimation = TweenSequence<Alignment>([
// First point move from top center to bottom center
TweenSequenceItem<Alignment>(
tween: AlignmentTween(
begin: Alignment.topCenter, end: Alignment.bottomCenter),
weight: 1.0),
}
I am trying to animate navigation between two pages. I managed to animate the loading of the second page by following Reso Coder's Tutorial. But I also needed to animate "exiting" animation for the current page.
I managed to achieve it using Animated Widget (stanim). When a user clicks on the navigation button, I just start the animation, and when the animation finishes it runs the navigation code. This works somewhat like what I needed but the animation looks janky when page animation finishes and PageRouteBuilder animation starts.
_controller = AnimationController(
vsync: this, duration: Duration(milliseconds: duration))
..addStatusListener(
(status) {
if (status == AnimationStatus.completed) {
if (widget.nextPageBuilder != null) {
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(milliseconds: duration),
pageBuilder: (context, animation, secondaryAnimation) =>
widget.nextPageBuilder(animation),
),
);
}
}
},
);
Here is navigation logic
return ForwardButton(onPressed: () {
_controller.forward();
});