ListView with a Navigator as child - flutter

I'm trying to place a Navigator as child of a ListView widget. I'm doing this in order to have some static top content (i.e. a top navbar with a navigation options) and below that, some dynamic content based on the routing of the Navigator. I want to use a ListView instead of a Column in order to be able to scroll all the content, including the top navigation bar.
However, I'm getting a render exception, as the content of the Navigator widget is not bounded, and therefore can not be places inside a ListView, as it doesn't have any size constraints.
Is there any workaround in order to achieve such an effect?
|------------------| ^
| STATIC NAVBAR | | SCROLL
|------------------| |
| | ^
| NAVIGATOR |
| CONTENT |
| |
|------------------|

First off a SingleChildScrollView would probably suit your needs better to scroll a single widget.
To solve your render exception you should put you ListView or SingleChildScrollView as a child of Navigator as your intended effect is to scroll the contents of each routed widget. This isn't the only way to do it, I just think it would be easier for you to manage constraints for each child route. Either way, you're going to need to bound the children of your Navigator at some point in the vertical direction.

You can use TabBar so you can achieve the navigation that you meant in your question. You can put the TabBar inside the bottom property of Scaffold - AppBar().
For documentation you can check this official documentation of how to work with tabs here
Example of my work :
return Scaffold(
appBar: AppBar(
title: AppBarTitle(),
bottom: TabBar(
controller: _tabController, // define your TabController
tabs: _tabs, //list of tab widgets
),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
// Here you can put your ListView widget as your dynamic contents
],
),
);

Related

Flutter: I need to make the widgets scrollable so that whenever i'm scrolling with list view they will follow

I have 2 rows in my screen, the first row is consist of dropdown button and elevation button and the second row is where the stream builder located, I used flexible so that the stream builder is scrollable. What I want is every time I scroll the stream builder I want the first row to follow the scroll not stay in the screen.
This is how my widget set:
Scaffold
-Column
-Row
-Dropdown button
-Elevated buton
-Flexible
-Streambuilder
-stack
-listview
Just like in facebook everytime you scroll down the "what's in your mind" controller disappers too, not floating like an app bar
Inside Listview add physics: NeverScrollableScrollPhysics()
//
Listview(
physics: NeverScrollableScrollPhysics(),
return .....;
)
//
Follow this pattern.
If you want that widget to disappear when you scroll, you need to wrap your Column in a SingleChildScrollView which you will need to wrap in a Flxible
Code:
Flexible(
child: SingleChildScrollView(
child: Column(
//your normal code insode Column
Depending on your code, you may also need to make the ListView not scroll (as suggested by Rafid):
Listview( physics: NeverScrollableScrollPhysics()

How can i make shared appBar and bottomNavigation across flutter screens

i am new to flutter and i would like to have a shared appBar and bottomNavigationBar
the way i am currently using is implementing them in spearte files and importing them in each screen but i need to make one screen contains the appbar and the bottomNavigationBar and the content of the body renders diffrent views according to the routes and i can't make it at main page because the main page renders welcome screen
in reactJS i was importing the header and footer and make my routes between them how can i make somthing similar in flutter
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: navBar(),
body: SingleChildScrollView(reverse: true, child: ScanPassport()),
bottomNavigationBar: bottomNavigation(),
currentIndex: _selectedIndex,
onTap: _onItemTapped,
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
),
);
}
}
A couple of options:
Use MaterialApp() router. There's a tutorial here showing how to refactor your Scaffold() so you don't have duplicate code for appBar, bottomNavigationBar, etc. This is the official Flutter method for view routing.
If you need to swap out your Scaffold() body but can't change your other Scaffold() elements, you can create a widget for the body that takes a "page" value and change what it returns from build() based on the "page" value passed. The widget holding your Scaffold can be stateful and your bottom navigation bar can setState() the page number.
In your context, You can just have a single scaffold homepage screen after logged in success or after welcome screen (depends up app). Once you navigate to homepage, You will have appBar and bottom navigation bar at top and bottom respectively. The remaining portion at center will be your body content of the selected tab. Once you switched the tap on bottom navigation, you should change the content rather than using routes for switching the body content. The current page status will be preserved on homepage.

I need to make this layout but I am confused as to what should I use how to place them like in the image I have posted below

Since i want this to be my layout i was trying to implement it with a showModalBottomSheet but the problem is that this widget only works on the button click as it is showing me error when i am trying to call the method as it is in the initState method. So then I started to work with bottomSheet value present in the scaffold but then the background is being displayed only upto the starting of the bottom sheet creating the distance between the model sheet and the background whereas I want it to overlap like in the image..How should I prepare this layout.
There is no such parameter as "bottomSheet" in Scaffold, there is one called bottomAppBar, which is used for making Bottom Bars like the one on the Youtube Android App. So this should help you make the basic structure.
Use a Stack widget to put widgets on top of each other, in first layer, add the image using the NetworkImage widget, then in the second layer, make a Column, like this:
#override
Widget build() => Scaffold(
body: _body(),
);
_body() => Stack(
children: <Widget>[
NetworkImage(your_url_here),
Column(
children: <Widget>[
_basicDetails(),
_guidePanel(),
]
),
]);
Then create 2 new methods after the _body method like this:
_body() => Stack(...);
_basicDetailsPage() => Container();
_guidePanel() => Container();
Create your layout in these 2 methods. Comment if you need more help :)
For additional help, please join the Facebook Group "Let's Flutter With Dart"

How to remove Scrollbar from a widgets scrolling children

I have a ScrollBar surrounding a CupertinoPageScaffold child Widget.
Inside this contains a few horizontal scrolling ListViews which should not show scrollbars but due the parent ScrollBar being present, every scrolling widget below has a scroll bar attached to it.
Is there a Widget to wrap scrolling Widgets that removes the scrollbar?
I've looked for Widgets that may be called NoScrollbar but these don't exist.
If I remove the parent ScrollBar then the scrollbars are removed
If you wrap the ListViews for which you don't want scroll bars for in a NotificationListener in the following manner:
NotificationListener<ScrollNotification>(
onNotification: (_) => true,
child: ListView(....)
)
I think those ListViews will not have scrollbars.
You can use ScrollConfiguration to hide the scrollbars.
ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: ListView(....)
)
You can use this with any scrollable widget.

How can I create a Drawer below status bar in Flutter?

I want to make something like this, but always get this:
Scaffold(
drawer: Drawer(..),
..
)
How do I create a Drawer that is not displayed in the status bar?
For this kind of scenario, Flutter has the SafeArea widget. This widget will make sure that nothing is rendered e.g. beneath the status bar, i.e. a padding is added.
To apply this to your Drawer, you can simply wrap your Drawer with a SafeArea:
Scaffold(
drawer: SafeArea(
child: Drawer(..),
),
..
)
Screenshot of the drawer
You can also specify if you want to remove some of the padding added by SafeArea using the optional parameters top, bottom, left & right, e.g. SafeArea(bottom: false, ..).
Adding the padding: const EdgeInsets.all(0.0), to ListView resolves the issue.