Flutter set max width for AppBar - flutter

I want to set the max width of an AppBar like this:
PreferredSize(
preferredSize: Size(500, 200),
child: AppBar(
flexibleSpace: _AppHeader(),
),
)
But this only sets the height. How is is possible to set the width?

Looks like this is an open issue (https://github.com/flutter/flutter/issues/54784).
As suggested there by #imeDevelopers you can use Stack to "hack" an AppBar with max width:
If you use Stack, you also get to decide if the AppBar will scroll with the content or not.
Use this code to keep the AppBar in place even when scrolling (default AppBar behaviour):
const double appBarWidth = 980;
Scaffold(
body: Stack(
children: [
ListView(
shrinkWrap: true,
children: [
Padding(
padding: const EdgeInsets.only(top: 56),
child: Column(
children: [
...[Colors.green, Colors.indigo, Colors.amber].map(
(c) => Container(
color: Colors.red,
child: Center(
child: Container(
height: 1000,
width: appBarWidth,
color: c,
),
),
),
)
],
),
),
],
),
Container(
width: double.infinity,
height: 56,
color: Colors.lime,
),
Positioned(
left: (MediaQuery.of(context).size.width - appBarWidth) / 2,
child: Container(
width: appBarWidth,
child: AppBar(
elevation: 0,
title: const Text('TITLE'),
actions: [
...[1, 2, 3].map(
(i) => TextButton(
style: TextButton.styleFrom(
primary: Theme.of(context).colorScheme.onPrimary),
onPressed: () {},
child: Text('ACTION $i'),
),
),
],
),
),
)
],
),
);
Use this code if you want the AppBar to scroll with the content:
const double appBarWidth = 980;
Scaffold(
body: ListView(
shrinkWrap: true,
children: [
Stack(
children: [
Container(
width: double.infinity,
height: 56,
color: Colors.lime,
),
Positioned(
left: (MediaQuery.of(context).size.width - appBarWidth) / 2,
child: Container(
width: appBarWidth,
child: AppBar(
elevation: 0,
title: const Text('TITLE'),
actions: [
...[1, 2, 3].map(
(i) => TextButton(
style: TextButton.styleFrom(
primary: Theme.of(context).colorScheme.onPrimary),
onPressed: () {},
child: Text('ACTION $i'),
),
),
],
),
),
)
],
),
Column(
children: [
...[Colors.green, Colors.indigo, Colors.amber].map(
(c) => Container(
color: Colors.red,
child: Center(
child: Container(
height: 1000,
width: appBarWidth,
color: c,
),
),
),
)
],
),
],
),
);

Related

Flutter - Why Material elevation not working?

Material elevation in Column not working.
On this code elevation not working.
Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: const Text('Test'),
),
body: Column(
children: [
Material(
elevation: 8,
child: Container(
height: 50,
color: Colors.yellowAccent,
),
),
Container(
height: 50,
color: Colors.white,
)
],
),
);
But just remove Container is working. why?
Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: const Text('Test'),
),
body: Column(
children: [
Material(
elevation: 8,
child: Container(
height: 50,
color: Colors.yellowAccent,
),
),
],
),
);
has next Container.
remove next Container.
Include SingleChildScrollView and some content message.
It looks like a little shadow appears in the background, but not in the content.
update simple code:
Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: const Text('Test'),
elevation: 0,
),
body: Column(
children: [
Material(
elevation: 8,
child: Container(
alignment: Alignment.center,
height: 50,
color: Colors.yellowAccent,
child: const Text('Some title message'),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
for (var i = 0; i < 20; i++)
Container(
alignment: Alignment.center,
height: 100,
color: Colors.white,
// Divider
margin: const EdgeInsets.only(bottom: 8),
child: const Text('Some content'),
),
],
),
))
],
),
)
I think you can use Stack instead of Column if you want the shadow of Material was visible even if you scroll the list. And add transparent Container on the top of the list.
Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: const Text('Test'),
elevation: 0,
),
// Use stack instead of column
body: Stack(
children: [
SingleChildScrollView(
child: Column(
children: [
// Add transparent container
Container(
alignment: Alignment.center,
height: 60,
color: Colors.transparent,
),
for (var i = 0; i < 20; i++)
Container(
alignment: Alignment.center,
height: 100,
color: Colors.white,
// Divider
margin: const EdgeInsets.only(bottom: 8),
child: const Text('Some content'),
),
],
),
),
Material(
elevation: 8,
child: Container(
alignment: Alignment.center,
height: 50,
color: Colors.yellowAccent,
child: const Text('Some title message'),
),
)
],
),
);

