How to make this screen responsive in Flutter? - flutter

I'm kinda confused with how responsive layouts are made with flutter can you guys point me to the right direction or where in my codes will be wrapped in Expanded widget?
I tried wrapping the containers with Extended but It keeps showing an error and I'm getting confused now. I'm still a beginner, to be honest. Thank you very much!
Also, when I searched I found out that I should avoid using hardcoded sizes most of the time. So I want to learn when to apply Extended widget in order to make my screen responsive.
my code is below:
import 'package:flutter/material.dart';
class RegisterPage extends StatefulWidget {
RegisterPage({Key key}) : super(key: key);
#override
_RegisterPageState createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Color(0xff0D192A),
body: Container(
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Container(
height: 200,
width: 200,
child: Image(
image: AssetImage("assets/images/vlogo.png"),
),
),
),
Padding(
padding: EdgeInsets.all(40.0),
child: Center(
child: Text("Register an Account",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20)),
)),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text("Email Address",
style: TextStyle(
fontSize: 10.0, color: Colors.grey[400])),
],
),
],
),
),
SizedBox(height:10.0),
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter your email address",
hintStyle: TextStyle(color: Colors.grey[400]),
),
),
),
)
),
SizedBox(height:20.0),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text("Choose Password",
style: TextStyle(
fontSize: 10.0, color: Colors.grey[400])),
],
),
],
),
),
SizedBox(height:10.0),
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter your email address",
hintStyle: TextStyle(color: Colors.grey[400]),
),
),
),
)
),
SizedBox(height: 50),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: InkWell(
onTap: () {
setState(() {
});
},
child: Container(
height: 50,
decoration: BoxDecoration(
color: Color.fromRGBO(211, 184, 117, 100)
),
child: Center(
child: Text("Login", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20),
),
),
),
),
),
],
),
],
),
),
),
);
}
}

