Screen compatible to all devices in flutter - flutter

How to Adjust the screen to all android devices screens in flutter. I have checked in stackoverflow but unfortunately i haven't got any satisfying answer.

Basically, Flutter automatically sets the height and width depending on the device sizes wherever possible. Example - if you have use a list view having 100 items then some devices may show 5 items at a time and some may show 6 items. It is automatically done by Flutter.
The problem comes only when you specify an absolute value for height and/or width. Let's say you've a widget and you specify width as 450. Now, it may fit on the bigger screens but on the small screen (e.g. width 400 points)then you'll see pixel overflow error in the UI.
Now, to solve this problem, you can use MediaQuery.of(context).size.height/width as suggested by LGM.

I think you have some questions about responsive layouts, so i will give you some examples with MediaQuery:
With MediaQuery you can get the device screen width:
double width = MediaQuery.of(context).size.width;
The height:
double height = MediaQuery.of(context).size.height;
as well as the orientation:
Orientation orientation = MediaQuery.of(context).orientation;
and also various information about the device, and then, you can base the layout on orientation, size etc.
Here's an example:
Container(
width: MediaQuery.of(context).orientation == Orientation.portrait ?
MediaQuery.of(context).size.width / 1.3 : MediaQuery.of(context).size.width / 2.1,
child: RaisedButton(
elevation: 0.0,
color: Colors.green,
child: Text("CONTINUE", style: TextStyle(color: Colors.white),),
onPressed: (){
//code of onPressed
);
}
),
),
You can use too Align, to define where the widget should be, Positioned, the properties of Column, Center etc.
One more example, using FittedBox to deal with texts:
#override
Widget build(BuildContext context) {
return Material(
child: SafeArea(
child: Scaffold(
body: ListView(
children: <Widget>[
FittedBox(child: Text("Test"),),
FittedBox(child: Text("Flutter Flutter Flutter"),)
],
),
),
),
);
}
The result:
Portrait:
Landscape:

Related

Flutter: how to create widget positioned relative to the screen?