Strange Top Padding on my second AppBar Flutter

Screen of the strange top padding of my app
I have made two classes : the first has a first AppBar and calls the second one that has also a sticky AppBar and display a list of scrollable Items. However, I have a strange top padding in the second AppBar. I have tried a lot of stuff but nothing seems to work.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
extendBodyBehindAppBar: true,
bottomNavigationBar: BottomNavBar(0, _currentAccount),
appBar: PreferredSize(
preferredSize:
Size.fromHeight(MediaQuery.of(context).size.height / 7),
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
Color(0xFF894c56),
Color(0xFFa80d0d)
])),
child: Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.only(top: 50, left: 5),
child: Text(
'Votre évenement ',
style: TextStyle(
fontSize: 15, color: Colors.grey),
)),
Padding(
padding: const EdgeInsets.only(top: 5, left: 5),
child: Text(
event,
style: const TextStyle(
color: Colors.white, fontSize: 17),
),
)
])),
)
],
),
),
body: ListPrestat('Traiteur', _currentAccount)
// ListPrestat('Traiteur', _currentAccount)
));
}
This is the code of my first class that calls the ListPrestat class here under :
#override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height ,
// -(MediaQuery.of(context).size.height / 6 + 56),
child: CustomScrollView(
slivers: [
SliverAppBar(
toolbarHeight: 50,
expandedHeight: 0,
backgroundColor: const Color(0xFFDCDCDC),
pinned: true,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Color(0xFFDC3535),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MainScreen(_currentAccount)),
);
},
),
centerTitle: true,
shadowColor: Colors.black,
elevation: 10,
bottom: const PreferredSize(
preferredSize: Size.fromHeight(0),
child: TagList(ListCat: 'brouette')),
title: Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(MediaQuery.of(context).size.width / 4),
child: Text(
_currentCat,
style: const TextStyle(
color: Colors.black,
fontSize: 16.0,
fontWeight: FontWeight.w700,
),
)),
),
SliverFixedExtentList(
itemExtent: 110.0,
delegate: SliverChildListDelegate(
[
for (int index = 0; index < 5; index++)
CustomListItem2(
thumbnail: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: AspectRatio(
child: Image.network(
growableList[index],
width: 100.0,
height: 100.0,
fit: BoxFit.fill,
),
aspectRatio: 1 / 1,
)),
title: 'Chez Luigi',
subtitle: 'Les meilleurs pizza hors d\'italie.',
ListCat: 'Food Truck',
),
],
),
)
],
),
);
}
Do you have any idea what can have caused this padding and how to resolve this problem ?
wrap your secound class with scaffold
Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height ,),
...................
)

What is the best flutter widget to use to achieve this kinda layout?

This is the UI I want to implement, I only started playing with flutter last week so I am not as fluent. I was wondering what is the best way to achieve this layout.
This is what I get with a stack and column:
This is the code:
Column(
children: <Widget>[
Expanded(
child: Container(
constraints: BoxConstraints.expand(height: 150),
color: Colors.blue,
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
bottom: -40,
left: MediaQuery.of(context).size.width * 0.4,
// alignment: Alignment.bottomCenter,
child: Container(
constraints: BoxConstraints.expand(height: 80, width: 80),
color: Colors.green,
),
),
],
),
),
flex: 3,
),
Expanded(
child: Container(
margin: EdgeInsets.all(15.0),
color: Colors.red,
),
flex: 7,
)
],
);
I made something like the image you provided with dummy image and some icon you can change icons if you want,use media query size instead of fixed padding tops
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
Stack(children: [
Container(
child: FittedBox(
fit: BoxFit.fill,
child: Image.network('https://picsum.photos/300?image=10')),
height: 150,
width: double.infinity,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.only(top: 75),
child: MaterialButton(
onPressed: () {},
elevation: 2.0,
color: Colors.red,
child: Icon(
Icons.message,
size: 27.0,
),
padding: EdgeInsets.all(20),
shape: CircleBorder(),
),
),
Padding(
padding: const EdgeInsets.only(top: 75),
child: Column(children: [
CircleAvatar(
radius: 55.0,
backgroundImage:
NetworkImage('https://i.pravatar.cc/150?img=54'),
backgroundColor: Colors.transparent,
),
Text("David Beckham"),
Text("Model/SuperStar")
]),
),
Padding(
padding: const EdgeInsets.only(top: 75),
child: MaterialButton(
onPressed: () {},
elevation: 2.0,
color: Colors.blue,
child: Icon(
Icons.add,
size: 27.0,
),
padding: EdgeInsets.all(20),
shape: CircleBorder(),
),
),
],
),
]),
Container(height: 100, color: Colors.red),
Container(height: 100, color: Colors.green),
Container(height: 100, color: Colors.yellow),
Container(height: 100, color: Colors.blue),
],
)));
}
}

