Hi I created 3 containers but when I use a different device it obviously doesn't scale properly. How can I set as a Container as a specific size to any device. This is my code.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Welcome to my app"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(padding: EdgeInsets.fromLTRB(450.0, 0.0, 100.0, 0.0)),
Container(
height: MediaQuery.of(context).size.height - 100,
color: Colors.grey[600],
),
Container(
color: Colors.amber,
height: MediaQuery.of(context).size.height - 100,
),
Container(
color: Colors.black,
height: MediaQuery.of(context).size.height - 100,
),
],
),
),
);
}
}
Use MediaQuery widget:-
Container(
color: Colors.amber,
height: MediaQuery.of(context).size.height - 100, // set this calculation as per your requirement
),
Container(
color: Colors.teal,
height: MediaQuery.of(context).size.height - 200, // set this calculation as per your requirement
),
You can use Expanded Widgets and give it flex according to your requirements.
also you can use this flutter plugin to provide width and height in terms of %.
https://pub.dev/packages/responsive_flutter
// Example 20% of screen's width
ResponsiveFlutter.of(context).wp(20)
// Example 20% of screen's height
ResponsiveFlutter.of(context).hp(20)
I'm very new to flutter and I have been trying to create a modern drawer, and I have found one, the problem is the one I have found usesquadraticBezierTo and enddrawerwhich opens the drawer on the right to left but want to usedrawer which opens the drawer form left to right. here is my code
Widget build(BuildContext context) {
width = MediaQuery.of(context).size.width - 50;
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
drawerScrimColor: Colors.grey.shade900.withOpacity(0.5),
drawer: ClipPath(
clipper: _DrawerClipper(),
child: Drawer(
child: Container(
padding: const EdgeInsets.only(top: 48, bottom: 32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
color: Colors.blue.shade200,
child: DrawerHeader(
child:Wrap(
children:<Widget>[
Container(
alignment: Alignment.topCenter,
child: CircleAvatar(
maxRadius: 40,
child: Image.asset("assets/profile.png"),
),
),
Container(padding: EdgeInsets.fromLTRB(0, 10, 0, 0), alignment: Alignment.center,
child:Text("Name",style: TextStyle(fontSize: 20,color: Colors.white),
),
),
Container( alignment: Alignment.center,
child:Text("E-mail Address",style: TextStyle(fontSize: 20,color: Colors.white),
),
),
],
),
),
),
ListTile(
title: Center(
child: Text(
"Item1",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)),),],
)),),),
and I use the following class for the clipper:
class _DrawerClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = Path();
path.moveTo(50, 0);
path.quadraticBezierTo(0, size.height / 2, 50, size.height);
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0);
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}
and here is a photo of how it looks:
If I use endDraweit looks normal but in my case I want to use drawer. I assume it has something to do with the quadraticBezierTo parameters but i'm not sure. how can I fix this?
Thanks for the help
I am not able to scroll my flutter app body. As it is giving overflow error all the time. Please see the code below and help me.
Body.dart code
import 'package:flutter/material.dart';
import 'CustomGridview.dart';
class MyCustomBody extends StatefulWidget {
#override
_MyCustomBodyState createState() => _MyCustomBodyState();
}
class _MyCustomBodyState extends State<MyCustomBody> {
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return SingleChildScrollView(
child: Column(
children: [
Stack(
overflow: Overflow.visible,
children: [
CustomPaint(
painter: MyCustomPainter(),
child: ClipPath(
clipper: MyCustomClip(),
child: Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
color.custombarG1,
color.custombarG2,
],
),
),
height: height / 2 - 50,
width: width,
),
),
),
Positioned(
left: -40.0,
top: 10.0,
child: Image.asset(
'assets/images/covid3.png',
height: 310.0,
),
),
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 20.0, right: 2.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'CoVID-19',
style: TextStyle(
color: color.writingTitle,
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.all(3.0),
child: Text(
'TRACKER',
style: TextStyle(
color: color.primary,
fontSize: 30.0,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
height: 1.2,
),
),
),
Padding(
padding: const EdgeInsets.only(right: 40),
child: Text(
'+',
style: TextStyle(
color: color.writingHead,
fontSize: 35.0,
height: 0.75,
),
),
),
Padding(
padding: const EdgeInsets.only(right: 12.0),
child: Text(
'CASES',
style: TextStyle(
color: color.writingTitle,
fontSize: 30.0,
fontStyle: FontStyle.italic,
),
),
),
Text(
'IN SECONDS',
style: TextStyle(
color: color.writingSubHead,
fontSize: 35.0,
fontWeight: FontWeight.bold,
fontFamily: 'Poppins',
height: 1.5,
),
),
Text(
'WorldWide',
style: TextStyle(
color: color.writingTitle,
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontFamily: 'Poppins',
height: 3.5,
),
),
],
),
),
),
],
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.width / 1.5,
child: Card(
color: color.cardTotalBg,
child: Text(
'hello There',
),
),
),
],
),
);
}
}
class MyCustomClip extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = new Path();
path.lineTo(0.0, size.height - 80);
var firstCPoint = new Offset((size.width / 4) - 20, (size.height) / 2 - 50);
var firstEPoint = new Offset((size.width / 2 + 30), size.height - 70);
path.quadraticBezierTo(
firstCPoint.dx, firstCPoint.dy, firstEPoint.dx, firstEPoint.dy);
var secondCPoint = new Offset(size.width * 0.9, size.height + 60);
var secondEPoint = new Offset(size.width, size.height / 2 + 50);
path.quadraticBezierTo(
secondCPoint.dx, secondCPoint.dy, secondEPoint.dx, secondEPoint.dy);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}
class MyCustomPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Path path = new Path();
path.lineTo(0.0, size.height - 80);
var firstCPoint = new Offset((size.width / 4) - 20, (size.height) / 2 - 50);
var firstEPoint = new Offset((size.width / 2 + 30), size.height - 70);
path.quadraticBezierTo(
firstCPoint.dx, firstCPoint.dy, firstEPoint.dx, firstEPoint.dy);
var secondCPoint = new Offset(size.width * 0.9, size.height + 60);
var secondEPoint = new Offset(size.width, size.height / 2 + 50);
path.quadraticBezierTo(
secondCPoint.dx, secondCPoint.dy, secondEPoint.dx, secondEPoint.dy);
path.lineTo(size.width, 0.0);
path.close();
canvas.drawShadow(path, color.custombarG2, 30.0, false);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
This is home.dart code
import 'package:CovidTraces/body.dart';
import 'package:CovidTraces/constraints.dart';
import 'package:CovidTraces/customnavbar.dart';
import 'package:flutter/material.dart';
import 'customappbar.dart';
Constraints color = new Constraints();
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
CustomAppBar(),
MyCustomBody(),
],
),
bottomNavigationBar: MyCustomNavBar(),
),
);
}
}
Kindly help me please I am facing a lot of such errors in flutter.
In this I am not able to make my UI scrollable after using single child scroll view also.
Reason for the error:
Column expands to the maximum size in main axis direction (vertical axis), and so does the SingleChildScrollView.
Solutions
So, you need to constrain the height of the SingleChildScrollView. There are many ways of doing it, you can choose that best suits your need.
Use an Expanded widget to allow the SingleChildScrollView take up the remaining space.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
CustomAppBar(),
Expanded(
child: MyCustomBody(),
),
],
),
),
);
}
}
Limit the SingleChildScrollView to certain height using SizedBox
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
CustomAppBar(),
SizedBox(
height: 650,
child: MyCustomBody(),
),
],
),
),
);
}
}
EDIT: It is better to add Appbar to the scaffold instead of a child. Extends the PreferredSize Widget to your CustomAppBar class and put it inside the scaffold.
Sample:
class CustomAppBar extends PreferredSize {
final Widget child;
final double height;
CustomAppBar({#required this.child, this.height = kToolbarHeight});
#override
Size get preferredSize => Size.fromHeight(height);
#override
Widget build(BuildContext context) {
return
Container(
height: preferredSize.height,
alignment: Alignment.center,
child: child,
);
}
}
Using flutter, i need to place in the mobile device two blocks so that:
in vertical position block_A was on top, and block_B was on the bottom
in horizontal position block_A is on the left and block_B is on the right
image of result
I implemented this through Wrap, setting the width of the block based on the width of the current screen, and Wrap put down the block automatically. But I'm not sure if this is the right decision.
class MainPage extends StatelessWidget {
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
double mainBoxWidth = screenSize.width / 100 * (screenSize.width > screenSize.height ? 50 : 100) ;
double mainBoxHeight = screenSize.height / 100 * (screenSize.width > screenSize.height ? 100 : 50) ;
return Scaffold(
body: Center(
child: Wrap(
children: [
Container(
child: Center(
child: Text("block_A"),
),
width: mainBoxWidth,
height: mainBoxHeight,
),
Container(
child: Center(
child: Text("block_B"),
),
width: mainBoxWidth,
height: mainBoxHeight,
),
],
),
),
backgroundColor: Colors.green
);
}
}
Please tell me how to correctly implement this task. Thanks.
As with most things in Flutter, there are a few ways this could be done. Here's one way:
class MainPage extends StatelessWidget {
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
final isLandscape = screenSize.width > screenSize.height;
return Scaffold(
body: isLandscape
? Row(
children: _buildChildren(),
)
: Column(
children: _buildChildren(),
),
backgroundColor: Colors.white,
);
}
List<Widget> _buildChildren() {
return [
Expanded(
child: Container(
color: Colors.yellow,
child: Center(
child: Text("block_A"),
),
),
),
Expanded(
child: Container(
color: Colors.green,
child: Center(
child: Text("block_B"),
),
),
),
];
}
}
Clipping allows me to draw only the part which I want to show. How do I remove the extra part which is not drawn but still takes up space?
The code
import 'package:flutter/material.dart';
class ClipTut extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children: <Widget>[
ClipRect(
clipper: CustomRect(),
child: Container(
decoration: BoxDecoration(
border: Border.all(width: 4, color: Colors.black),
color: Colors.blue,
),
width: 200.0,
height: 200.0,
),
),
Container(
height: 200,
width: 100,
decoration: BoxDecoration(
border: Border.all(width: 4, color: Colors.black),
color: Colors.green,
),
)
],
),
),
);
}
}
class CustomRect extends CustomClipper<Rect> {
#override
Rect getClip(Size size) => Rect.fromLTRB(0, 0.0, size.width/2, size.height);
#override
bool shouldReclip(CustomRect oldClipper) => true;
}
My Solution
I had a similar problem recently (I needed to clip the image in half) and found this sample code on the flutter api site (use the other alignment points to change slicing behaviors) - no extra space left over:
ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: Image.network(userAvatarUrl),
),
)