Basically I need to create some kind of Snackbar widget that can be created on any page. So I need to make it positioned relative to the screen. The only idea is to create the main Stack widget which will wrap all other pages. Do you have any other ideas? I found pretty similar question without any interesting answers
By using Mediaqueryto retrieve the screen size.
For example we can the screen width like this :
MediaQueryData screenSize = MediaQuery.of(context).size.width;
let's say i want my container's size to take up half the screen's size
One way to go about it is like this :
Container(
height: MediaQuery.of(context).size.height/2,
width: MediaQuery.of(context).size.width/2,
child: Text('This container is half this device screen's size');
);
What you are going for here is using the Positioned widget
Let's take the last example and leave a quarter of the screen on every side :
Container(
height: MediaQuery.of(context).size.height/2,
width: MediaQuery.of(context).size.width/2,
child: child: Stack(
children: <Widget>[
Positioned(
left: MediaQuery.of(context).size.width/4,
top: MediaQuery.of(context).size.height/4,
right: MediaQuery.of(context).size.width/4,
bottom: MediaQuery.of(context).size.height/4,
child: Text('This container is half this device screen's size'),
),
],
),

Flutter - Responsive Image mapping?

Good Evening,
I have been searching for many hours and can not find a solution.
I have set a full screen image and with a Stack I have Positioned several GestureDetectors.
I have succeeded to be able to press on a GestureDetector and call a Function.
The problem is that when the screen size changes, either to a new or older phone then the Image responds and covers the full screen but the Positioned() of course stay at the same place, thus the Image mappings are not correct any more.
Is there a way to make the Positioned be responsive? or Maybe a total different way achieving the desired outcome?
Please help me :)
class Overview extends StatelessWidget {
#override
Widget build(BuildContext context) {
double sh = MediaQuery.of(context).size.height;
double sw = MediaQuery.of(context).size.width;
return Scaffold(
drawer: AppDrawer(),
body: Stack(
children: <Widget>[
Container(
height: sh,
width: sw,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/ang7.png'),
fit: BoxFit.cover)),
),
Positioned(
left: 10,
top: 50,
child: IconButton(
icon: Icon(Icons.menu),
iconSize: 30,
color: Colors.white,
onPressed: () => Scaffold.of(context).openDrawer(),
),
Positioned(
left: left,
top: top,
child: GestureDetector(
// child: Icon(Icons.add_circle),
onTap: () => Navigator.push(context, MaterialPageRoute(
builder: (context) {
return Amenities(
tText[page][0],
tText[page][1],
tText[page][2],
);
},
)),
child: Container(
height: 35,
width: 50,
color: Colors.blue,
),
));
),
Posting my comment as an answer just in case it works and there are no better answers provided. Please up vote and mark as answered if it does. :-)
You could try experimenting with MediaQuery.of to determine the size of the device (height and width) and then use those values to scale the Positioned widgets position parameters up or down from your 'baseline' sizes. In theory that should (may) match how the background image has been scaled. Would probably need to scale the size of the Positioned widgets as well.
Update regarding your comment:
Not really. What I mean is that you would need to run MediaQuery.of on the device that you are happy with the UI layout, and record that device's width and height. You then use this width and height in your app and compare these 'baseline' values with what values you get when you run the app on other devices.
So:
Divide other-device-width by baseline-device-width to get your width scaling factor.
Divide other-device-height by baseline-device-height to get your height scaling factor.
Then use these scaling factors to 'scale' the Positioned widgets width (positioned-widget-width multiplied by width-scaling-factor) and height (positioned-widget-height multiplied by height-scaling-factor) and position on the screen (you would have to play around with the positioning values).
Sounds messy but it is just a bit of simple math.
Like I say, might not work or might not be the most elegant solution. There are so many different devices out there you will never really be able to completely test this. Might need to rethink you UI. Maybe some other people have ideas around that.

Flutter responsiveness problem on various mobile devices

I am a beginner to Flutter and I tried creating a dummy login page. When I tried to run the app it was flawless on Pixel 3 XL but it was not good in Pixel 2 XL. How would I manage the responsiveness? I came across the MediaQuery widget, but how could I create a completely responsive app for each device? There are many variations among today's mobile devices (like notched display, fullscreen, etc) and thereafter comes the tablets. How could I manage this? Should I write code for each and every resolution?
Here is my design on Pixel 3 XL and Pixel 2 XL
You can use SingleChildScrollView as parent,
SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
),
),
);
Edit: Also remove fit: StackFit.expand, from Stack widget.
The reason behind this problem is the sizedbox widget with height 100px.
removing that and using mainaxisalignment as spaceevenly gives the required output.
Here is the modified code:
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Stack(
fit: StackFit.expand,
children: <Widget>[
bgimage,
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
logoimage,
userName(),
password(),
forgotPassword(),
loginButton(),
googleSignIn(),
signUp()
],
),
],
),
);
}
This solves the problem.
Best easiest way to make responsive UI for different screen size is Sizer plugin.
Responsive UI in any screen size device also tablet.
Check it this plugin ⬇️
https://pub.dev/packages/sizer
.h  - for widget height
.w  - for widget width
.sp - for font size
Use .h, .w, .sp after value like this ⬇️
Example:
Container(
height: 10.0.h, //10% of screen height
width: 80.0.w, //80% of screen width
child: Text('Sizer', style: TextStyle(fontSize: 12.0.sp)),
);
I have build many responsive UI with this plugin.
Use this package flutter_next using this you design responsive UI even for desktop web and everything and they have an demo also so you can check there

BoxConstraints forces an infinite height

