Flutter Vertical Scrollable Drawer - flutter

I would like to create something like this
I have a page with a list of products and I would like to make visible the "Cart" part only when I scroll to the bottom of the screen and when I click on a product and be able to swipe up to navigate to the cart screen.
A solution could be making a Stack with two Container inside and have a variable that represent the current % of screen of the first Container (products) and moving them with the widget Positioned. So when I scroll to the bottom, I can raise up the product container and reveal the cart container and same thing when I swipe up the first container.
This is an example of the vertical drawer with % and Positioned
Is there a better solution?
EDIT
I did it, but it's not very smooth
The structure:
CustomScrollView()
|
|____SliverList()
| |
| |____Visibility() => Container() //Products list
| |
| |____Visibility() => Container() //Bottom Container with Borders
|
|____SliverList()
|
|____Visibility() => Container() //Bottom Cart part
|
|____Visibility() => Container() //Cart Screen
Starting with only Products List visible
When user clicks on a product, Bottom Container and Bottom Cart will be visible
I also put a GestureDetector() in Bottom Container and Bottom Cart.
With onVerticalDragUpdate if the user swipe up (details.delta.dy < 0):
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
And set visibility of Bottom Cart to false and set the Cart Screen visibility to true
As well I can might set the visibility of Products List to false, but this will cause a bug in the scroll animation so I set the mobile screen to only show Bottom Container and Cart Screen with the screen width (I didn't test it on other devices, this may be an error on ui) and I also block the scrolling with NeverScrollableScrollPhysics() in the CustomScrollView
On Swipe down on the Bottom Container, I set the visibility of Cart Screen to false, Bottom Cart to true and set CustomScrollView physics to AlwaysScrollableScrollPhysics() and made a scroll animation:
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
That's not very smooth because a better animation could be moving down the Cart Screen with Positioned, instead of making it invisible

Related

Dart/Flutter: resize widget on button click

I want to implement a dashboard that has 2 widgets: a menu panel and a panel where information is displayed.
I also want that if you click the top left button, the panel would collapse and the information panel would be 100% of the screen's width.
How can I resize a widget on button click?
Wrap you sidebar with an AnimatedContainer. Then, set the width property on that container to width: isExpanded ? 200 : 0, where isExpanded is a bool that specifies whether or not the sidebar should be expanded, and 200 is the width that you want the sidebar to be when expanded.
To toggle the sidebar to be expanded or not, simply call this:
setState(() { isExpanded = !isExpanded; });

How Do I Create this Page Swipe Behaviour in Flutter?

I want to implement this page swipe behaviour in Flutter as shown in the picture. The user should be able to drag the screen from the right edge of the screen to the left up until the page is dragged halfway through the screen. Once released, the app will move onto a new page.
Desired Outcome
You can use Slidable Package and wrap the whole page in a slideable.
Slidable(
key:UniqueyKey(),
endActionPane: ActionPane(
onDismissed: (){}, // Leave empty, confirmDismiss will handle event
confirmDismiss: () asnyc {
// function that rerender page with next question
}
children: [] //list of widgets to show when slide
child: // this is the widget that shows and will be slideable
if you want to have both sides you just add startActionPane aswell.

When using Flutter Visibility widget, can the change in visibility be animated?

I have a column holding a number of containers. The top and bottom containers are always shown, but the ones between sit inside a Visibility widget. If the user taps the screen, the middle containers are made visible, and then are made invisible again on the next tap. So essentially, the column expands and contracts each time it's tapped.
I'd like the expansion and contraction to happen a bit more gracefully - currently it looks very harsh when the middle containers just suddenly appear. Is there any way of animating the way in which the containers are made visible and hidden? Or should I be looking at using a totally different Widget than Visibility?
You can use an animated crossfade. Make the first child as SizedBox.shrink() and second child as the widget that you wish to display and it should be animating as expected. And switch according to the requirement
bool _first = true;
AnimatedCrossFade(
duration: const Duration(seconds: 1),
firstChild: const SizedBox.shrink(),
secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
)
Alter the value of _first to true or false.

How to make scrolling page continue even when tabBarView reaches the top? Flutter

The code I ran was the code that was given by Griffins here: How To Move The TabBarView in the Center to The Top of the Page?
Everything is the same as the code given by Griffins.
However, when the tabBar was scrolled to the top and locked there, the content under each widget stopped scrolling too.
I want the content of the widget page to continue scrolling to its end, even when the tabBar is locked at the top.
Even if pinned and floating of SliverPersistentHeader was declared false, all it does is just to make the tabBar scrolled up, the content of the tabBarView still ends at the similar position. This is occurring for both tabBarViews.
So I'm suspecting it has something to do with the sliverfillremaining taking up the remaining height. Is there a way to overcome this? and show all the content of the tabBar?
Solved.
I changed the SliverFillRemaining to
SliverToBoxAdapter(
child: AnimatedBuilder(
animation: tabController.animation,
builder: (ctx, child) {
if (tabController.index == 0) {
return Page1();
} else
return Page2();
}),
)

Flutter: How to make a ListView transparent to pointer events (but not its non-transparent contents)?

I have a Scrollable (ListView or any other) and it contains a transparent widget, say Container(height:200). I can see through both the widget and the scrollable (in other words I can see the widgets behind the scrollable).
How can I be able to click through the transparent widget and the scrollable, so that I reach the widgets behind the scrollable?
ListView(
children: [
Container(height: 200), // Transparent.
Container(color: Colors.red, height: 200),
],
);
Note, I cannot wrap the scrollable with IgnorePointer, because I still want to click the non-transparent widgets in the scrollable.
The only reasonable solution I can think of is to have a GestureDetector on the transparent container, which will give you the global position of the taps:
GestureDetector(
onTapUp: (TapUpDetails tapUpDetails) {
print("onTapUp global: " + tapUpDetails.globalPosition.toString());
},
And then add a Key to the widget behind the list, and use it to get the global position of the top left corner of the widget's rectangle, as well as the size of the widget, and use those to get the rectangle of the widget:
RenderBox renderBox = _key.currentContext.findRenderObject();
Offset topLeftCorner = renderBox.localToGlobal(Offset.zero);
Size size = renderBox.size;
Rect rectangle = topLeftCorner & size;
If the background widget does not move, you can do it within initState on the very next frame using WidgetsBinding.instance.addPostFrameCallback (the render object will be null if do it synchronously within initState) and save the Rect - otherwise you will have to recalculate it on every tap.
And then finally on each tap on the transparent container you can calculate whether the tap's position is within the boundaries of the background widget, and invoke the corresponding code:
// if tap is within boundaries of the background widget
if (rectangle.contains(tapUpDetails.globalPosition)) {
// your code here
}