How to make bottomNavigationBar notch transparent - flutter

I want to make the notch margin spacing (space between FAB's sides and bottom bar) like android material design explain in Inset FAB, It looks like a zoom background text in this small visible round portion. How we can make notching space transparent to see the text behind it?
However, mine bottom bar is not showing like that
My implementation
Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.white,
child: Image.asset("images/paw.png"),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Map()));
},
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.menu),
color: Colors.transparent,
onPressed: () {},
),
],
),
color: Utiles.primary_bg_color,
),
body: Container(...)

You need extendBody: true in Scaffold
class SO extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
appBar: AppBar(),
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text('text text text text text text text text text text text text text text text text text text text text ');
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {},
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 12,
color: Colors.blue,
child: Container(
height: 60,
),
),
);
}
}

BottomAppBar + BottomNavigationBar
The question title asks about BottomNavigationBar so I'm adding this answer to help people using both a BottomAppBar with a BottomNavigationBar.
If you're not using BottomNavigationBar, ignore this.
NavBar Covers Notch
By default, a BottomNavigationBar used as a child inside a BottomAppBar, will cover the notch like so:
We need to remove its color & shadow to let the notch show.
Using BottomNavigationBar in BottomAppBar
To keep the notch visible...
BottomNavigationBar needs:
a backgroundColor specified, with 0 alpha (completely transparent)
otherwise, the default onBackground theme color is used, covering the notch
elevation: 0 to remove an ugly shadow under BottomNavigationBar
the transparent backgroundColor makes the shadow visible & horrendous
BottomAppBar needs:
shape: CircularNotchedRectangle() obviously, to have a notch for the FAB
elevation: 0 to remove a slight shadow under the notched FAB (barely visible)
Scaffold needs:
extendBody: true to allow body content to flow underneath notched FAB
SafeArea needs:
if using SafeArea, use bottom:false arg, so our body can flow below past the BottomNavigationBar, under the FAB
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
extendBody: true, // CRITICAL for body flowing under FAB
body: SafeArea(
child: Center(
child: Container(
color: Colors.greenAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
),
bottom: false,
// ↑ SafeArea(bottom:false) allows Scaffold body:+extendBody: to hit bottom edge
),
// ↓ Location: centerDocked positions notched FAB in center of BottomAppBar ↓
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
bottomNavigationBar: BottomAppBar( // ****** APP BAR ******************
clipBehavior: Clip.antiAlias,
shape: CircularNotchedRectangle(), // ← carves notch for FAB in BottomAppBar
color: Theme.of(context).primaryColor.withAlpha(255),
// ↑ use .withAlpha(0) to debug/peek underneath ↑ BottomAppBar
elevation: 0, // ← removes slight shadow under FAB, hardly noticeable
// ↑ default elevation is 8. Peek it by setting color ↑ alpha to 0
child: BottomNavigationBar( // ***** NAVBAR *************************
elevation: 0, // 0 removes ugly rectangular NavBar shadow
// CRITICAL ↓ a solid color here destroys FAB notch. Use alpha 0!
backgroundColor: Theme.of(context).primaryColor.withAlpha(0),
// ====================== END OF INTERESTING STUFF =================
selectedItemColor: Theme.of(context).colorScheme.onSurface,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit_outlined,
size: 40,
color: Theme.of(context).colorScheme.onBackground),
label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm,
size: 40,
color: Theme.of(context).colorScheme.onBackground),
label: 'Edit')
],
),
),
);
Result
With the above pieces in place you should see something like this:

Use, extendBody: true
From the docs,
extendBody: true ensures that that scaffold's body will be visible through the bottom navigation bar's notch