Explore this plugin: This is one of the most effective plugins I have ever used for making responsive design.
https://pub.dev/packages/responsive_screen
Or
Use MediQuery() for getting the screen height and width i.e:-
Example:
#override
Widget build(BuildContext context) {
dynamic screenHeight = MediaQuery.of(context).size.height;
dynamic screenwidth = MediaQuery.of(context).size.width;
//use screenHeight and screenWidth variable for defining the height and
//width of the Widgets.
return Container(
height:screenHeight * .2, //It will take the 20% height of the screen
width: screenwidth * .5, //It will take the 50% width of the screen
//height: screenHeight, //It will take 100% height
child: Image(
image: AssetImage("assets/images/vlogo.png"),
);
}

You can make each screen responsive in flutter by just using MediaQuery or LayoutBuilder Concepts.
For your application, replace all your custom sizes like
width : MediaQuery.of(context).size.width * 0.1
height : MediaQuery.of(context).size.height * 0.3
MediaQuery gives you the sizes and orientation of the screen.
Even your padding, margin and other dimensions also should be calculated using MediaQuery to make it responsive.
Here, MediaQuery.of(context).size.width will give you the width of the current device screen and MediaQuery.of(context).size.height will give you the height of the current device screen.
Also, you can use LayoutBuilder Widget like,
LayoutBuilder(
builder: (context, constraints) {
if(constraints.maxWidth > 500) {
getLandscapeLayout();
} else {
getPortraitLayout();
}
},
)
LayoutBuilder is a widget which provides the dimensions of its parent so we can know how much space we have for the widget and can build it our child accordingly.
So these are two most powerful concepts are available in flutter to make your apps fully responsive.

Related

A widget in my SliverAppBar is causing a bottom overflow, how do i correct this in flutter?

I use a SliverAppBar and use flexibleSpace title instead of the default sliver title, on portrait mode, it is perfectly fine as shown :
But when i get to landscape mode it causes a bottom overflow by 13px, VScode tells me the renderflex is caused by a column.
This is how it looks like in landscape :
It is so messy that when i discovered this bug i couldn't continue coding until i fix this and this is what i've been trying to do :(
I will give my SliverAppBar code and also the widget used in the sliverapp flexibleSpace title as snippet below
I have tried using Expanded instead of Flexible, but it causes even more errors.
I also tried using some screen utility packages in pub.dev but seem like i don't use it properly.
Main view with sliverapp :
class HomeView extends GetView<HomeController> {
#override
Widget build(BuildContext context) {
controller.initScrollController();
return WillPopScope(
onWillPop: Helper().onWillPop,
child: Scaffold(
body: RefreshIndicator(
onRefresh: () async {
Get.find<LaravelApiClient>().forceRefresh();
controller.refreshHome(showMessage: true);
Get.find<LaravelApiClient>().unForceRefresh();
},
child: CustomScrollView(
physics: const AlwaysScrollableScrollPhysics(),
controller: controller.scrollController,
shrinkWrap: false,
slivers: <Widget>[
SliverAppBar(
backgroundColor: Color(0xffFFFFFF),
expandedHeight: MediaQuery.of(context).size.height * 0.18,
elevation: 0.5,
floating: false,
iconTheme: IconThemeData(color: Get.theme.primaryColor),
actions: [NotificationsButtonWidget()],
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
title: MainProfileDetails(),//i suspect this is the widget causing the bug
),
),
SliverToBoxAdapter(
child: Wrap(
children: [
JobSummaryView(),
//BookingsListWidget(),
],
),
),
],
)),
),
);
}
}
MainProfileDetails() code:
class MainProfileDetails extends StatelessWidget {
const MainProfileDetails({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Obx(() {
return Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Stack(
children: [
GestureDetector(
onTap: () {
Get.toNamed(Routes.PROFILE);
},
child: Container(
child: Stack(
children: [
SizedBox(
width: 60,
height: 60,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(80)),
child: CachedNetworkImage(
height: 100,
width: double.infinity,
fit: BoxFit.cover,
imageUrl: Get.find<AuthService>()
.user
.value
.avatar
.thumb,
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
width: double.infinity,
height: 80,
),
errorWidget: (context, url, error) =>
Icon(Icons.error_outline),
),
),
),
Positioned(
top: 35,
left: 30,
right: 0,
child: Get.find<AuthService>()
.user
.value
.verifiedPhone ??
false
? Icon(Icons.check_circle,
color: Color(0xffB0BEC1), size: 24)
: Icon(Icons.error_outline),
)
],
),
),
),
],
),
SizedBox(
width: 10,
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
flex: 2,
child: Padding(
padding: const EdgeInsets.only(left: 1.0),
child: Text(
'Hello, ${Get.find<AuthService>().user.value.name}',
style: GoogleFonts.poppins(
color: Color(0xff34495E), fontSize: 9),
),
),
),
Flexible(
flex: 2,
child: Padding(
padding: const EdgeInsets.only(top: 1.0, bottom: 1.0),
child: Text(
'Good Stitching',
style: GoogleFonts.poppins(
fontSize: MediaQuery.of(context).size.width * 0.04,
color: Color(0xff000000),
fontWeight: FontWeight.w600),
),
),
),
Flexible(
child: Container(
decoration: BoxDecoration(
color: Color(0xffeeeeee),
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.only(
top: 3.0, bottom: 3.0, left: 10.0, right: 10.0),
child: Get.find<AuthService>().user.value.verifiedPhone ??
false
? Text(
'Verified',
style: GoogleFonts.poppins(
fontSize:
MediaQuery.of(context).size.width * 0.025,
fontStyle: FontStyle.italic),
)
: Text(
'Unverified',
style: GoogleFonts.poppins(
fontSize:
MediaQuery.of(context).size.width * 0.025,
fontStyle: FontStyle.italic),
),
),
)),
],
),
//NotificationsButtonWidget(),
],
),
);
});
}
}
Please i need your time and assistance on this one. Thank you!
After many hours of asking for help here, i decided to go with simple AppBar in flutter as SliverAppBar flexibleSpace title is only customisable to a limit.
And that was goodbye to orientation issues.
Thanks everyone for your support.

How to draw line between 1 widget to 2nd widget Flutter

