Related
I want my floatingActionButton to stay like this when using persistentFooterButtons
If I add persistentFooterButtons, it becomes like this, but I want it lower and docked
This is the stateful widget with the bottom bar:
class Main extends StatefulWidget {
const Main({Key? key}) : super(key: key);
#override
State<Main> createState() => _MainState();
}
class _MainState extends State<Main> {
int selectedIndex = 0;
static User user = FirebaseAuth.instance.currentUser!;
final screens = [
const Home(),
const Search(),
const Library(),
Account(user: user),
];
#override
Widget build(BuildContext context) {
return Scaffold(
persistentFooterButtons: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
IconButton(
iconSize: 35,
icon: Icon(Icons.play_arrow),
onPressed: null,
),
Text("Some data over hereSome data "),
IconButton(
icon: Icon(Icons.favorite),
onPressed: null,
)
],
)
],
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const FittedBox(child: PlayButton()),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
resizeToAvoidBottomInset: false,
bottomNavigationBar: BottomAppBar(
shape: const CircularNotchedRectangle(),
notchMargin: 5,
color: Colors.red,
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
IconlyLight.home,
color: Colors.white,
),
activeIcon: Icon(
IconlyBold.home,
color: Colors.white,
shadows: [
BoxShadow(
blurRadius: 30,
color: Colors.white,
),
],
),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(
IconlyLight.search,
color: Colors.white,
),
activeIcon: Icon(
IconlyBold.search,
color: Colors.white,
shadows: [
BoxShadow(
blurRadius: 30,
color: Colors.white,
),
],
),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(
Iconsax.music_library_2,
color: Colors.white,
),
activeIcon: Icon(
Iconsax.music_library_25,
color: Colors.white,
shadows: [
BoxShadow(
blurRadius: 30,
color: Colors.white,
),
],
),
label: 'Library',
),
BottomNavigationBarItem(
icon: Icon(
IconlyLight.profile,
color: Colors.white,
),
activeIcon: Icon(
IconlyBold.profile,
color: Colors.white,
shadows: [
BoxShadow(
blurRadius: 30,
color: Colors.white,
),
],
),
label: 'Account',
),
],
currentIndex: selectedIndex,
unselectedItemColor: Colors.white,
selectedItemColor: Colors.white,
onTap: (index) => setState(() => selectedIndex = index),
),
),
body: IndexedStack(
index: selectedIndex,
children: screens,
),
);
}
}
The key elements are
persistentFooterButtons: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
IconButton(
iconSize: 35,
icon: Icon(Icons.play_arrow),
onPressed: null,
),
Text("Some data over hereSome data "),
IconButton(
icon: Icon(Icons.favorite),
onPressed: null,
)
],
)
],
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const FittedBox(child: PlayButton()),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
I ended up pushing the FAB down using a Stack with Positioned
floatingActionButton: Stack(
alignment: Alignment.bottomCenter,
clipBehavior: Clip.none,
children: [
Positioned(
bottom: 5,
child: FloatingActionButton(
onPressed: () {},
),
),
],
),
I am trying to create a Bottom Navigation Bar with a button group in the middle. The 2 icons on either side of the button group will switch the displayed screen. The centered button group has 3 buttons which would act on the displayed screen. This is similar to the new Google Assistant bottom bar
.
I tried using the BottomNavigationBar with the centre item a custom widget. However the sizes of all the items end up equal. Any help creating this layout would be appreciated. Thanks.
This is the design I am trying to achieve
Here's what I have now:
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.secondary,
leading: IconButton(
icon: Image.asset(alInvertedIcon, width: 32, semanticLabel: "Home screen"),
onPressed: () {
push(const HomeScreen());
},
iconSize: 32,
),
title: Image.asset(alTextInv, width: 175),
centerTitle: true,
actions: [
IconButton(
icon: const Icon(Icons.person_outlined, semanticLabel: "User Profile"),
onPressed: () {
push(const ProfileScreen());
},
iconSize: 32,
)
],
),
body: bodyWidget,
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,
showSelectedLabels: false,
showUnselectedLabels: false,
backgroundColor: Theme.of(context).colorScheme.secondary,
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor: Colors.grey,
currentIndex: _currentIndex,
items: [
const BottomNavigationBarItem(
icon: Icon(
Icons.camera_alt,
),
label: 'Visual',
),
BottomNavigationBarItem(
icon: SizedBox(
width: 300,
child: _actionPanel(),
),
label: 'Add',
),
const BottomNavigationBarItem(
icon: Icon(
Icons.chat,
),
label: 'Text',
),
],
),
),
);
}
Widget _actionPanel() {
return Material(
elevation: 1.0,
borderRadius: const BorderRadius.all(Radius.circular(25)),
child: Row(
children: <Widget>[
IconButton(
onPressed: () {},
icon: const Icon(
Icons.refresh,
),
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.mic,
),
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.camera,
),
),
],
),
);
}
Try using this way.
Widget _actionPanel() {
return Material(
elevation: 1.0,
borderRadius: BorderRadius.all(Radius.circular(25)),
child: Container(
padding: EdgeInsets.symmetric(vertical: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
MaterialButton(
onPressed: () {},
shape: CircleBorder(),
minWidth: 0,
padding: EdgeInsets.all(5),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Icon(Icons.refresh),
),
MaterialButton(
onPressed: () {},
shape: CircleBorder(),
minWidth: 0,
padding: EdgeInsets.all(5),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Icon(Icons.mic),
),
MaterialButton(
onPressed: () {},
shape: CircleBorder(),
minWidth: 0,
padding: EdgeInsets.all(5),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Icon(Icons.camera),
),
],
),
),
);
}
I have this:
And I want to do this:
I find out that I have 2 ways to do this:
Cutting my circle widget on bottom by some pixels
Hide circle widget behind bottomnavigationbar (preferred)
Well, I don't know how to implement code in any of these 2 ways.
My code:
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FittedBox(
fit: BoxFit.scaleDown,
child: Container(
margin: const EdgeInsets.fromLTRB(0, 0, 0, 55),
width: 80,
height: 80,
child: SizedBox(
height: 80,
child: SpeedDial(
foregroundColor: Colors.white,
overlayColor: Colors.white10,
elevation: 0,
backgroundColor: const Color.fromARGB(255, 105, 30, 0),
childrenButtonSize: (const Size.square(100)),
direction: SpeedDialDirection.left,
child: const Icon(
Icons.add,
size: 48,
),
children: [
SpeedDialChild(
backgroundColor:
const Color.fromARGB(190, 105, 30, 1),
child: const Icon(
Icons.ac_unit_sharp,
size: 40,
))
])))),
bottomNavigationBar: Container(
decoration: const BoxDecoration(
border: Border(top: BorderSide(color: Colors.white, width: 2))),
child: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Znajomi',
backgroundColor: Color.fromARGB(190, 105, 30, 1),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.map),
label: 'Mapa',
backgroundColor: Color.fromARGB(210, 105, 30, 1),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.crown),
label: 'Ranking',
backgroundColor: Color.fromARGB(190, 105, 30, 1),
),
],
type: BottomNavigationBarType.shifting,
currentIndex: _selectedIndex,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.white,
showSelectedLabels: false,
iconSize: 38,
onTap: _onItemTap,
elevation: 0),
),
);
You can use the Stack widget for overlaying widgets on top of each other. If you place your BottomNavigationBar above your circle widget in the Stack the circle widget will be hidden behind the BottomNavigationBar.
Stack(
children: <Widget>[
FittedBox(),
BottomNavigationBar(),
],
)
Example here with Containers:
Stack(
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 90,
height: 90,
color: Colors.green,
),
Container(
width: 80,
height: 80,
color: Colors.blue,
),
],
)
Well, I was trying to create my custom appbar but I keep editing my column widget with properties I wanted in my appbar and it worked same as I wanted the appbar(as you can see in image) so I thought I dont need a appbar now. But now I want to implement a drawer which can be access by my iconbutton (which is implemented in top left corner of my widget). Actually drawer is implemented bcoz i can use it with sliding action, but I think its hidden behind my widget! I searched on internet and found some codes but since I dont have deep knowledge of any other programming knowledge so its little hard to understand the syntax for me. How can I access this drawer with my IconButton???
enter image description here
This is my page source code. NOTE: sorry i could not update the upper part of my bcoz i dont know how to format it in stackoverflow so its getting input as text instead of code snippet so I am avoiding it
return Scaffold(
backgroundColor: Colors.white,
drawer: CstmDrawer(),
body: SafeArea(
child: Column(
children: [
Row(
children: [
Container(
height: 150.0,
width: MediaQuery.of(context).size.width * 1.0,
child: Stack(
children: [
Container(
height: 130.0,
width: MediaQuery.of(context).size.width * 1.0,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.vertical(
bottom: Radius.elliptical(
MediaQuery.of(context).size.width, 100.0),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Scaffold.of(context).openDrawer(); //I found this code on internet but it gives error "Scaffold.of() called with a context that does not contain a Scaffold."
},
icon: Icon(Icons.menu),
),
Container(
child: Row(
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.notifications_active_outlined)),
IconButton(
onPressed: () {},
icon: Icon(Icons.shopping_cart_outlined)),
],
),
),
],
),
),
Positioned(
bottom: 20.0,
right: MediaQuery.of(context).size.width * 0.07,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width * 0.85,
child: Theme(
data: ThemeData(primaryColor: Colors.black),
child: TextField(
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(Icons.search),
hintText: "Search Here",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
),
),
),
),
],
),
),
],
),
],
),
),
);
Drawer source code.
return Drawer(
elevation: 16.0,
child: Column(
children: [
UserAccountsDrawerHeader(
onDetailsPressed: (){},
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,
child: IconButton(
onPressed: (){},
tooltip: "Add Photo",
splashColor: Colors.black,
icon: Icon(
Icons.add_a_photo_rounded,
),
),
),
accountName: Text(
"My Name"
),
accountEmail: Text(
"myemail#gmail.com",
),
),
ListTile(
//tileColor: Colors.green,
onTap: (){},
leading: Icon(Icons.person),
hoverColor: Colors.grey,
title: Text("My Account"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.shopping_cart_outlined),
hoverColor: Colors.grey,
title: Text("Cart"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.storefront_sharp),
hoverColor: Colors.grey,
title: Text("Shop"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.location_on_outlined),
hoverColor: Colors.grey,
title: Text("Map"),
),
Divider(
thickness: 2.0,
),
ListTile(
onTap: (){},
leading: Icon(Icons.settings),
hoverColor: Colors.grey,
title: Text("Settings"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.logout),
hoverColor: Colors.grey,
title: Text("Logout"),
),
],
),
);
The issue is that your context does not contains yet the data from your Scaffold, the workaround you can apply would be to use a GlobalKey to refer to your current ScaffoldState:
class MyWidget extends StatelessWidget {
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
drawer: CstmDrawer(),
body: SafeArea(
child: Column(
children: [
Row(
children: [
Container(
height: 150.0,
width: MediaQuery.of(context).size.width * 1.0,
child: Stack(
children: [
Container(
height: 130.0,
width: MediaQuery.of(context).size.width * 1.0,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.vertical(
bottom: Radius.elliptical(
MediaQuery.of(context).size.width, 100.0),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
/// Use the _scaffoldKey to call openDrawer()
IconButton(
onPressed: () =>
_scaffoldKey.currentState.openDrawer(),
icon: Icon(Icons.menu),
),
Container(
child: Row(
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.notifications_active_outlined)),
IconButton(
onPressed: () {},
icon: Icon(Icons.shopping_cart_outlined)),
],
),
),
],
),
),
Positioned(
bottom: 20.0,
right: MediaQuery.of(context).size.width * 0.07,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width * 0.85,
child: Theme(
data: ThemeData(primaryColor: Colors.black),
child: TextField(
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(Icons.search),
hintText: "Search Here",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
),
),
),
),
],
),
),
],
),
],
),
),
);
}
}
Here the solution is to use _scaffoldKey to call openDrawer() so instead of doing Scaffold.of(context).openDrawer() you will do _scaffoldKey.currentState.openDrawer(), and do not forget to assign the key to your Scaffold, by doing key: _scaffoldKey.
You can use this I guess!
IconButton(
icon: Icon(Icons.menu),
onPressed: () => Scaffold.of(context).openDrawer()
)
How to make this arrow icon in the center of the button
it's see the edge of icon is the center of icon, and I want make flutter see the center of icon is the center of icon
for more explain:
my code:
AppBar(
backgroundColor: Colors.transparent,
leading:
// Here the code of the button
SizedBox(
height: getProportionateScreenHeight(20),
width: getProportionateScreenWidth(10),
child: Padding(
padding: EdgeInsets.all(8),
child: FlatButton(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
color: Colors.white,
onPressed: () {
Navigator.pop(context);
},
child: Center(
child: Icon(
Icons.arrow_back_ios,
),
),
),
),
),
// ....
actions: [
IconButton(
icon: Icon(
Icons.favorite,
color: favFlag ? Colors.red : Colors.red[100],
),
onPressed: () {
setState(() {
favFlag = !favFlag;
});
},
),
],
);
And it's was working with me before last upgrade.
I think there is some problem with the use of your height and width factor for SizedBox. I used simple values for these and it is working fine.
In fact, I removed the SizedBox widget and there was no such effect. I have attached the pic after the code as well :)
appBar: AppBar(
backgroundColor: Colors.transparent,
leading:
// Here the code of the button
SizedBox(
height: 20,
width: 20,
child: Padding(
padding: EdgeInsets.all(8),
child: FlatButton(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
color: Colors.white,
onPressed: () {
// Navigator.pop(context);
},
child: Center(
child: Icon(
Icons.arrow_back_ios,
),
),
),
),
),
actions: [
IconButton(
icon: Icon(
Icons.favorite,
color: favFlag ? Colors.red : Colors.red[100],
),
onPressed: () {
setState(() {
favFlag = !favFlag;
});
},
),
],
),
Output:
My solution
AppBar(
backgroundColor: Colors.transparent,
// Here the code of the button
leading: Padding(
padding: EdgeInsets.all(8),
child: FlatButton(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
color: Colors.white,
onPressed: () {
Navigator.pop(context);
},
child: Stack(
alignment: Alignment.center,
children: [
Positioned.directional(
textDirection: Directionality.of(context),
end: 3,
child: Icon(
Icons.arrow_back_ios,
),
),
],
),
),
),
// ....
actions: [
IconButton(
icon: Icon(
Icons.favorite,
color: favFlag ? Colors.red : Colors.red[100],
),
onPressed: () {
setState(() {
favFlag = !favFlag;
});
AdsService.listByPagination();
},
),
],
);
I've positioned it to center manually, so I prefer if there an another clean short solution.