I've added a BottomAppBar to scaffold in a materialApp, and to that I've added a fab with a inset at the center. The code looks somewhat like this
Scaffold(
bottomNavigationBar: BottomAppBar(
color: Theme.of(context).accentColor,
shape: CircularNotchedRectangle(),
child: _buildBottomBar(context),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
backgroundColor: Theme.of(context).primaryColor,
child: Center(
child: Icon(
Icons.add,
size: 32.0,
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CreateEvent()),
);
},
),
)
And this is what I'm getting after rendering:
The notch is not transparent, and the content behind it is getting hidden.
Is there a way to fix this? Something I might have missed?
You just need to be on the flutter channel: master and then add to Scaffold:
Scaffold(
extendBody: true
);
and it should be transparent :)
Greets
Rebar
UPDATE:
You don't need to be on master channel. It's included everywhere :)
The problem is if you put your content in the body of Scaffold it won't overlap the size of your AppBar, BottomAppBar.
You can try using Stack, put your body as a first child, then put the Scaffold, change the backgroundColor as Transparent.
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Align(
alignment: Alignment.bottomCenter,
child: Image.network(
"https://images.pexels.com/photos/255379/pexels-photo-255379.jpeg?auto=compress&cs=tinysrgb&h=350"),
),
Scaffold(
backgroundColor: Colors.transparent,
bottomNavigationBar: BottomAppBar(
color: Theme.of(context).accentColor,
shape: CircularNotchedRectangle(),
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.access_alarm),
onPressed: () => null,
),
IconButton(
icon: Icon(Icons.sms_failed),
onPressed: () => null,
),
],
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
backgroundColor: Theme.of(context).primaryColor,
child: Center(
child: Icon(
Icons.add,
size: 32.0,
),
),
onPressed: () {
/*
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CreateEvent()),
);*/
},
),
),
],
);
I was able to achieve the desired behavior by also setting the resizeToAvoidBottomInset flag to false.
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
resizeToAvoidBottomInset: false,
body: IndexedStack(
children: <Widget>[],
index: _selectedTab,
),
bottomNavigationBar: ClipRRect(
clipBehavior: Clip.antiAlias,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0)
),
child: BottomNavigationBar(
backgroundColor: Colors.white,
elevation: 10,
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[],
currentIndex: _selectedTab,
),
),
);
}
Edit: keep in mind that you may have to manually set the bottom insets by using MediaQuery.of(context)
Adding to the accepted solution, if you are using SafeArea as an immediate child to Scaffold then make sure you set the bottom property to false.
Scaffold(
extendBody: true,
...
child: SafeArea(
bottom: false, /* important */
child: Container(
child: // your app content
),
),
);
This enables the content to flow behind the BottomNavigationBar
Related
I have a strange issue with my BottomAppBar and an overlapping ElevatedButton.
If I click on the upper half of the + Button the onTap event is fired for the widget behind the + Button. I tried different things but non are working, help is very appreciated, thanks :)
HomePage
return Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: _pages,
),
bottomNavigationBar: const _BottomAppBar(),
);
_BottomAppBar
#override
Widget build(BuildContext context) {
return BottomAppBar(
child: IconTheme(
data: IconThemeData(color: Theme.of(context).colorScheme.onPrimary),
child: Stack(
alignment: AlignmentDirectional.bottomCenter,
clipBehavior: Clip.none,
children: [
Positioned(
top: -30,
child: ElevatedButton(
clipBehavior: Clip.hardEdge,
onPressed: () {
...
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(20),
primary: lightGreen),
child: const Icon(
Icons.add,
size: 30,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
tooltip: 'Home',
iconSize: 28,
icon: SvgPicture.asset(
'assets/svg/home-aktiv.svg'
),
onPressed: () {
...
}),
IconButton(
tooltip: 'Profile',
iconSize: 32,
icon: SvgPicture.asset(
'assets/svg/profil-aktiv.svg'
),
onPressed: () {
...
}),
],
),
],
),
),
);
}
Did you try with a FloatingActionButton?
return Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: _pages,
),
bottomNavigationBar: _BottomAppBar(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
I have a BottomAppBar() widget
BottomAppBar(
shape: CircularNotchedRectangle(),
color: Colors.orange,
notchMargin: 5,
child:Container(),
);
And, I want to set the edge color differently like the answer from this question.
How do I change Bottom App Bar Items Color?
I'd tried to set the color of the child Container(). However, it draws a straight line without the bump at the FloatingAppButton(). Is there any way that I can do this?
Do you want to like this, please check the below code
Source code
Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.orange,
onPressed: () {},
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 6,
elevation: 30,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () {},),
IconButton(icon: Icon(Icons.search), onPressed: () {},),
],
),
),
appBar: AppBar(
titleSpacing: 0,
title: Text("Test"),
backgroundColor: const Color(0xffFA7343),
),
body: Container(
),
)
I am developing an app with Flutter, and I want to have 2 FABs on the main screen. One in the BottomAppBar which I have done.
Scaffold(
appBard: AppBar(title: Text("My App")),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{}
),
bottomNavigationBar: BottomAppBar(
color: Style.darkPrimaryColor,
shape: CircularNotchedRectangle(),
child: Container(
height: 50,
child: Row(
children: <Widget>[]
),
),
),
)
I want to have a second FAB positioned and fixed in the right bottom side of the screen in plus of the centered FAB like the following maquette:
Is there any way to achieve that?
I don't think there is any built in way of doing this with the scaffold, but it should be easy enough to just use a stack as your scaffold body, since you can add a floating action button anywhere. However, if you have two, you will need to change the hero tag on one of them to avoid errors when moving to/from that page.
Scaffold(
appBar: AppBar(title: Text("My App")),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{}
),
bottomNavigationBar: BottomAppBar(
color: Style.darkPrimaryColor,
shape: CircularNotchedRectangle(),
child: Container(
height: 50,
child: Row(
children: <Widget>[]
),
),
),
body: Stack(
alignment: Alignment.bottomRight,
children: [
Container(
child: //Use this as if it were the body
),
//Setup the position however you like
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: null, //Must be null to avoid hero animation errors
child: Icon(Icons.add),
onPressed: () => {},
),
),
],
),
)
Try this:
Scaffold(
appBar: AppBar(title: Text("My App")),
body: Stack(
children: [
Positioned(
bottom: 16,
right: 16,
child: FloatingActionButton(
heroTag: null,
child: Icon(Icons.add),
onPressed: ()=>{}
),
),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{}
),
bottomNavigationBar: BottomAppBar(
color: Colors.black54,
shape: CircularNotchedRectangle(),
child: Container(
height: 50,
child: Row(
children: <Widget>[
]
),
),
),
)
I have added a floating action button in the bottomNavigationBar. The default location should be on the bottom right, but mine stays at the center.
I have tried using this floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
but the FAB still resides at the center screen.
Here is my full code of the screen:
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(55.0),
child: CustomAppBar(title: 'Customers (2)',),
),
drawer: Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.white
),
child: MyDrawer(),
),
body: Container(
padding: EdgeInsets.all(15.0),
decoration: BoxDecoration(color: Colors.white),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
FaIcon(FontAwesomeIcons.search, color: Colors.greenAccent,),
SizedBox(width: 15.0,),
Text("Search Customers"),
],
),
],
),
),
),
bottomNavigationBar: FloatingActionButton(
child: FaIcon(FontAwesomeIcons.plus),
backgroundColor: Colors.greenAccent,
foregroundColor: Colors.white,
splashColor: Colors.black,
onPressed: () {
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
);
}
Any idea how to solve this?
Replace:
bottomNavigationBar: FloatingActionButton(...)
with:
floatingActionButton: FloatingActionButton(...)
Let's say that I have this widget:
Card(
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(28.0),
child: RaisedButton(
child: Text('Test'),
onPressed: () {},
),
),
),
),
I would like to disable (prevent showing) ripple effect on Card/InkWell only when the RaisedButton is tapped, but to show it when the Card is tapped (i.e. outside the button). Is there any way to achieve this effect?
I think the generalized question can be: How to prevent ripple effect on surrounding InkWell when tapped on InkWell inside? If you take a look at the source code then you can see that RaisedButton has Material and InkWell widgets that cause ripple.
Here is the full sample code.
If you want a quick hack, check it out:
Container(
width: 180,
height: 120,
child: Stack(
children: <Widget>[
Card(
child: InkWell(
onTap: () {},
),
),
Center(
child: RaisedButton(
child: Text('Test'),
onPressed: () {},
),
)
],
),
)
You can handle the logic inside onHighlightChanged method;
Color _color;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Card(
child: InkWell(
splashColor: _color,
highlightColor: _color,
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(28.0),
child: RaisedButton(
onHighlightChanged: (value) {
if (value) {
setState(() => _color = Colors.white);
} else {
Timer(Duration(milliseconds: 200), () {
setState(() => _color = null);
});
}
},
child: Text('Test'),
onPressed: () {},
),
),
),
),
),
);
}
try this out https://dartpad.dev/7ff7f5756d93db2d4ed6a4b9a6d75208. I used hack with wrapping in InkWell the widget you want to surround with parent InkWell