I'm trying to create a comment tree but I don't have any idea how to do that. The package I found on pub.dev is not like what I want. I mesh with codes. No tutorial found related to me.
This is what I want :
I want a tutorial or idea to create design like showing in the image.
You can draw line like this
SizeBox(
height : 2,
width : MediaQuery.of(context).size.width,
child : Container(color:Colors.black)
),
try this
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(width: 2.0, color:Colors.black),//(or use VerticalDivider())
SizedBox(width: 4.0),
YourCommentWidget(),
],
))
In your tree, you can use divider() for clear line, also you can use sizedbox.
firstwidget (
child : secondwidget (child : ..............)
)
simply you can wrap second widget with a padding.
Check this package. https://pub.dev/packages/flutter_fancy_tree_view
#Pradip said in comments.
If that you want, just add in pubspec.yaml file or you want to customize like in image just Copy the code from git repository and paste in your project as separate directory.
Edit as you want.
Finally, I achieve what I want. I think is not an Optimize way. I really like to know your comment on my code. It's litter meshy but the output looks nice.
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class TestTree extends StatelessWidget {
const TestTree({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('title'),
),
body: ListView(
children: [
commentTreeRoot(
context: context,
image:
'https://www.whatsappprofiledpimages.com/wp-content/uploads/2018/07/beaJKHutiful-girl-profile-p-199x300.jpg',
name: 'User Name',
subtitle: '11111 Comment Text User name Comment Text User name ',
posteDate: Text('20:18'),
content:
Text("""The :expressions will be suitable for girls, guys,\n
married people too. Because in life complications start and\n
ends with girls at the same time happiness comes to girls and only girls. Thus, even a silly waste paper will look bright when it is in the hands of beautiful girls.
The pixels are picture perfect in our website."""),
comments: [
commentTreeChild(
context,
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT16eO5W8VPjVFrkvG8n_2FQKjByMcbLtBF4A&usqp=CAU,',
[
commentTreeChild(
context,
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT16eO5W8VPjVFrkvG8n_2FQKjByMcbLtBF4A&usqp=CAU',
[],
margin: 40,
last: true)
]),
commentTreeChild(
context,
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT16eO5W8VPjVFrkvG8n_2FQKjByMcbLtBF4A&usqp=CAU',
last: true,
[]),
],
)
],
));
}
Widget commentTreeRoot({
required BuildContext context,
required String image,
required String name,
required String subtitle,
required Widget posteDate,
required Widget content,
required List<Widget> comments,
}) {
return Column(
children: [
CustomPaint(
painter: CreateLine(root: true),
child: Column(
// root
children: [
ListTile(
horizontalTitleGap: 0,
leading: CircleAvatar(
backgroundImage: NetworkImage(image),
),
title: Padding(
padding: const EdgeInsets.only(top: 15, left: 8),
child: Text(name),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 0, left: 8),
child: Text(
subtitle,
overflow: TextOverflow.clip,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
trailing: posteDate,
),
Container(
// Content
margin: EdgeInsets.only(left: 60),
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Color.fromARGB(255, 240, 240, 240),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: content,
),
Column(
children: comments,
),
SizedBox(
height: 10,
),
commentRootTextfield(context),
],
),
)
],
);
}
Widget commentTreeChild(
BuildContext context, String image, List<Widget> commentReply,
{bool last = false, double margin = 60}) {
return Container(
margin: EdgeInsets.only(left: margin, top: 15),
child: CustomPaint(
painter: CreateLine(root: false, last: last),
child: Column(
// child 1
children: [
SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 15,
backgroundImage: NetworkImage(image),
),
Expanded(
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Color.fromARGB(255, 240, 240, 240),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Column(
children: [
Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 8),
child: Text(
'User Name',
overflow: TextOverflow.ellipsis,
),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8),
child: Text('20:18'),
)
],
),
Text(
"""The expressions will be suitable for girls, guys,
"""),
],
),
),
),
],
),
),
last ? commnetChildTextField(context) : commnetChildReplyButton(),
Column(
children: commentReply,
)
],
), // child root
),
);
}
Widget commnetChildReplyButton() {
return Container(
margin: const EdgeInsets.only(
left: 30,
),
alignment: Alignment.centerLeft,
child: SizedBox(
height: 20,
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () {},
child: Text('Replay')),
));
}
Widget commnetChildTextField(BuildContext context) {
return FittedBox(
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 8, top: 16),
child: Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(
'https://img.etimg.com/thumb/msid-69381991,width-650,imgsize-594328,,resizemode-4,quality-100/hacker-1.jpg'),
radius: 15,
),
SizedBox(
width: 10,
),
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Color.fromARGB(255, 231, 231, 231),
border: Border.all(width: 0.5),
borderRadius: BorderRadius.all(Radius.circular(30))),
child: TextField(
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
hintText: 'Type your message...',
contentPadding:
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
isDense: true,
border: InputBorder.none,
),
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
],
),
),
);
}
Widget commentRootTextfield(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 3, color: Color.fromARGB(255, 231, 231, 231)),
bottom:
BorderSide(width: 2, color: Color.fromARGB(255, 231, 231, 231)),
),
),
child: FittedBox(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
IconButton(onPressed: () {}, icon: Icon(FontAwesomeIcons.smile)),
SizedBox(
width: MediaQuery.of(context).size.width,
child: Container(
decoration: BoxDecoration(
color: Color.fromARGB(255, 231, 231, 231),
borderRadius: BorderRadius.all(Radius.circular(30))),
child: TextField(
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
hintText: 'Type your message...',
contentPadding:
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
isDense: true,
border: InputBorder.none,
),
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
SizedBox(
width: 30,
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.attach_file,
size: 25,
))),
SizedBox(
width: 40,
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.mic,
size: 30,
)),
),
],
),
),
);
}
}
class CreateLine extends CustomPainter {
CreateLine({required this.root, this.last = false});
final bool root;
final bool last;
#override
void paint(Canvas canvas, Size size) {
final p1 = size.topLeft(root ? Offset(35, 65) : Offset(15, 40));
final p2 = root
? Offset(35, size.height - 53)
: Offset(15, size.height - (last ? 40 : 0));
final paint = Paint()
..color = Colors.black
..strokeWidth = 1;
canvas.drawLine(p1, p2, paint);
// TODO: implement paint
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}
Output look like this now

Flutter Wrap Widget does not expand itself

I'm trying to create a calendar and I'm using Wrap widget to display days inside calendar. But I faced a problem. Wrap widget does not expand itself to every side that's why overflow happens. This is my code:
return Container(
height: MediaQuery.of(context).size.height * 0.40,
width: MediaQuery.of(context).size.width / 2,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(46.0),
color: Color(0xFFD6D6D6),
boxShadow: [
BoxShadow(
color: Color(0xFF000000).withOpacity(0.16),
offset: Offset(0, 10),
blurRadius: 20.0,
),
],
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(width: 8.0),
GestureDetector(
onTap: () {},
child: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
Text(
'${getMonthName(initialDate.month)}',
style: GoogleFonts.baloo(
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.w400,
),
),
GestureDetector(
onTap: () {},
child: Icon(
Icons.arrow_forward_ios,
color: Colors.white,
),
),
SizedBox(width: 8.0),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.25,
width: MediaQuery.of(context).size.width / 2.5,
child: Row(
children: [
Wrap(
alignment: WrapAlignment.start,
direction: Axis.horizontal,
spacing: 2.0,
children: dayList == null
? SizedBox()
: dayList.map((e) {
return DaysContainer(
number: e,
);
}).toList(),
),
],
),
),
],
),
);
When I remove upper Row in Wrap, this time widget only goes to vertical even though I define Axis.horizontal.
DaysContainer class:
class DaysContainer extends StatelessWidget {
const DaysContainer({Key key, this.number, this.isAvailable})
: super(key: key);
final String number;
final bool isAvailable;
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Color(0xFFFFFFFF),
),
child: Center(
child: Text(
number,
style: GoogleFonts.baloo(
fontSize: 30.0,
color: Color(0xFFBFBFBF),
fontWeight: FontWeight.w400,
),
),
),
);
}
}
This is the result in Flutter Web:
Expected result:
Can anyone help me to figure out what is the problem in Wrap widget?
Please change your code with the following changes:
Removed Row widget outside Wrap
Defined your width of DaysContainer. Currently, the width of Container in DaysContainer has full width of parent widget. That is the reason why your time widget goes to vertical even though you define Axis.horizontal in Wrap widget.
By the way, you can add the properties runSpacing and spacing to your Wrap widget to give more space between your items in horizontal and vertical instead of using padding.
try to change to:
Container(
height: MediaQuery.of(context).size.height * 0.25,
width: MediaQuery.of(context).size.width / 2.5,
child: Wrap(
alignment: WrapAlignment.start,
direction: Axis.horizontal,
spacing: 2.0,
children: dayList == null
? SizedBox()
: dayList.map((e) {
...
class DaysContainer extends StatelessWidget {
const DaysContainer({Key key, this.number, this.isAvailable})
: super(key: key);
final String number;
final bool isAvailable;
#override
Widget build(BuildContext context) {
return Container(
width: 20,
height: 20,
margin: EdgeInsets.only(bottom: 2.0),
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Color(0xFFFFFFFF),
),
child: Center(
child: Text(
number,
style: GoogleFonts.baloo(
fontSize: 30.0,
color: Color(0xFFBFBFBF),
fontWeight: FontWeight.w400,
),
),
),
);
}
}

Bottom container inside stack moves upwards as keyboard opens on textfeild click - Flutter

I have a stack with list of content and custom dialogBox that I created. It contains textfeild. When I click the textfeild, keyboard opens and push dialog box way above the keyboard. There is alot of gap between the bottom of the dialog and the start of the keyboard. How can I keep the bottom of dialog stuck to the top the keyboard in a clean manner.
import 'package:flutter/material.dart';
class CombinedHomeView extends StatefulWidget {
// --- Services Headings
#override
_CombinedHomeViewState createState() => _CombinedHomeViewState();
}
class _CombinedHomeViewState extends State<CombinedHomeView> {
_showGrocOrderReviewDialog(Size _deviceSize) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
width: double.infinity,
height: _deviceSize.height * 0.28,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"How was your last order?",
style: TextStyle(
fontFamily: fontMontserrat,
color: Colors.black87,
),
),
SizedBox(height: 10),
Expanded(
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.2),
borderRadius: BorderRadius.all(
Radius.circular(_deviceSize.height * 0.02),
),
),
child: SingleChildScrollView(
child: TextField(
maxLines: 5,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Add additional remarks',
hintStyle: TextStyle(
fontSize: _deviceSize.height * 0.015,
fontFamily: fontMontserrat,
color: Colors.black38,
),
),
),
),
),
),
SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: SmallBtn(
passedText: "Cancel",
passedBorderColor: Colors.green,
passedBGColor: Colors.white,
passedFontColor: Colors.brown,
),
),
SizedBox(width: 10),
Expanded(child: SmallBtn(passedText: "Submit")),
],
),
],
),
),
);
}
#override
Widget build(BuildContext context) {
Size _deviceSize = MediaQuery.of(context).size;
return Stack(
alignment: Alignment.center,
children: [
// ------------ List of content
ListView( // few simple widgets here),
// ------------ Dialog
_showGrocOrderReviewDialog(_deviceSize)
],
);
}
}
You can ignore the below code. It is just a code of SmallBtn incase anyone needs it.
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class SmallBtn extends StatelessWidget {
final String passedText;
IconData passedIcon;
Color passedBGColor;
Color passedFontColor;
Color passedBorderColor;
bool isShadowEnabled;
SmallBtn({
#required this.passedText,
this.passedIcon,
this.passedBGColor,
this.passedFontColor,
this.passedBorderColor,
this.isShadowEnabled,
});
#override
Widget build(BuildContext context) {
isShadowEnabled == null
? isShadowEnabled = false
: isShadowEnabled = isShadowEnabled;
final deviceSize = MediaQuery.of(context).size;
return Container(
// alignment: Alignment.bottomLeft,
// width: deviceSize.width * 0.5 + passedText.length * 3,
padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5),
height: deviceSize.height * 0.04,
decoration: BoxDecoration(
color: passedBGColor == null ? Colors.brown : passedBGColor,
borderRadius: BorderRadius.all(
Radius.circular(
deviceSize.height * 0.02,
),
),
border: Border.all(
color: passedBorderColor == null
? Colors.transparent
: passedBorderColor,
),
boxShadow: [
isShadowEnabled
? BoxShadow(
color: Colors.brown,
blurRadius: 10.0, // has the effect of softening the shadow
spreadRadius: 1.0, // has the effect of extending the shadow
offset: Offset(
0.0, // horizontal
1.0, // vertical
),
)
: BoxShadow()
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
passedIcon != null
? Icon(
passedIcon,
color: Colors.white,
size: deviceSize.height * 0.02,
)
: Container(),
passedIcon != null
? SizedBox(width: deviceSize.width * 0.01)
: SizedBox(),
Text(
passedText,
style: TextStyle(
fontSize: deviceSize.height * 0.018,
fontFamily: "Montserrat",
color: passedFontColor != null ? passedFontColor : Colors.white,
),
),
],
),
);
}
}
Why are you using a stack? If you replace the stack with a column your dialog will not be pushed to the top of the screen.

