How to fit image as the background of status bar in flutter? - flutter

I am trying to apply image in the background of the status bar in an flutter project. So which widget can help me to apply the following expected result.
detailpage.dart
import 'package:flutter/material.dart';
class MyDetailPage extends StatefulWidget {
#override
_MyDetailPageState createState() => _MyDetailPageState();
}
class _MyDetailPageState extends State<MyDetailPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
height: 300,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/image2.png"),
fit: BoxFit.fitHeight,
),
),
)
],
),
);
}
}

Use Scaffold property
extendBodyBehindAppBar: true, and
set statusBarColor: Colors.transparent
This code is for status bar colour.
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent
));
Here is an example of code in my current project.
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent
));
return Scaffold(
extendBodyBehindAppBar: true,
body: Column(
children: [
Container(
height: 250,
child: Container(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
width: screenWidthPercentage(context,percentage: 1),
child: Image.network(
contentImage,
fit: BoxFit.cover,
),
),
Padding(
padding: const EdgeInsets.only(top: 48.0,left: 12),
child: Icon(Icons.arrow_back,color: Colors.white,),
),
],
),
),
),
],
),
);
}
}

you can do it by not keeping SafeArea widget and set statusbar color as transparent.
I have created an example as below.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FullScreen extends StatefulWidget {
const FullScreen({Key? key}) : super(key: key);
#override
_FullScreenState createState() => _FullScreenState();
}
class _FullScreenState extends State<FullScreen> {
#override
void initState() {
super.initState();
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light
//color set to transperent or set your own color
)
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: buildBody(),
);
}
Widget buildBody() {
return SizedBox(
height: 400,
width: double.infinity,
child: Card(
clipBehavior: Clip.antiAlias,
margin: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40),
bottomRight: Radius.circular(40)),
),
child: Image.network(
'https://source.unsplash.com/random',
fit: BoxFit.cover,
),
),
);
}
}
I have added card as it gives nice elevation effect to the image 😎 .
FYI keep margin as 0 in card if you are using card.

You can achieve it using FlexibleSpaceBar, here is the example code.
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 300,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset("assets/images/chocolate.jpg", fit: BoxFit.cover),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text("Item ${index}")),
childCount: 100,
),
),
],
),
);
}

When we using a ListView on a top tree,
The ListView makes a default padding.top even without a SafeArea.
So we need a
padding: EdgeInsets.zero.

Related

Flutter : Let big image overflow inside stack

I'm trying to let my users increase the size of an image inside a fixed size Stack.
The chosen size can be way above the Stack's size.
This is the result I get for now, even though the image :
Here is the relevant code :
Expanded(
child: AspectRatio(
aspectRatio: myCustomScreen.width / myCustomScreen.height,
child: ClipRRect(
borderRadius: BorderRadius.circular(14),
child: LayoutBuilder(
builder: (context, boxConstraint) {
return Stack(
alignment: Alignment.center,
fit: StackFit.passthrough,
children: [
Container(
color: Colors.blue,
),
//This object doesn't overflow when its width is above the
UnconstrainedBox(
child: Image(
width: (object.width.toDouble() * boxConstraint.biggest.width) / myCustomScreen.width,
image: NetworkImage("www.images.com/image.png", scale: 1)),
),
],
);
},
),
),
),
),
How can I let my users view the real size of the image inside this view without being constrained by the stack ?
Thank you !
Stack has a property called clipBehavior you can use it like this to enable overflow:
Stack(
clipBehavior: Clip.none,
// Your code continues here
Edit: Testing your code I made ti work on dart pad. The steps were, remove the UnconstrainedBox and used the image scale to resize it alongside with the fit property defined as none:
here's the code that I used on darted: https://dartpad.dartlang.org/
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
Expanded(
child: AspectRatio(
aspectRatio: 200 / 400,
child: ClipRRect(
borderRadius: BorderRadius.circular(14),
child: LayoutBuilder(
builder: (context, boxConstraint) {
return Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
fit: StackFit.passthrough,
children: [
Container(
color: Colors.blue,
),
Image(
fit: BoxFit.none,
image: NetworkImage(
"https://images.pexels.com/photos/13406218/pexels-photo-13406218.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
scale: 1 / (_counter + 1),
),
),
],
);
},
),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}

Border (Flutter)

How to put the widgets inside the mobile so that the picture is like a border, I want to put the widget inside the mobile frame, how can I do that?
Code:
Container(
decoration: BoxDecoration(
border: MobileImage(),
),
child: Widgets(),
),
You can try this code & I have added a screenshot also for your favor.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: FractionallySizedBox(
widthFactor: 0.9,
heightFactor: 0.9,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/iphone13.png"),
fit: BoxFit.fill,
),
),
child: Container(),
),
Positioned(
child: FractionallySizedBox(
widthFactor: 0.8,
heightFactor: 0.9,
child: Container(
alignment: Alignment.centerLeft,
child: ListView.separated(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(
title: Text('Text ${index+1}'),
);
},
separatorBuilder: (context, index) {
return const SizedBox(height:10);
},
),
),
),
),
],
),
),
),
));
}
}
N.B: Here, "assets/images/iphone13.png" are the iPhone background image.
you can do like this,
Container(
decoration: BoxDecoration(
border: //your border,
image: DecorationImage(image: AssetImage(MobileImage()))
),
child: Widgets(),
),
and also u can use the stack widget to Put The Widgets Inside the border Image

Flutter full width Container