Do:
return Scaffold(
extendBody: true,
(...)
after
body: SafeArea(
bottom: false,
(...)
after "no add backgroundColor"
BottomNavigationBar(
//backgroundColor:

If you use safe Area ,then extended Body and probably other methods doesn't work. So set the safe Area to (false).

Related

[Flutter]: FAB for only one bottom tab

I have a BottomAppBar that has a FloatingActionButton. However, I only want this button to be seen in one particular screen. In the best case, I'd like to add this button only when the user clicks on that particular screen.
I've found that you can add a FAB like this:
return Scaffold(
extendBodyBehindAppBar: true,
extendBody: true,
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {
...
},
child: const Icon(
Icons.add_sharp,
color: Color(0xFFFFFFFF),
),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: buildBottomNavigationBar(),
);
However, as you can see this Scaffold is shared by all the screens that can be selected in the bottomNavigationBar. How do I add a FAB only for a particular screen?
I'd like the FAB to be embedded into the bottomNavigationBar so I do not want to add a plain button to that particular screen. Thanks.
The answer by #Josip Domazet is absolutely right, but it can be achieved with shorter workaround instead of creating different Scaffold, using conditional operator as
floatingActionButton: _selectedIndex==1
? FloatingActionButton(....) : const SizedBox.shrink(),
Use Stack In your Specific Tab and Add FAB at the bottom :
Example :
Stack(
children[
Container(height: double.infinity,
width: double.infinity) // for full screen
Position(
bottom : 10,
left: 150,
right : 150,
child: FloatingActionButton(
onPressed: () {
...
},
child: const Icon(
Icons.add_sharp,
color: Color(0xFFFFFFFF),
),
)
)
])
Wrap that specific screen with scaffold again and use fab on that screen only.
Turns out the solution was actually quite simple and I was overthinking stuff. I have a variable that keeps track of the currently open screen. So I simply added this little logic to the mother screen that hosts the bottomNavigationBar:
if (_selectedIndex==1){
// Other screen that needs the FAB
return Scaffold(
...,
floatingActionButton: FloatingActionButton(
....
),
bottomNavigationBar: buildBottomNavigationBar(),
);
}
return Scaffold(
...,
bottomNavigationBar: buildBottomNavigationBar(),
);

how we can use two rows in appbar flutter Like first row with title and the second with search input field

Hi There I am working on a app where i need to use two sections in appbar one upper
1->section with logo and some Icons
2-> Search input field below the Title Section.
UI images are attached for better understanding.
you can customize the size of app bar by using toolbarHeight: 120.0 // set value
then use flexibleSpace to add column or rows
it will look something like this
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
toolbarHeight: 120.10, //set your height
flexibleSpace: SafeArea(
child: Container(
color: Colors.blue, // set your color
child: Column(
children: [
Row(
children: [Text("Logo")],
),
Text("data"), // set an icon or image
IconButton(
icon: Icon(Icons.search),
onPressed: () {}) // set your search bar setting
],
),
),
),
),
),
);
}
}
Just simply create your AppBar as intended, in your screenshot, you don't actually need a second Row. A TextFormField will be enough (you will actually need to customise the InputDecoration as well):
return AppBar(
title: Column(children: [
Row(children: [
Icon(Icons.menu),
Text('First row'),
const Spacer(),
Icon(Icons.person),
]),
TextFormField(),
]),
);
You can use the bottom property from the AppBar widget.
AppBar(
title: YourFirstRowWidget(),
centerTitle: true,
bottom: PreferredSize(
child: YourSearchBarWidget(),
preferredSize: null),
)
But you may want to create your own AppBar widget for a perfect result.

Flutter web vertical tab navigation

How to create vertical tab navigation for dashboard in flutter web and whats it the best way?
You can you a NavigationRail to get this look. It was added to flutter this year. It works almost like the bottom tab bar.
I believe you want something similiar to what is shown in the screenshot right?
If so, I would recommend you to use the Scaffold Widget and making use of the attributes appBar and drawer.
For further information about the Scaffold Widget please check this link.
Here a simple example:
In your main Widget modify the build function like this.
#override
Widget build(BuildContext context) {
GlobalKey<ScaffoldState> key = GlobalKey();
return Scaffold(
key: key,
drawer: Padding(
padding: const EdgeInsets.fromLTRB(0, 70, 0, 0),
child: Container(
color: Colors.red,
width: 300,
child: Column(children: [Text("1"), Text("2"), Text("3")])),
),
appBar: AppBar(
toolbarHeight: 70,
elevation: 5,
centerTitle: true,
backgroundColor: Colors.black,
leading: RawMaterialButton(
child: Icon(Icons.menu),
onPressed: () => key.currentState.openDrawer(),
),
title: Container(child: Text("Title Widget")),
),
body: Container(
child: Text("Main Widget"),
));
}
The result would look like this:

How to display a snackBar in scaffold is body is composed of Stack?

I am trying to display a snack bar on my screen. But the snack bar is covering the whole screen instead of just being displayed at the bottom. Here is my code.
Scaffold(
key: _scaffoldKey ,
backgroundColor: Colors.pink,
body: Stack(
children: <Widget>[
Text('Display Scaffold'),
Positioned(
top: 110,
child: Container(
child: FlatButton(
onpressed: (){
final snackBar = SnackBar(duration: Duration(seconds: 4),
content: Center(child: Text('Welcome')),
) ;
_scaffoldKey.currentState.showSnackBar(snackBar);
}
),
),
),
),
);
Remove Center widget. This makes the widget as big as the parent allows.
If you need to center your text, just use textAlign: TextAlign.center property in Text widget.
Have you try this ?
Scaffold.of(context).showSnackBar(snackBar);
instead of
_scaffoldKey.currentState.showSnackBar(snackBar);
It may be the solution.
I hope it could help you !

Drag and Drop Chip widgets

I was trying to make a list of chips which user can reorder by doing drag and drop gesture,
Here is sample code which you can execute to see the issue,
As being told, Chip class need a Material ancestor, so what is solution to this? Have to keep Chip wrapped with Card all the time?
Error:
The following assertion was thrown building Chip(dirty):
No Material widget found.
Chip widgets require a Material widget ancestor.
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Wrap(
direction: Axis.horizontal,
children: List.generate(_counter, (i) {
var chip = Chip(
backgroundColor: Colors.blue,
label: Text('item ${i}'),
);
return Draggable(
child: chip,
feedback: chip,
childWhenDragging: Container(),
);
}),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
note: I have modified the default click count template to demonstrate my issue
You can wrap it inside a FloatingActionButton.
var chip = FloatingActionButton(
child: Chip(
backgroundColor: Colors.blue,
label: Text('item $i'),
),
);
Hope it helps!
I had encountered the same issue. You can not use chips in the feedback of draggable. What I did is, wrapped my chip in Material with transparent background. The transparent background helps to remove the extra style that gets added from the Material widget.
feedback: Material(
color: Colors.transparent,
child: Chip(
// your code for the Chip
)
)