child:Column(
children: <Widget>[
Container(
height: double.infinity,
width: 100.0,
color: Colors.red,
child: Text('hello'),
),)
in this,when i make height:double.infinity,it gives error in run saying **BoxConstraints forces an infinite height.**but when i give height manually it work fine.
can anyone explain me why this happening.
How about this one.
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
Expanded(
child: Container(
// height: double.infinity,
width: 100.0,
color: Colors.red,
child: Text('hello'),
),
),
],
),
),
);
}
}
This means that you can't offer inifite height to the container. It's obvious behaviour if you don't provide the contraints to height.
You have to specify limited height to the container so that flutter can render it, if you offer it infinite it how can flutter render that and up to which constraints it would do that !
Rather you can set double.infinity to width and flutter will successfully render that because by default flutter has constraints for width it will set width to width of screen.
Considering that you have to provide height as that of screen you can use MediaQuery for that
Widget yourMethod(or build)(BuildContext context){
final screenHeight = MediaQuery.of(context).size.height;
return Column(
children:<Widget>[
Container(
height:screenHeight,//but this will be height of whole screen. You need to substract screen default paddings and height of appbar if you have one
width:100.0,
....
)
]);
}
Hope this helps !
Happy coding..
BoxConstraints forces an infinite height
Why This Happens
You're asking to render an infinite height object without a height constraint... Flutter can't do that.
Column lays out children in two phases:
Phase 1: non-Flex items (anything not Expanded, Flexible or Spacer)
done in unconstrained space
Phase 2: Flex items (Expanded,Flexible, Spacer only)
done with remaining space
Phase 1
Column's phase 1 vertical layout is done in unbounded space. That means:
no vertical constraint → no height limit
any widget with infinite height will throw the above error
you can't render an infinite height object in an infinite height constraint... that's goes on forever
Phase 2
after Phase 1 widgets have taken as much space as they intrinsically need, phase 2 Flex items share the remaining/leftover space
the remaining space is calculated from incoming constraints minus Phase 1 widgets dimensions
double.infinity height will expand to use up the remaining space
Infinite Height is OK
Here's an example of using infinite height on a Container inside a Column, which is fine:
class ColumnInfiniteChildPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Flexible(
child: Container(
height: double.infinity, // ← perfectly fine
child: Text('Column > Container > Text')),
),
Text('Column > Text')
],
),
),
);
}
}
Remove the Flexible and the error will be thrown.

Flare and Flutter with different devices (screens)

i am doing my first steps with flare and flutter and right now its really nice to be able to put animations into flutter without coding them by hand. But i dont understand how to make the flare thingy responsive (how to support different screen sizes).
This is part of a splash screen:
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(250, 224, 61, 1.0),
body: Center(
child: Container(
child: FlareActor(
"assets/flare/splash.flr",
callback: (nameOfAnimation) =>
Navigator.pushReplacementNamed(context, "/login"),
fit: BoxFit.none,
animation: "splash",
)),
));
}
This works well on my iPhone X because the animation is designed for that size. Is there any way how a smaller device can be able to use this same flare animation? Testing this with iPhone SE resulted in a clipped animation.
I hope there is another way than creating several animations for several screen sizes.
Just add your animation as a child of a SizedBox and give it a width/height and you’ll be fine.
You can also use the MediaQuery.of(context).size.width or height to get the viewport dimensions and set your SizedBox to use a % of the screen accordingly, if you want to.
you can use MediaQuery with the current context of your widget and get width or height in your container or sizedbox like this
width: MediaQuery.of(context).size.width * 0.65
height: MediaQuery.of(context).size.width * 0.65
else If you have a single widget you can use a FractionallySizedBox widget to specify a percentage of the available space to fill
FractionallySizedBox(
widthFactor: 0.7,
heightFactor: 0.3,
child:FlareActor(
"assets/flare/splash.flr",
callback: (nameOfAnimation) =>
Navigator.pushReplacementNamed(context, "/login"),
fit: BoxFit.none,
animation: "splash",
)),
);