Flutter UI design using stack and column: How Can i achieve this look? - flutter

I am using Flutter 2.8, as many package dont yet have support for latest flutter version.
I am using stack instead of appBar. and I want to get the look as of below picture.
I dont want to use stack in the whole page, i think it will cause performance issues. Also, If i use stack only in lieu of appBar, I can copy paste this code to make that home button on top-left corner, for another app.
here is my full code of this page:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SafeArea(
child : Scaffold(
//todo: 1. copy code from getx4 cool ui app
//todo: 1. make it as he made it
body: Column(
children: [
Expanded(
flex: 1,
child: Container(
color: Color(0xFFc5e5f3),
child: Stack(
children: [
Positioned(
top: 10,
left: 5,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.home),
)),
],
),
),
),
Expanded(
flex: 10,
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: [
Expanded(child: Text('ShopX', style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold) ,)),
Padding(
padding: const EdgeInsets.only(right: 8) ,
child: Icon(Icons.format_list_bulleted ),
),
Icon(Icons.grid_view_outlined ),
],
),
),
),
],
),
),
);
}
}

You need to use Align widget with a property like alignment: FractionalOffset.topCenter . Please see the sample code below:
Stack(
fit: StackFit.expand,
children: <Widget>[
Column(
children: [
Container(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
color: Colors.black,
child: Image(image: AssetImage('assets/image.png'), width: MediaQuery.of(context).size.width, height: 50,)),
Expanded(
flex: 1,
child: Align(
alignment: FractionalOffset.topCenter,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 12, 0, 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Image(image: AssetImage('assets/image.png'), width: 120, alignment: Alignment.bottomLeft,),
Image(image: AssetImage('assets/image.png'), width: 100, alignment: Alignment.bottomLeft,),
Image(image: AssetImage('assets/image.png'), width: 100, height: 40, alignment: Alignment.bottomLeft,),
],
),
),),),
),
],
),
],
),
This sample code adds images 4 images on top center of the screen.
1 image on the top of the screen
3 images below the top image
Moreover, you can directly put your Stack widget into the body of Scaffold.

Use crossAxisAlignment: CrossAxisAlignment.start, on Row. Default is center.
Expanded(
flex: 10,
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, //this
children: [
Expanded(
child: Text(
'ShopX',
style:
TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
)),

Related

Not click on Container in Stack

I have a problem with the Stack Widget.
I have a Stack that contains two children: an Image wrapped with GestureDetector and a Container
. When i click anywhere on the Container, whoever is last on the Stack children list his onTap
I am extremely new to flutter.
Screenshot of the screen
this code
sonItem(dynamic icon ,String text,Color color){
return GestureDetector(
onTap: () {
print("dddddddddddddddd");
},
child: Container(
width: 70,
height: 100,
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Column(
children: [
Icon(icon ,color: color,),
Text(text)
],
),
),
);
}
I Have a problem with the Stack Widget.
I have a Stack that contains two children: an Image wrapped with GestureDetector and an Container
. When i click anywhere on the Container , whoever is last on the Stack children list his onTap
body: Container(
color: Colors.white,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Color(0xffF0F0F0),
height: 200,
child: Stack(
overflow: Overflow.visible,
alignment: Alignment.center,
children: [
Positioned(
bottom: -170.0,
child: Container(
padding: EdgeInsets.only(top: 40 , right: 10, left: 10),
height: 250,
decoration: BoxDecoration(
color: Color(0xffFFFFFF),
borderRadius: BorderRadius.circular(30),
border: Border.all(
width: 1,
color: Colors.black,
style: BorderStyle.solid,
),
),
child: Column(
children: [
Text('company',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
Text("The number 2000"),
RatingBar(
rating: 3,
icon:Icon(Icons.star,size:20,color: Colors.grey,),
starCount: 5,
spacing: 5.0,
size: 20,
isIndicator: false,
allowHalfRating: true,
onRatingCallback: (double value,ValueNotifier<bool> isIndicator){
print('Number of stars--> $value');
//change the isIndicator from false to true ,the RatingBar cannot support touch event;
isIndicator.value=true;
},
color: Colors.amber,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
sonItem(Icons.phone,"call us",Colors.green),
sonItem(Icons.location_on_outlined,"location",Colors.red),
sonItem(Icons.facebook,"FaceBook",Colors.blue),
sonItem(Icons.add_ic_call_outlined,"whatsapp",Colors.green)
],
)
],),
)),
Try below code hope its help to you
Stack(
children: <Widget>[
//your InkWell or GestureDetector Widget
InkWell(
child: Container(
// your child Widget
),
onTap: () {},
),
Positioned(),
]
),
The problem is solved when I delete bottom: -170.0,
But I need it in the design

Custom dialog widget that scales height dynamically to child content

I want to build a custom dialog whose child is a widget displaying the HTML content. I'm struggling with making the dialog's height size to its child. Currently, I'm giving the container a fixed height as otherwise it would crash due to unbounded height for Column. The package i use to display HTML content: Easy Web View.
My code:
class CustomContentDialog extends StatelessWidget {
CustomContentDialog({required this.content});
final String content;
#override
Widget build(BuildContext context) {
return Center(
child: Material(
child: Container(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.8,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding:
const EdgeInsets.only(left: 24, bottom: 16, top: 16),
child: Text(
'Title',
),
),
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: const Icon(
Icons.close,
color: Colors.grey,
size: 20,
),
)
],
),
const Divider(
indent: 10,
endIndent: 10,
color: Color(0xFFE9E9E9),
),
Flexible(
fit: FlexFit.loose,
child: Padding(
padding: const EdgeInsets.only(left: 24.0),
child: EasyWebView(
src: src,
onLoaded: () {},
isHtml: true,
isMarkdown: false,
convertToWidgets: false,
key: const Key('HTML'),
),
),
),
],
),
),
),
);
}
}
What I've achieved so far:

