I currently have a listview which contain some widgets that I collapse when they leave the viewport, but this causes everything below to move upwards which becomes a really strange experience for the user.
Is there a way to have the widgets collapse without moving below when the collapse happens outside the viewport?
I use collapsible and visibility_detector to handle the collapse and the check for whether the widget is in view or not.
Related
Looking at the Flutter Hero Transition, it appears to move the tagged Widgets to an Overlay class that exists in all Navigator Widgets but sits above the main content in the stack.
If this is correct, it allows the Hero to widgets to still respond to the Route scope and its animators but exist above the actual route content. How is this actually done efficiently? Surely this involves taking an entire Widget and storing it in a state for the duration of the animation. That Widget still has to respond to intrinsic responses from its original position such as slivers responding to active scroll actions.
Recreating this could be done with state management but I wondered how the standard hero actually does this. It seems like Widgets are effectively duplicated and then conditionally rendered on the screen defaulting to the overlay during the route animation and swapping out the original widget with an Offstage or similar. Is this how it is done?
The reason for trying to understand it is the need to replicate this behaviour in situations where Navigator is not an effective use case for a transition taking place internally on a page. I built an accordion style navigator but still want a hero transition to take place on the AppBar / NavigationBar. I know that this could be done with Navigator but it doesn't suit the use case. I could also predefine the AppBar content for each internal navigator state of the accordion but that is a lot of additional code.
Problem summary
I'm building simple animation in which, simply, a panel expands to the right on a onTap event. The layout can be summarized as follows:
The panel has many tiles. Each tile has its own:
leading icon
title text
trailing icon
Each tile, when expanded, shows the three widgets above
Each tile, when shrinked, just shows the leading icon
The panel is scrollable to hold many icons such as these
At the end of the panel there's a simple icon which, when tapped, triggers the "expand" or "shrink" animation
The animation is built with an AnimatedContainer on the panel and a SizeTransition on the single tiles (via one single controller on the parent class)
The problem is simple: when the tiles shrink, their inner text overflows in the row.
Sample code
I just made this reproducible example on DartPad.
The obvious solution isn't helping me out
The most obvious solution is to simply wrap the Text inside a Flexible Widget: this advised by Flutter's docs and it makes sense, but unluckily it completely breaks my Layout.
Flexible introduces a flex factor that in this context is 100% unwanted.
I want my leading icons to be always at the end of the row, so my Spacer widget should "prevail" there.
I can't just play with flex factors there, as it would unintendedly hide text depending on its value.
Another code smell
Another thing I really don't like is the fact that I have to build a controller on the parent class, but I'm not actually using it on the parent class (I'm just exploiting it so I can give it to the children).
I'm new to animations in Flutter so I'm kinda confused on how I should orchestrate the whole thing here.
Any help will be appreciated / upvoted / accepted. Thank you!
As far as I understood you in a right way you just need set sizes for Row inside of SizeTransition instead of Container sizes
Here is your modified sample https://dartpad.dev/?id=a2408d29a1e8c6ce7a1cef8f21e7491d
I'd try an OverflowBox or a FittedBox (wrapping your text), depending on the result you want to achieve.
Even though there is absolutely no gap between my positioned widgets there is a glitchy visual gap between them. I have my Stack in an InteractiveViewer and when I zoom in and out and move about they become randomly more or less visible.
This happens with any Positioned widgets in a Stack so I've not provided any specific code of mine.
This ui looks like there is nothing that's being stacked. If you are using positioned widget then the value given maybe a problem. For this layout you can try adding all images ina column
Is it possible to add new elements into the top of the ListVeiw or CustomScrollView and keep the scroll position as it's with Flutter
I've tried the following
extentAfter = _scrollController.position.extentAfter;
_scrollController.jumpTo(_scrollController.position.maxScrollExtent - extentAfter);
but this won't work well with SliverAppBar - floating and its actually not optimal solution.
Actually the cleanest way would be to add those items only when user scrolls back to the top of the ListView. You can cache them in memory for the moment user is far enough from the top (in your case) of the list.
How do you hide certain widgets when the keyboard is activated? I have an app that overflows when a textfield is activated and instead of just compressing everything I would like to hide several of the widgets that are not necessary when filling out the fields.
I'd first suggest to use SingleChildScrollView as parent. It allows you to show the whole view and make it scrollable when keyboard appears.
If you still want to hide elements, you can know if keyboard is on screen by checking if MediaQuery.of(context).viewInsets.bottom > 100.