I faced some problem. I want make an image, a text and two icons in AppBar but I can't make it work as I want.
I tried to make some fonts in a row after the images and text. The images and the text successful show in my AppBar, but the rest of 2 fonts (Trolley and notifications) show some error.
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.amber,
appBar: new AppBar
(
title: new Row
(
mainAxisAlignment: MainAxisAlignment.start,
children:
[
Image.asset('images/logoapp.png',fit: BoxFit.contain,height: 32,),
Container(padding: const EdgeInsets.all(8.0), child: Text('Solid Shop'))
],
)
),
....
Use leading to set a widget before appBar title & use actions to specify list of widgets in appBar which appears on right side of appBar title.
AppBar(
leading: Image.asset('yourImage'), // you can put Icon as well, it accepts any widget.
title: Text ("Your Title"),
actions: [
Icon(Icons.add),
Icon(Icons.add),
],
);
Read more about it here
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Solid Shop"),
leading: Image.asset("your_image_asset"),
actions: <Widget>[
IconButton(icon: Icon(Icons.shopping_cart), onPressed: () {}),
IconButton(icon: Icon(Icons.message), onPressed: () {}),
],
),
);
}
You need to use actions instead of title
actions: <Widget>[
Image.asset('images/logoapp.png',fit: BoxFit.contain,height: 32,),
Container(padding: const EdgeInsets.all(8.0), child: Text('Solid Shop')),
Image.asset('images/logoapp.png',fit: BoxFit.contain,height: 32,), // here add notification icon
Container(padding: const EdgeInsets.all(8.0), child: Text('Solid Shop')) // here add other icon
],
You can add icon and also a picture on app bar, this code works for me:-
appBar: AppBar(
centerTitle: true,
elevation: 2,
title: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/bell.png",
fit: BoxFit.contain,
height: 28,
),
Container(
child: Text(" APP BAR"),
)
],
),
),
actions: [
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return Settings();
},
),
);
},
color: Colors.white,
)
],
),
Hope this was helpful.
You can combine it with Spacers :
actions: const [
Spacer(flex: 3),
Icon(Icons.fit_screen),
Spacer(flex: 10),
Icon(Icons.width_normal),
Spacer(flex: 1),
Icon(Icons.aspect_ratio),
Spacer(flex: 1),
Icon(Icons.ad_units),
Spacer(flex: 5),
],
Related
Why does it the text stay at the bottom? when i reduce the heigh of the appbar the text gets cut at the bottom.
Aligned to the Bottom
class InfoScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: PreferredSize(preferredSize: Size.fromHeight(50),
child: AppBar(
title: Column (
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.end,
children:[
Text('AppBar Demo'),
]
),
//toolbarHeight: 10.0,
actions: <Widget>[
IconButton(
icon: const Icon(Icons.settings),
tooltip: 'Next page',
onPressed: () {
openPage(context);
},
),
],
),
),
body: const Center(
child: Text(
'This is the home page',
style: TextStyle(fontSize: 24),
),
),
);
You should declare in your Scaffold appBar COnstructor the widget AppBar() and not the size of your appBar. Go check Material.io to learn about designing for better customer experience.
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Column (
crossAxisAlignment: CrossAxisAlignment.stretch,
//Here you align the text of your appBar to the bottom
mainAxisAlignment: MainAxisAlignment.end,
children:[
Text('AppBar Demo'),
]
),
//toolbarHeight: 10.0,
actions: <Widget>[
IconButton(
icon: const Icon(Icons.settings),
tooltip: 'Next page',
onPressed: () {
openPage(context);
},
),
],
),
),
I am new to flutter and I need to add the main drawer of the app to a button as you can see in the below picture(This is the upper section of the UI of the app)
Any ideas of having the main drawer apply to a button instead of having it normally assign it to the app bar. (This mobile app doesn't have an app bar)
#override
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
return Scaffold(
key: scaffoldKey,
body: Stack(
children: <Widget>[
_buildWidgetAlbumCover(mediaQuery),
getMainContentWidget(mediaQuery),
_buildWidgetMenu(mediaQuery),
_buildWidgetFloatingActionButton(mediaQuery),
Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
},
),
],
),
),
],
),
);
}
Widget _buildWidgetMenu(MediaQueryData mediaQuery) {
return Padding(
padding: EdgeInsets.only(
left: 2.0,
top: mediaQuery.padding.top + 2.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
Icons.menu,
color: Colors.white,
size: 25,
),
padding: EdgeInsets.all(2.0),
// onPressed: () => scaffoldKey.currentState.openDrawer(),
),
],
),
);
}
enter image description here
This is output which I get after having this code. This drawer can't even change or as it is fixed one. I want the normal drawer which is also attached to the _buildWidgetMenu instead of the app bar drawer.
If youre using a sacffold it has a drawer property that you can make use of eg cookbook
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(child: Text('My Page!')),
drawer: Drawer(...
opening your drawer from button clicks
var scaffoldKey = GlobalKey<ScaffoldState>();
//required key
Scaffold(
key: scaffoldKey,
drawer: new Drawer(
child: new ListView(
padding: EdgeInsets.zero,...
body:Center(..
IconButton(
icon: Icon(Icons.menu),
//open drawer
onPressed: () => scaffoldKey.currentState.openDrawer(),
),
I'd like to center an image in appbar (As Twitter does in their mobilapps), but I can't find any logic that does that. I tried to wrap the Container with Center() but it didn't work.
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text('Cranes'),
actions: <Widget>[
Container(
// margin: const EdgeInsets.only(right: 75),
child: Image.asset(
'assets/hmf_logo_medium.png',
),
),
FlatButton(
onPressed: () async {
await Provider.of<FlutterSecureStorage>(context, listen: false)
.deleteAll();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => LoginPage()),
(route) => false);
},
child: Text(S.of(context).craneListPageLogoutText,
style: TextStyle(color: Colors.white)),
)
],
),
); }
Try this
AppBar(
leading: Center(
child: Text('Cranes'),
),
title: Image.asset('assets/hmf_logo_medium.png'),
centerTitle: true,
)
You can wrap your all items with row then mainAxisAlignment.spaceBetween can handle that.
AppBar(
title:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Cranes'),
Container(
// margin: const EdgeInsets.only(right: 75),
child: Image.asset(
'assets/hmf_logo_medium.png',
),
),
FlatButton(
onPressed: () async {},
child: Text(S.of(context).craneListPageLogoutText,
style: TextStyle(color: Colors.white)),
)
],
),
),
Following would work :
AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Cranes'),
Image.asset(
'assets/logo.png',
fit: BoxFit.contain,
height: 32,
),
Container()
],
),
)
Result :
in title Property Use your Image. and then make centerTitle:true,
AppBar(
backgroundColor: kWhite,
elevation: 0,
title: Image.asset(kLogoYellow),
centerTitle: true,
)
I have a navigation drawer with a bunch of items and I want the logout item aligned to the very bottom of the drawer.
return Drawer(
child: Column(
children: [
DrawerAccountHeader(UserType.worker),
DrawerNavigationItem(
"Home",
Icons.home,
),
new ListTile(
title: new Text('Jobs', style: TextStyle(color: Colors.black54),),
dense: true,
),
DrawerNavigationItem(
"Nearby",
Icons.location_on,
),
DrawerNavigationItem(
"Applied",
Icons.check_circle_outline,
),
DrawerNavigationItem(
"Hired",
Icons.check_circle,
),
Expanded(child: Container()),
Divider(),
DrawerNavigationItem(
"Logout",
Icons.exit_to_app,
)
],
),
);
But on smaller screen I get overflow error because that topmost column height is bigger than screen height. So I tried changing the column to a ListBox and then I get an exception "Vertical viewport was given unbounded height", because I have the Expanded() in between the items to make that gap so that Login buttons sticks to the bottom of the list.
Is there any way to achieve below?
Have the login button (and possibly a group of buttons) stick to the bottom of the screen when there's vertical space.
Make the drawer item scrollable when there's not enough vertical space.
(nice to have) The scrollable, the entire drawer can be scrolled. I.e. on a small screen the user will need to scroll the drawer to get to the logout option.
Try this,
Drawer(
child: LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: IntrinsicHeight(
child: Column(
children: <Widget>[
DrawerHeader(
margin: EdgeInsets.all(0.0),
child: Center(
child: Text("Header"),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text("Home"),
onTap: () {},
),
new ListTile(
title: new Text(
'Jobs',
style: TextStyle(color: Colors.black54),
),
dense: true,
),
ListTile(
leading: Icon(Icons.location_on),
title: Text("Nearby"),
onTap: () {},
),
ListTile(
leading: Icon(Icons.check_circle_outline),
title: Text("Applied"),
onTap: () {},
),
ListTile(
leading: Icon(Icons.check_circle),
title: Text("Hired"),
onTap: () {},
),
const Expanded(child: SizedBox()),
const Divider(height: 1.0, color: Colors.grey),
ListTile(
leading: Icon(Icons.exit_to_app),
title: Text("Logout"),
onTap: () {},
)
],
),
),
),
);
},
),
)
Use the Align widget to position bottom
Align(
alignment: Alignment.bottomCenter, //you can set it as per your requirement
child: Container(
child: Image.asset(
"assets/drawerCycleImage.png", //or Text widget or More Any
)),
#override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title:Text('Title')),
drawer:Drawer(
child:Stack(
children:[
ListView(
shrinkWrap:true,
children: List.generate(25,(ind){
//SizedBox is to remain space for logout button !
return ind==25 ?
SizedBox(height:60)
: ListTile(title:Text('Item $ind'));
})
),
Align(
alignment:Alignment.bottomCenter,
child: Container(
height:60,
color:Colors.black,
child: ListTile(
leading:Icon(Icons.exit_to_app),
title:Text('Logout')
),
),
)
]
)
),
body: Container(
alignment:Alignment.center,
child: Text('Hello !')
),
);
}
I am making a custom AppBar that has a larger height than the typical AppBar. I would like to resize the leading widget/icon as well, and take advantage of the automaticallyImplyLeading default behaviors (so the menu icons and back icons are automatically implemented).
This is the solution I thought I would implement:
class AppAppBar extends PreferredSize{
AppAppBar(String title) : super(
preferredSize: Size.fromHeight(56.0),
child: AppBar(
centerTitle: true,
title: Text(title, style: textStyle)
)) {
(child as AppBar).leading =
SizedBox(width: 30.0, height: 30.0, child: (child as AppBar).leading);
}
static const textStyle = TextStyle(fontSize: 32.0);
}
But of course this won't work because (child as AppBar).leading is final.
So in the AppBar below (text size made dramatically larger for illustration purposes), I would like to make the automatically added hamburger icon larger in comparison.
What do you think? Are there solutions for this or should I give up on the automatic icons and add them myself?
Edit: Added an image to show what I mean
You cant because it is a predefined widget.
You can work around it with a Row widget:
Scaffold(
key:_scaffoldKey,
drawer: Drawer(),
appBar: AppBar(
automaticallyImplyLeading: false
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 20, // Your Height
width: 20, // Your width
child: IconButton( // Your drawer Icon
onPressed: () => _scaffoldKey.currentState.openDrawer()),
icon: Icon(Icons.arrow_back, color: Colors.white),
),)
// Your widgets here
],
),
),
)
You need the Key to open the drawer with _scaffoldKey.currentState.openDrawer().
automaticallyImplyLeading: false will prevent the default drawer Icon.
A simple example to demonstrate Raffi Jonas answer
AppBar(
automaticallyImplyLeading: false,
title: Row(
children: [
Expanded(
child: Text('One'),
),
Center(
child: Text('Two'),
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Text('Three'),
),
),
],
),
),
The leading Widget width of AppBar in Flutter can be resized using the leadingWidth property.
For Example :
AppBar(
title: const Text('Title'),
leadingWidth: 50,
leading: Container()
)
What you want is a custom app bar in Flutter. Most people try giving their own widgets in the title argument of an AppBar. But let me show you how to properly do it.
#override
Widget build(BuildContext context) => Scaffold(
appBar: _appBar(),
body: _body(),
);
//Custom AppBar
_appBar() => PreferredSize(
//kToolBarHeight: Default size used by all AppBar widgets in Flutter.
//MediaQuery...: viewPadding.top is StatusBar area. viewPadding.bottom is iPhone bottom bar.
preferredSize: PreferredSize.fromHeight(kToolBarHeight + MediaQuery.of(context).viewPadding.top),
child: Container(
child: Row(
//This will spread Row content evenly across the screen.
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//Leading Widget
Icon(Icons.home),
//Title
Text("Hello World!"),
//Trailing Widget / Actions
Icon(Icons.home),
],
),
),
);
Widget _body() => Container(
color: Colors.blue,
);
You can set a margin for height or width.
AppBar(
leading: Container(
margin: EdgeInsets.symmetric(vertical: 15),
child: IconButton(
icon: Icon(CupertinoIcons.chevron_left),
onPressed: () {},
),
),
To use a custom appBar leading button, here is the code.
appBar: AppBar(
title: Text('hello'),
// automaticallyImplyLeading: false,
elevation: 0,
leadingWidth: 58,
actions: [
ProfileBar(),
],
leading: Container(
width: 14,
//color: Colors.yellow,
child: Row( // <--- Using row to avoid force resizing of leading
children: [
Padding( // <--- Padding to make it look more nicer
padding: const EdgeInsets.only(left: 24.0),
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: SvgPicture.asset( // <-- Using SvgPicture package
'assets/svg/icons/backbtn.svg',
width: 24,
height: 24,
),
),
),
],
),
),
),