Flutter: Create a rectangle that fills the title area of the app bar - flutter

In Flutter I want to create an app bar that looks as follows:
I've easily managed to add the 2 icons on the left and right, but I am struggling to create a rectangle in the middle.
I've tried the following code:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Image.asset('assets/images/maps.png'),
onPressed: () => {},
),
title: Expanded( // The bit that's not working. A rectangle that fills the middle area.
child: Container(
color: Colors.blue,
),
),
actions: <Widget>[
IconButton(
icon: Image.asset('assets/images/search.png'),
onPressed: () => {},
),
],
),
);
but I get the following exception:
Expanded widgets must be placed inside Flex widgets.
Expanded(no depth, flex: 1, dirty) has no Flex ancestor at all.
Thanks for the help.

You can achieve this by setting the centerTile attribute of the AppBar to true
Like this
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
leading: IconButton(
icon: Icon(
Icons.location_on,
color: Colors.grey,
),
onPressed: () => {},
),
title: Container(
padding: EdgeInsets.all(10),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(Icons.refresh),
Expanded(
child: Center(
child: Text("London"),
),
),
Opacity(child: Icon(Icons.refresh), opacity: 0,),
],
),
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(10)),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.grey,
),
onPressed: () => {},
),
],
),
);
}
}
The output:

An alternative solution (inspired by #Josteve Adekanbi answer), to create a rectangle that fills the title area is:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: ...
title: Container(
width: double.infinity,
height: 40,
child: Container(
color: Colors.blue,
),
),
actions: ...
),
);

Related

Custom widget of app bar with a humburger menu as ElevatedButton with a Drawer doesn't work OnPressed

I am facing a problem with my custom app bar. I would like it to have a drawer but it doesn't work. I just don't know how to make it being able to open.
It is a custom app bar widget named Pasek (which stands for top bar in my language).
It has a logo picture which on click moves you to the first page of the app.
Next to it there is humburger menu with a drawer but I do not know why it doesn't work. I click on it and nothing happens.
Any ideas?
class Pasek extends StatelessWidget with PreferredSizeWidget {
#override
Size get preferredSize => Size.fromHeight(50.0);
const Pasek({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return AppBar(
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 35.0),
child: ElevatedButton(
child: Icon(Icons.menu, color: Colors.white),
onPressed: () {
Scaffold(
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.black,
),
child: Text(
'Menu',
style: TextStyle(
color: Colors.pink,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Profile'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
);
},
)),
],
backgroundColor: Colors.black,
title: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => FirstPage(),
),
);
}, // Image tapped
child: Image.asset(
'images/logo.png',
fit: BoxFit.scaleDown,
height: 30,
width: 200,
),
));
}
}

How can I change the height of CupertinoNavigationBar in Flutter?

I want to increase CupertinoNavigationBar heigth. The code is like this:
child: CustomCupertinoNavigationBar(
padding: EdgeInsetsDirectional.zero,
backgroundColor: Colors.white,
middle: Semantics(
label: "dashboard-main-page-title",
child: Text(
"My Title",
style: TextStyles.HankenSans_Bold_18_PrimaryBlack,
key: Key('dashboard-main-page-title'),
),
),
leading: Semantics(
label: "dashboard-back-button",
child: Material(
color: Colors.white,
child: CustomBackButton(
onPressHandler: () {
Navigation().openMyAccountPage();
},
),
),
),
);
I tried creating my own custom cupertino. I copied the cupertino/nav_bar.dart and changed _kNavBarPersistentHeight parameter as const double _kNavBarPersistentHeight = 58.0; but it resulted at two navigation bars in IOS. Can anybody help me with this? Much appreciated.
I solved this problem as
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: Container(
height: 120,
child: CupertinoNavigationBar(
padding: EdgeInsetsDirectional.zero,
backgroundColor: Colors.white,
middle: Semantics(
label: "dashboard-main-page-title",
child: Text(
CustomerLoyaltyLocalizations.instance.dashboardMainPageTitle,
style: TextStyles.HankenSans_Bold_18_PrimaryBlack,
key: Key('dashboard-main-page-title'),
),
),
leading: Semantics(
label: "dashboard-back-button",
child: Material(
color: Colors.white,
child: CustomBackButton(
onPressHandler: () {
Navigation().openMyAccountPage();
},
),
),
),
),
),
),
First I used PreferredSize and then Container widget before CupertinoNavigationBar.

Scrollable Listview in sidebar flutter

I am using Default Sidebar but getting error while scroll
'The $controllerForError is currently attached to more than one '
'ScrollPosition.',
here is Sidebar Widget
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bgimage.jpg"),
fit: BoxFit.cover),
color: Colors.blue,
),
child: Center(
child: Column(
children: [
Text(
'${store.user['name']}',
style: TextStyle(color: Colors.white, fontSize: 25),
),
Lottie.asset(
'assets/lottie/coin.json',
width: 50,
height: 50,
),
Text(
'${store.user['wallet']}',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
)),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.popAndPushNamed(context, '/home');
},
),
ListTile(
leading: Icon(Icons.assessment_outlined),
title: Text('Loss/Profit'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.calendar_today),
title: Text('Results'),
onTap: () {
Navigator.popAndPushNamed(context, '/result');
},
),
ListTile(
leading: Icon(Icons.supervised_user_circle),
title: Text('Referrals'),
onTap: () {
Navigator.pop(context);
},
),
],
);
}
}
Using in homepage
drawer: Drawer(
child: Sidebar(),
),
where is scroll position is using multiple
by default drawer is already scrollable. i think the cause of not being able to scroll is not in the drawer