I am trying to make Container full width but its not working
void main() {
runApp(MaterialApp(
title: "Practice",
home: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: Text("My Awesome Border"),
)
],
),
],
),
));
}
this is output in browser
I have couple of more questions
Why color of text is Red and size is big?
How there is a yellow line under text?
Update
Resolved issue with MediaQuery. Here is full working code for future readers.
void main() {
runApp(MaterialApp(
title: "Practice",
home: Scaffold(
body: MyHomeScreen(),
)));
}
class MyHomeScreen extends StatelessWidget {
const MyHomeScreen({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.orange,
border: Border.all(color: Colors.blueAccent)),
child: Text("My Awesome Border"),
)
],
)
],
);
}
}
There are several possibilities
1- Use MediaQuery.of(context).size.width,
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.orange,
border: Border.all(color: Colors.blue)),
child: Text("My Awesome Border"),
)
Here, make sure that your container has a parent that has context
2- Use double.infinity
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.orange,
border: Border.all(color: Colors.blue)),
child: Text("My Awesome Border"),
)
3- Use FractionallySizedBox widget
Creates a widget that sizes its child to a fraction of the total available space.
Example :
FractionallySizedBox(
widthFactor: 1.0, // between 0 and 1 // 1 for max
heightFactor: 1.0,
child:Container(color: Colors.red
,),
)
4- Use other widgets such as Expanded , Flexible and AspectRatio and more .
Output :
You can write:
Container(
width: double.infinity,
child: Text("My Awesome Border"),
)
I'm used to work with flutter for mobile devices and this kind of error usually happen when we don't have a Scaffold as the base widget. I mean, we can have a SafeArea that has a Scaffold as child, but I don't think we can use a Column as root. So try putting a Scaffold and setting the Column as Scaffold's body. Hope this answer helps you somehow!
By Using the LayoutBuilder a parent widget for your widget and set the constraint.maxWidth to your container to fill the Width.
LayoutBuilder(
builder: (context, constraint){
return Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: constraint.maxWidth,
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: Text("My Awesome Border"),
)
],
),
],
);
},
),
Hope it will you to achieve your requirement.
You have missed wrapping the child widget inside the Scaffold Widget like below so that only its showing a red color text and yellow line
void main() {
runApp(MaterialApp(
title: "Practice",
home: CartScreen()
));
}
class CartScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your Cart'),
),
body: LayoutBuilder(
builder: (context, constraint){
return Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: constraint.maxWidth,
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: Text("My Awesome Border"),
)
],
),
],
);
},
),
);
}
}
Because you have used Column within MaterialPage without Scaffold or CupertinoScaffold. So if you wrap Your Column with Scaffold then you’ll see the Text’s yellow underlines removed and the text will be black.
And I see one other problem with your code, is it the wrong format for dart so it’s not readable so I mean it is not clean code.
Fully formatted code:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: buildBody(),
),
);
}
Widget buildBody(){
return Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: Text("My Awesome Border"),
)
],
),
],
);
}
}
You are missing the Scaffold widget. Try using the scaffold widget before the column widget. It will fix the issue

Is there a screen problem with stack in flutter

My problem is because
I have a image at the top of the screen and under the image is the rest of body scaffold, but that has a rounded corners
I used the Stack with positioned to appbar floating and transparent, the container below appbar, but I can't do the rounded corners of the container with this stack, this is what I'm doing
Scaffold(
body: Stack(
children: <Widget>[
SingleChildScrollView(
child: ...
)
Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: AppBar(
...
),
),
],
),
)
After tried this, I could not do this container with rounded corners and I got this
You can use Stack and Position widget to achieve so.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: MyHomePage(),
));
class MyHomePage extends StatefulWidget {
#override
MyHomePageState createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
final upperbodypartheight = 230;
final double rounded = 30;
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/crown.png"),
fit: BoxFit.cover,
),
),
height: 230,
child: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
title: Text("title"),
),
),
Positioned(
bottom: 0,
child: Container(
height: MediaQuery.of(context).size.height -
upperbodypartheight +
rounded,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(rounded),
topRight: Radius.circular(rounded))),
),
),
],
);
}
}

Flutter: sliverAppBar resize issue on list scroll

I want to make sliverAppBar resized while scrolling list below it.
Now there are two issues:
1) sliverAppBar doesn't resize while I am scrolling list (screenshot)
2) I can't find example/solution how to resize child content of sliverAppBar when it change height (screenshot)
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar( // <-- how to resize on scrolling ListView?
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: SafeArea(
child: Column(
children: [
Row( // <-- how to make it flexible/resizable?
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/user.png',
fit: BoxFit.cover,
width: 120,
)
],
),
],
),
)
),
SliverFillRemaining(
child: ListView.builder(
shrinkWrap: false,
itemCount: widget.europeanCountries.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(widget.europeanCountries[index]),
);
},
),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Use [FlexibleSpaceBar] and [SliverList]
[SliverList] can change the size of [sliverAppBar] when scrolling the list
[FlexibleSpaceBar] prevents border overflow
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
ScrollController controller = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: true,
pinned: true,
flexibleSpace: LayoutBuilder(
builder: (context, bc) {
double size = min(
// bc.constrainHeight() - MediaQuery.of(context).padding.top,
bc.constrainHeight(),
120);
return FlexibleSpaceBar(
centerTitle: true,
// title: Container(
// width: size,
// height: size,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// image: DecorationImage(
// image: NetworkImage(
// 'https://i.loli.net/2019/08/09/OvVzMqpF3jmI8lE.jpg'),
// fit: BoxFit.cover,
// ),
// ),
// ),
background: Center(
child: Container(
width: size,
height: size,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(
'https://i.loli.net/2019/08/09/OvVzMqpF3jmI8lE.jpg'),
fit: BoxFit.cover,
),
),
),
),
);
},
),
),
SliverList(
//
delegate: SliverChildBuilderDelegate(
(context, index) {
return ListTile(
title: Text("Text"),
);
},
childCount: 100,
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}