Child Container's Height is depending on parent Container's Widget

I Creating a Container giving it a height and width responsively, but the issue is that in the child of Container I use a ListView to show some Cards which are basically container and I give them a constant height but the height of the card are totally depending on Container's height, even if I give the of cards to 0, nothing will happen, and when I increase the container height, the card height increases, same happens while decreasing. this never happens to me before in flutter, may be this is a new version, I need help, please give answers with an explanation. You can see the Code of the container and Card.
Container Code
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
child: Container(
child: ListView(
scrollDirection: Axis.horizontal,
children: sample
.map((obj) => card.PredictionCard(
temprature: obj.temprature, status: obj.status))
.toList(),
),
height: _device.height * 0.22,
decoration: cardDecoration,
),
),
Card Code
class PredictionCard extends StatelessWidget {
final temprature;
final status;
const PredictionCard({this.temprature, this.status});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Container(
margin: EdgeInsets.symmetric(
vertical: 10,
),
height: 120,
decoration: predictionCardDecoration,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'$temprature',
style: TextStyle(
color: Colors.white,
fontSize: 40,
),
),
Text(
'$status',
style: TextStyle(
color: Colors.white, fontSize: 15, letterSpacing: 1),
),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Column(
children: [
Image(
image: AssetImage('assets/rainIcon.png'),
),
Text(
'23%',
style: TextStyle(
color: Colors.white, fontSize: 15, letterSpacing: 1),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/rainDropIcon.png'),
Text(
'0%',
style: TextStyle(
color: Colors.white, fontSize: 15, letterSpacing: 1),
),
],
),
],
)
],
),
),
);
}
}
Code of Class from where Responsive height is integrated
// widget binging method
class DeviceConfig {
final height = WidgetsBinding.instance.window.physicalSize.height /
WidgetsBinding.instance.window.devicePixelRatio;
final width = WidgetsBinding.instance.window.physicalSize.width /
WidgetsBinding.instance.window.devicePixelRatio;
}
// using media query {uses context to set value of device configuration}
class DeviceConfigQuery {
var height;
var width;
DeviceConfigInit(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
}
}
Ok I will allow myself to copy the answer from another post as its worth to remember that and I woudnt put it better.
Constraints in Flutter works a bit different than usual. Widgets
themselves do not have constraints.
When you specify a width/height on a Container, you're not
constraining Container. You're constraining the child of Container.
Container will then size itself based on the size of its child.
As such, parent widgets always have the last word on how their
descendants should be sized.
If you want to go around this, you have to use Align widget:
Container(
width: 200.0,
height: 200.0,
child: Align(
alignment: Alignment.topLeft,
child: Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.red),
),
),
);
This may seem weird and limiting. But this single weirdness is the
reason why Flutter's layout is so powerful and composable.
answered by:
RĂ©mi Rousselet in this post https://stackoverflow.com/a/54717843/2945977
In your example instead of using Padding, use Align with alignment: Alignment.center