Flutter: How can i put the text widget center in screen

I need to put the title' in the center even to fit any screen, I know can I sized box to move the title in the center, but when using the different device the dimensions surely will change and become the title the different places.
this is code :
class NotificationDoctor extends StatelessWidget {
TextStyles textStyles = TextStyles.HEADING;
Texts texts;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(15.0))),
height: 130.h,
child: Padding(
padding: EdgeInsets.only(top: 40.h),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(
right: 15.w,
top: 15.h,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
FlatButton(
child: ArrowIcon(
arrowColor: Color(0xFFEEF4F9),
backgroundColor:
Theme.of(context).primaryColor.withOpacity(.9),
),
onPressed: () {
Navigator.pop(context);
},
),
// SizedBox(
// width: 55,
// ),
Center(
child: Texts(
'Notifications',
style: TextStyles.HEADING,
color: Color(0xFFEEF4F9),
),
),
],
),
),
],
),
),
),
));
}
}
use the padding like this
Padding(
padding: EdgeInsets.symmetric(vertical: 5.h, horizontal: 3.h),
child: Container(),
);
read more at https://pub.dev/packages/sizer

I am getting A RenderFlex overflowed by 57 pixels on the bottom

Hi I am new to Flutter and I came across this error that is in the title I looked here as well but nothing seems to help, the layout looks just fine when I star the app however I am getting an error which drives me crazy. One of the solutions that I found was to add resizeToAvoidBottomPadding: false which I did but the error is still present.
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 3,
child: SizedBox(),
),
_title(),
SizedBox(
height: 50,
),
_displayUserNameAndPassword(),
SizedBox(
height: 20,
),
_submitButton(),
Container(
padding: EdgeInsets.symmetric(vertical: 10),
alignment: Alignment.centerRight,
child: Text('Forgot Password ?',
style:
TextStyle(fontSize: 14, fontWeight: FontWeight.w500)),
),
_divider(),
_facebookButton(),
Expanded(
flex: 2,
child: SizedBox(),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: _createAccountLabel(),
),
],
),
);
}
You need to use ListView instead of Column.
In column when keyboard appears for text field it caused renderflexed overflow error.
Thanks

Expand widgets inside the Stack widget

I have a stack widgets with two widgets inside.
One of them draws the background, the other one draws on top of that.
I want both widgets to have the same size.
I want the top widget, which is a column, to expand and fill the stack vertically to the size that is set by the background widget.
I tried setting the MainAxis mainAxisSize: MainAxisSize.max but it didn't work.
How can I make it work?
Use Positioned.fill
Stack(
children: [
Positioned.fill(
child: Column(
children: [
//...
],
),
),
//...
],
);
More info about Positioned in Flutter Widget of the Week
How does it work?
This is all about constraints. Constraints are min/max width/height values that are passed from the parent to its children. In the case of Stack. The constraints it passes to its children state that they can size themselves as small as they want, which in the case of some widgets means they will be their "natural" size. After being sized, Stack will place its children in the top left corner.
Positioned.fill gets the same constraints from Stack but passes different constraints to its child, stating the it (the child) must be of exact size (which meant to fill the Stack).
Positioned.fill() is the same as:
Positioned(
top: 0,
right: 0,
left: 0,
bottom:0,
child: //...
)
For even more examples and info: How to fill a Stack widget and why? and Understanding constraints.
You can try wrapping the Column with a positioned widget. Set top to 0 and bottom to 0. This will make the column fill the stack vertically.
sample code:
Stack(
children: <Widget>[
// Background widget rep
Container(
color: Colors.pink,
),
Positioned(
top: 0,
bottom: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('madonna'),
Text('flutter'),
],
),
)
],
)
I think you could wrap you column in a container like this:
Container(
height: double.infinity,
width: double.infinity,
child: Column()
),
The accepted answer did not answer my issue completely. So, I put my code here in case you have a similar issue.
class NoContentView extends StatelessWidget {
const NoContentView({Key? key, required this.message}) : super(key: key);
final String message;
#override
Widget build(BuildContext context) {
return Expanded(
child: Stack(
children: [
Positioned.fill(
child: FittedBox(
child: const Image(image: AssetImage(AppImages.noReceiptsWeb), fit: BoxFit.fitWidth),
),
),
MessageView(message: message),
],
),
);
}
}
In my case, I thought that I needed to expand the container in the light blue color with an expanded widget inside the stack widget.
Problems arose, especially since I was adding the stack widget in the column widget, and the way to make the container double.infinity dimensions I definitely had a problem with the vertical axis.
In the end, I managed to show it like this photo...
Column(
children: [
//filter
Container(
color: orange,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Text(
'All',
style: getRegular(color: white.withOpacity(.6)),
),
),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 10, 0),
child: Text(
'Ready',
style: getRegular(color: white.withOpacity(.6)),
),
),
freeh(),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
],
),
Row(
children: [
Icon(
filter,
color: white.withOpacity(.7),
size: 20,
),
Text(
'FILTER',
style: getLight(
color: white.withOpacity(.7),
),
),
freeh(),
],
),
],
),
),
Expanded(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
color: lightBlue, //here to use map>>>>
),
Container(
height: 35,
width: 120,
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
FontAwesomeIcons.listUl,
color: white.withOpacity(.8),
size: 20,
),
Text(
'List View',
style: getRegular(color: white.withOpacity(.8)),
)
],
),
),
],
),
)
],
),