Flutter: keyboard pops out when opening drawer

everyone
I'm encountering a problem while using Flutter.
Basically when i open my CustomDrawer widget, not always but quite frequently, the keyboard pops out in an unwanted way.
I don't get why it does it... maybe because it re-runs the build method or something i don't know. Down below you can find the code.
Every little bit of information is well appreciated.
Thanks everyone.
Here's the Screen.dart
...
build(context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.transparent,
elevation: 0,
),
drawer: CustomDrawer(),
...
And the custom_drawer_widget.dart
...
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: [
Stack(
children: [
Container(
padding: EdgeInsets.all(20),
child: Text(
"Hi, $username",
style: TextStyle(
fontSize: 22,
),
),
alignment: Alignment.bottomLeft,
color: Colors.yellow,
height: 300,
),
],
),
Container(
height: 60.0 * 6,
child: Column(
children: [
Container(
height: 60,
child: FlatButton(
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10),
highlightColor: Colors.grey[350],
color: Colors.transparent,
onPressed: () {},
child: Row(
children: [
Icon(
Icons.home,
color: Colors.grey[600],
),
SizedBox(width: 30),
Text("Homepage"),
],
),
),
),
ListTile(
leading: Icon(Icons.book),
title: Text("Diary"),
onTap: () {}),
ListTile(
leading: Icon(Icons.chat),
title: Text("Chat"),
onTap: () {}),
ListTile(
leading: Icon(Icons.credit_card),
title: Text("Credit Card"),
onTap: () {}),
ListTile(
leading: Icon(Icons.exit_to_app),
title: Text("Sign Out"),
onTap: () async {
await FirebaseAuth.instance.signOut();
}),
ListTile(
leading: Icon(Icons.settings),
title: Text("Settings"),
onTap: () {}),
],
),
),
Expanded(
child: Container(
padding: EdgeInsets.all(22),
alignment: Alignment.bottomLeft,
child: Row(
children: [
Text("Version 0.1"),
],
),
),
)
],
),
);
}
...
I don't see exactly where you dismiss the keyboard, but I was having the same issue after dismissing the keyboard after a form submit. This fixed my issue.
See this answer here:
https://github.com/flutter/flutter/issues/54277
Where instead of:
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
The code should be:
onTap: () {
final FocusScopeNode currentScope = FocusScope.of(context);
if (!currentScope.hasPrimaryFocus && currentScope.hasFocus) {
FocusManager.instance.primaryFocus.unfocus();
}
},

Placing two trailing icons in ListTile

I want to place two icons, side by side on the "trailing" side of a ListTile. I tried adding a Row widget with the two icons inside, but it completely messed up the layout of the entire ListTile, making it unusable. Is there any way to expand the space allocated for the trailing part?
Here's the code:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.play_arrow,),
title: Text("This is a title"),
subtitle: Text("This is subtitle"),
trailing: Row(
children: <Widget>[
Icon(Icons.flight),
Icon(Icons.flight_land)
]),
)
]
),
),
);
}
}
This is how it looks like:
Adding mainAxisSize: MainAxisSize.min to the Row() instance fixes the issue.
You can simply use Wrap in trailing
ListTile(
title: Text("This is my ListTile"),
trailing: Wrap(
spacing: 12, // space between two icons
children: <Widget>[
Icon(Icons.call), // icon-1
Icon(Icons.message), // icon-2
],
),
)
Try this code. I think this is working correctly:
trailing: FittedBox(
fit: BoxFit.fill,
child: Row(
children: <Widget>[
Icon(Icons.flight),
Icon(Icons.flight_land),
],
),
),
I took advantage of the FittedBox solution left above and solved my problem by displaying a TextButton and an IconButton when the screen is in landscape and when in portrait mode, only IconButton
trailing: MediaQuery.of(context).size.width > 480
? FittedBox(
fit: BoxFit.fill,
child: Row(
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
// padding: const EdgeInsets.all(16.0),
primary: Theme.of(context).errorColor,
textStyle: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold),
),
onPressed: () => onRemove(tr.id),
child: const Text('Excluir'),
),
IconButton(
icon: Icon(Icons.delete),
color: Theme.of(context).errorColor,
onPressed: () => onRemove(tr.id),
),
],
),
)
: IconButton(
icon: Icon(Icons.delete),
color: Theme.of(context).errorColor,
onPressed: () => onRemove(tr.id),
),
Given negative value to spacing did the trick:
trailing: Wrap(
spacing: -16,
children: [
IconButton(
icon: const Icon(Icons.edit),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.delete,
color: Colors.redAccent,
),
onPressed: () {},
),
],
),