Gridview.count Flutter not working and showing yellow and black stripes

I did a Gridview.count for rendering 6 buttons in 2 columns and 3 rows, it's not rendering and instead of the components, it shows yellow and black stripes. I already set the height and the width, all wrapped in a container.
return Scaffold(
body: Container(
height: 450.0,
width: double.infinity,
child: GridView.count(
shrinkWrap: true,
primary: true,
crossAxisCount: 2,
children: <Widget>[
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Wifi')
]),
),
),
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Key/Access')
]),
),
),
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Key/Access')
]),
),
),
Center(
child: FlatButton(
onPressed: () => {},
padding: EdgeInsets.all(10.0),
child: Column(children: <Widget>[
Image.asset(
'assets/img/wifi.png',
height: 50.0,
width: 50.0,
),
Text('Key/Access')
]),
),
),
],
)));
}
}
Please, someone knows why it's not rendering properly? or have an alternative widget that might work better? Thanks.
This widget is imported in this one:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF88B4E0),
appBar: AppBar(
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(Icons.arrow_back_ios),
color: Colors.white,
),
backgroundColor: Colors.transparent,
elevation: 0.0,
title: Text('Help and FAQ',
style: TextStyle(fontSize: 18.0, color: Colors.white)),
centerTitle: true,
actions: <Widget>[
SearchButton(),
],
),
body: ListView(children: [
Stack(children: [
Container(
height: MediaQuery.of(context).size.height - 82.0,
width: MediaQuery.of(context).size.width,
color: Colors.transparent),
Positioned(
top: 75.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(45.0),
topRight: Radius.circular(45.0),
),
color: Colors.white),
height: MediaQuery.of(context).size.height - 100.0,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
SizedBox(height: 20.0),
Testing(),
],
),
)),
]),
]),
);
}
void moveBack() {
Navigator.pop(context);
}
}

How to make a Card lies between Body in flutter

Anybody how to do the layout similar to the image? I am having difficulty on the CardView and it position is lies between the body. I am still consider quite new to Flutter, having some difficulty in UI part. Full code is as below:
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: Size.fromHeight(45.0),
child: AppBar(
automaticallyImplyLeading: false,
elevation: 0.0,
centerTitle: true,
backgroundColor: Color(0xFFED2849),
leading: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: const EdgeInsets.only(left: 8.0),
child: GestureDetector(
onTap: (){
Navigator.of(context).pop(null);
},
child: Image.asset('assets/ic_user_title_back.png', width: 12.0, height: 12.0,),
),
),
],
),
title: Center(
child: Container(
child: Text(
'账号中心',
style: TextStyle(color: Color(0xFFFFFFFF), fontSize: 14),
),
),
),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: GestureDetector(
onTap: (){
//logout
},
child: Text(
'退出登陆',
style: TextStyle(color: Color(0xFFFFFFFF), fontSize: 11),
),
),
),
],
),
)
],
)
),
body: SafeArea(
top: false,
child: Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 3,
child: Container(
color: Color(0xFFED2849),
),
),
Expanded(
flex: 7,
child: Container(
color: Color(0xFFF1F1F1),
),
)
],
),
),
)
);
}
You can do this using Stack
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
// fit: StackFit.expand,
children: [
Column(
children: [
Expanded(
flex: 3,
child : Container(color: Colors.red)
),
Expanded(
flex: 7,
child: Container(
color : Colors.white)
)
]
),
Positioned(
top: MediaQuery.of(context).size.height * 0.2,
left: 20,
right: 20,
child:Card(
child: Padding(
padding : const EdgeInsets.all(16),
child: Text("Your Text here", ),
),)
)
],
)
Try using Stack() it will allow you to overlap several children in a simple way.