I would like to Set Full-Screen Background Image to Scaffold Container, but don't know how? Here is my code:
#override
Widget build(BuildContext context) {
_deviceHeight = MediaQuery.of(context).size.height;
_deviceWidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: Theme.of(context).hintColor,
appBar: AppBar(
backgroundColor: Theme.of(context).accentColor,
title: Text(this.widget._receiverName),
),
body: ChangeNotifierProvider<AuthProvider>.value(
value: AuthProvider.instance,
child: _conversationPageUI(),
)
);
}
wrap your scaffold with container and set its decoration
Container(
decoration: BoxDecoration(image: DecorationImage(image: AssetImage("... your image"))),
child: Scaffold(),
);
dont forgot to set scaffold background to Colors.transparent
Related
I have a Flutter app which I'm building for Android. The structure goes broadly like this:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("")),
body: SingleChildScrollView(
child: Container(
decoration: const BoxDecoration(
gradient: ...
),
child: ...
),
)
);
}
The goal here is to have the gradient background fill all the screen below the app bar, and if the content is larger than that space then to make it scrollable.
If I omit the SingleChildScrollView, the Container fills the space. But of course if it overflows then there is no scrolling. With the code as above, the scroll view does its thing on small screens but on large screens the gradient background doesn't fill the whole available area.
If I change it around like this:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("")),
body: Container(
decoration: const BoxDecoration(
gradient: ...
),
child: Column(children: [
SingleChildScrollView(
child: ...
),
Expanded(child:Container())
]),
)
);
}
then the gradient fills the background but the scroll view doesn't do the right thing - the content overflows the screen but can't be scrolled. How do I get it to do both?
The reason you're facing this issue is that your container is inside the SingleChildScrollView Widget and is getting scrolled along the SingleChildScrollView Widget. And Removing the SingleChildScrollView will result in renderflex overflow error
The Expanded keyword will throw incorrect use of ParentDataWidget
Also, you have added SingleChildScrollView widget inside the column you have to swap these well
Here is an example that I have given which will help you achieve it.
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// Add The Container gradient here
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: Column(
children: [
Container(
height: 100,
width: 50,
color: Colors.red,
),
Container(
height: 100,
width: 50,
color: Colors.blue,
),
Container(
height: 1000,
width: 50,
color: Colors.yellow,
),
Container(
height: 1000,
width: 50,
color: Colors.orange,
),
],
)),
));
}
I am working on a project where I am using a custom AppBar and hence using PreferredSize but I am getting a error stating that:
The superclass 'PreferredSize' doesn't have a zero argument constructor. Try declaring a zero argument constructor in 'PreferredSize', or explicitly invoking a different constructor in 'PreferredSize'.
Here's my part of the code:
class CustomAppBar extends PreferredSize {
final Widget child;
final double height;
CustomAppBar({required this.child, required this.height}); //getting error on this line
#override
Size get preferredSize => Size.fromHeight(height);
#override
Widget build(BuildContext context) {
return Container()
}
}
Edit :
After removing PreferredSize got this error:
The named parameter 'child' isn't defined. Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'child'.
appBar:
PreferredSize(
preferredSize:Size.fromHeight(95),
child:
AppBar(
child: Column(
children: <Widget>[
SizedBox(height: 40),
Row(
children: <Widget>[
Builder(
builder: (context) => FlatButton.icon(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: Icon(Icons.menu),
label: Text('')),
),
SizedBox(width: 60),
Text('Times ',
style: GoogleFonts.blackHanSans(
textStyle:
TextStyle(color: Colors.black, fontSize: 20))),
Image.asset(
'assets/newss.png',
height: 50,
),
],
)
You may not even have to extend PreferredSize you may just wrap an appBar or any other widget inside a PreferredSize and just specify its height.
PreferredSize(
preferredSize: Size.fromHeight(72),
child: AppBar(
title: Text(title, style: TextStyles.h1),
centerTitle: false,
elevation: 0,
brightness: Brightness.light,
backwardsCompatibility: false,
bottom: bottomAppBarWidget,
))
I have set the statusbar color to transparent. But still not the same with Appbar.
// on main method
if (Platform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle =
SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
// on a widget build method
Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
brightness: Brightness.light,
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0,
title: Text('发现', style: BMTextStyle.black_56),
),
body: SafeArea(
top: false,
child: TabBarView(controller: _controller, children: <Widget>[
_buildPageContentAccordingIndex(0),
_buildPageContentAccordingIndex(1),
]),
),
),
The result is the statusbar color seems gray, and the Scaffold is white. So how to make them the same? Thank you!
You want to use AnnotatedRegion inside each Stateful Widget (basically every screen) you make adjustments to regarding the status bar. I previously did it some other way, but AnnotatedRegion makes sure the status bar updates its style again when you use Navigator.pop(context) to come back to this screen. Just wrap the Scaffold around with AnnotatedRegion and set the value to your systemUiOverlayStyle variable like so:
#override
Widget build(BuildContext context) {
SystemUiOverlayStyle _statusBarStyle = SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
);
return AnnotatedRegion(
value: _statusBarStyle,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
brightness: Brightness.light,
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0,
title: Text('发现', style: BMTextStyle.black_56),
),
body: SafeArea(
top: false,
child: TabBarView(controller: _controller, children: <Widget>[
_buildPageContentAccordingIndex(0),
_buildPageContentAccordingIndex(1),
]),
),
),
);
}
Hope this helped.
I have made
appbar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0
),
Still I'm getting this
How to get that seamless transition between the Scaffold and the notification center?
Use this if you want your application to use transparent statusbar. Transparent status bar in flutter
#override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
),
child: MaterialApp(
title: 'Test',
);
}
I'm trying to create a test app that contains 2 widgets in a column.
The first should occupy 0.2 of the available height, and the second should occupy 0.8 of the available height. The latter is a scrollable widget.
In order to calculate the available height, I need 3 properties: screen height, status bar height, and appbar height.
I got screen height and appbar height.
From extensive search, I should be able to get status bar height with mediaQuery.padding.top, however it returns 0. Any idea why?
Currently, the bottom is overflowed by 24 pixels, which is clearly the status bar's height.
var availableHeight = mediaQuery.size.height - mediaQuery.padding.top - appBar.preferredSize.height; //737 - 0 - 56
I'm testing it in the android emulator on windows. Device: Pixel 3, OS: Android Pie.
I realized I can do this out of the box with LayoutBuilder without having to manually calculate the available height, but I'm still interested in the answer.
Here's the full code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
AppBar appBar = AppBar(title: Text("Test"));
return MaterialApp(
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: appBar,
body: SafeArea(child: Test(appBar))
)
);
}
}
class Test extends StatelessWidget {
final AppBar appBar;
Test(this.appBar);
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
var availableHeight = mediaQuery.size.height - mediaQuery.padding.top - appBar.preferredSize.height; //737 - 0 - 56
return Column(
children: <Widget>[
Container(
color: Colors.green,
height: availableHeight * 0.2,
),
Container(
height: availableHeight * 0.8,
child: getScrollable()
)
]
);
}
Widget getScrollable() {
return SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
color: Colors.amber,
height: 600.0
),
Container(
color: Colors.red,
height: 600.0
),
],
)
);
}
}
No need to calculate anything. Use Flex and Flexible to define how much space each child should take in relation to the space available:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
AppBar appBar = AppBar(title: Text("Test"));
return MaterialApp(
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: appBar,
body: SafeArea(child: Test(appBar))
)
);
}
}
class Test extends StatelessWidget {
final AppBar appBar;
Test(this.appBar);
Widget build(BuildContext context) {
return Flex(
direction: Axis.vertical,
children: <Widget>[
Flexible(
flex: 2,
child: Container(
color: Colors.green,
),
),
Flexible(
flex: 8,
child: getScrollable(),
)
],
);
}
Widget getScrollable() {
return SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
color: Colors.amber,
height: 600.0
),
Container(
color: Colors.red,
height: 600.0
),
],
)
);
}
}