Placing two widgets below each other inside Stack - flutter

I am having problems positioning the text inside my stack of widgets.
I just want to position two text widgets one below another. But one of them is initially at the bottom already , it moves up the whole widget.
You can see in this attachment the result I would like to achieve (red lines) and the current result:
Widget build(BuildContext context) {
return Stack(
children: [
Card(
elevation: 6,
margin: const EdgeInsets.all(8),
child: Padding(
padding: const EdgeInsets.only(
bottom: 60, right: 5, left: 5, top: 5), //bordes interiores
child: Stack(children: [
Container(
width: double.infinity,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(image as String), //varImg.url
fit: BoxFit.cover)),
//child:
),
]),
)),
Container(
//alignment: Alignment.centerLeft,
padding: const EdgeInsets.all(10),
child: Column(
children: [
Row(
children: [
IconTheme(
data: IconThemeData(
color: gender == 'Male' ? Colors.blue : Colors.pink),
child: Icon(gender == 'Male'
? Icons.male_rounded
: Icons.female_rounded)),
Positioned(
bottom: 10,
child: Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.grey),
),
),
],
),
],
),
),
],
);
}
}

You could use a Column with mainAxisAlignment set to MainAxisAlignment.end and set the two widgets as its children.

Related

Remove space in Stack

I want to place Card below the 4 icons, but why there is a big gap between?
case ConnectionState.active:
if (snapshot.hasData) {
return SingleChildScrollView(
child: Column(children: [
Stack(
children: [
Container(
height: 500,
),
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(height: 50, color: Colors.orange)),
Positioned(
top: 0,
left: 24,
right: 24,
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.white70, width: 1),
borderRadius: BorderRadius.circular(30),
),
margin: EdgeInsets.all(20.0),
child: _showWidget(
snapshot.data!), // this are the 4 icons code
),
),
],
),
_showBelowCard(snapshot.data!), // card below 4 icons
]));
} else {
return NoItem();
}
Widget _showBelowCard(ABC abc) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Place it below 4 icons",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
Text(
"Status",
style: TextStyle(color: Colors.grey),
),
]);
}
The reason why it is way down is due to the Container() with the height of 500 on your Stack(). The Stack() widget usually takes the size of the biggest children.
And if you want to have some space between the Card() and the Stack() just add SizedBox() with your desired height.

what is equivalent of guidelines (constraint layout) in flutter?

I want to create view like image, the first view (blue view) is 30% of screen height
and the second view (red view) is center vertical of first view (15% of the first view from bottom to top, and 15% of the first view from bottom to bottom).
if in android XML constraint layout I can use guidelines to handle that, but in flutter what I can use to create like that view?
import 'package:flutter/material.dart';
import 'package:flutter_app2/custom_text.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Card statsWidget() {
return new Card(
elevation: 1.5,
margin: EdgeInsets.only(bottom: 210.0, left: 20.0, right: 20.0),
color: Colors.white,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
new Padding(
padding: EdgeInsets.all(20.0),
child: new Row(
children: <Widget>[
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.center,
child: new Text(
"Photos",
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.grey,
fontSize: 16.0,
),
)),
new Align(
alignment: Alignment.center,
child: new Text(
"22k",
textAlign: TextAlign.center,
style: new TextStyle(
color: Color(0xff167F67),
),
)),
],
),
flex: 1,
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.center,
child: new Text(
"Followers",
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.grey,
fontSize: 16.0,
),
)),
new Align(
alignment: Alignment.center,
child: new Text(
"232k",
textAlign: TextAlign.center,
style: new TextStyle(
color: Color(0xff167F67),
),
)),
],
),
flex: 1,
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.center,
child: new Text(
"Following",
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.grey, fontSize: 16.0),
)),
new Align(
alignment: Alignment.center,
child: new Text(
"332k",
textAlign: TextAlign.center,
style: new TextStyle(
color: Color(0xff167F67),
),
)),
],
),
flex: 1,
)
],
),
)
],
));
}
#override
build(BuildContext context) {
return new Material(
type: MaterialType.transparency,
child: new Stack(
children: [
new Column(
children: <Widget>[
headerWidget(),
bodyWidget(),
],
),
new Center(
child: statsWidget(),
),
],
));
}
Widget headerWidget() {
var header= new Expanded(
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xff167F67),
),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new Container(
margin: EdgeInsets.only(bottom: 10.0),
height: 80.0,
width: 80.0,
decoration: new BoxDecoration(
color: const Color(0xff167F67),
image: new DecorationImage(
image: new NetworkImage(
"https://4.bp.blogspot.com/-QXHUYmKycZU/W-Vv9G01aAI/AAAAAAAAATg/eF1ArYpCo7Ukm1Qf-JJhwBw3rOMcj-h6wCEwYBhgL/s1600/logo.png"),
fit: BoxFit.cover,
),
border:
Border.all(color: Colors.white, width: 2.0),
borderRadius: new BorderRadius.all(
const Radius.circular(40.0)),
),
),
),
new Text(
"Developer Libs",
textAlign: TextAlign.center,
style: new TextStyle(
color: Color(0xffffffff),
),
)
],
),
),
flex: 1,
);
return header;
}
Widget bodyWidget() {
var bodyWidget=new Expanded(
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xffffffff),
),
child: new Padding(
padding:
EdgeInsets.only(left: 50.0, right: 50.0, top: 50.0),
child: new Column(
children: <Widget>[
new CustomText(
label: "contact#developerlibs",
textColor: 0xff858585,
iconColor: 0xff167F67,
fontSize: 15.0,
icon: Icons.email)
.text(),
],
),
)),
flex: 2,
);
return bodyWidget;
}
}
I found this code and it's good but If I try in other phone resolution the second view is not center of first view. like below image
you can play with something like this :
LayoutBuilder(
builder: (context, constraints) {
final firstHeight = constraints.biggest.height * .3;
final secondHeight = 200.0;
return SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: firstHeight + secondHeight / 2,
child: Stack(
children: [
Positioned(
top: 0,
height: firstHeight,
left: 0,
right: 0,
child: Container(
color: Colors.blue,
),
),
Positioned(
top: firstHeight - secondHeight / 2,
left: 0,
height: secondHeight,
child: Container(
width: 200,
color: Colors.red,
),
),
],
),
),
Container(
height: 200,
margin: const EdgeInsets.only(
bottom: 8,
),
color: Colors.green,
),
Container(
height: 200,
margin: const EdgeInsets.only(
bottom: 8,
),
color: Colors.green,
),
Container(
height: 200,
margin: const EdgeInsets.only(
bottom: 8,
),
color: Colors.green,
),
Container(
height: 200,
margin: const EdgeInsets.only(
bottom: 8,
),
color: Colors.green,
),
],
),
);
},
)
result :
I think what you can use is wrap your image in an expanded widget and use its flex property. Flex basically ensures how much space a widget takes.So by default flex is set to 1. Hence wrap both your widgets with an expanded widget and set the flex property accordingly. I hope it solves your problem.

Create color with round in a widget - Flutter

I cant able to achieve this round design below the Banana image.
When i try to add gradient, it is not creating sharp differentiator.
How can i achieve this in Flutter.
You will just need a Stack widget & place a Container with a circular shape.
To create a circle, you can use the shape property of Container & set it to BoxShape.circle. Then, place the remaining widgets on top of each other.
The resulting output of the below code is as follows:
Your code should look something like this:
return Stack(
children: [
// Green Background
Container(
height: 400,
decoration: BoxDecoration(
color: Colors.green,
),
),
// Circle
Positioned(
right: -50,
top: -50,
child: Container(
height: 300,
width: 300,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black12,
),
),
),
Positioned(
top: 20,
right: 20,
left: 20,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: TextFormField(
decoration: InputDecoration(
filled: true,
hintText: 'Search for products',
),
)),
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
),
Container(
margin: const EdgeInsets.only(top: 40),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text('BANANA 5% OFF',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
),),
),
Expanded(
child: Container(
height: 150,
width: 150,
color: Colors.white10,
alignment: Alignment.center,
child: Text('Image'),
),
),
],
),
),
],
),
),
],
);

Flutter. How can I overlay the container with a dynamic size by another container?

I have a container that represents a card with dynamical content. So it can be about 175 pixels height, can be 300. If this card is disabled I want to overlay this card by another container with, let say, gray color with opacity 0.5. I've realized that I can use Stack for this, but how can I define the correct size for overlay container?
Widget build(BuildContext context) {
return Center(
child: Stack(children: [
_buildCard(context),
Container(
margin: EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 8),
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.75),
borderRadius: BorderRadius.circular(20.0)),
child: Center(
child: Text(
AppTranslations.of(context).text("pending"),
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold),
)))
]),
);
}
Widget _buildCard(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 8),
child: Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 10.0,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
child: Material(
clipBehavior: Clip.antiAlias,
color: Colors.white,
child: Column(
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildImageLogo(),
Expanded(
child: Container(
padding: EdgeInsets.only(top: 12, left: 6, right: 6),
// margin: EdgeInsetsDirectional.fromSTEB(0, 8, 0, 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
LimitedBox(
maxWidth: 135,
child: Text(
widget.serviceInfo.title == null
? ""
: widget.serviceInfo.title,
style: TextStyle(fontSize: 16),
textAlign: TextAlign.start,
),
),
LimitedBox(
maxWidth: 50,
child: Container(
margin: EdgeInsetsDirectional.fromSTEB(
0, 0, 8, 0),
child: Text(
widget.serviceInfo.price == null
? ""
: ("AED" +
widget.serviceInfo.price
.toString()),
style: Theme.of(context)
.textTheme
.title
.copyWith(
fontSize: 13,
color: Colors.black54),
textAlign: TextAlign.end,
),
),
),
],
),
SizedBox(
height: Size.fromHeight(15).height,
),
Text(
widget.serviceInfo.description == null
? ""
: widget.serviceInfo.description,
style: Theme.of(context)
.textTheme
.caption
.copyWith(fontSize: 13),
),
serviceOptions(),
],
),
)),
],
),
SizedBox(
height: Size.fromHeight(10).height,
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.only(
top: 8, bottom: 8, left: 8, right: 8),
child: _btnDecline(),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(
top: 8, bottom: 8, left: 8, right: 8),
child: _btnAccept(),
),
),
],
),
],
),
),
),
));
}
the full hierarchy looks like
Scaffold -> Consumer -> Center -> Column -> Expanded -> Consumer -> ListView -> ServiceCard
You GlobalKey to get the BuildContext and use it to find out your container's size using it's RenderBox. Then you can give this size to the overlaying container. However, this is overkill imo.
You can also define a boolean to see whether or not your container should be overlayed and adjust it's decoration conditionally.

How to display text below the image?

i'm trying to display text of each picture below to that picture in an alertdialog like rating a score. I tried to use stack widget and this is the result the result. Text is in front of the picture and not display below th picture but i just want it to display below the picture. How can I do it correctly?
#override
Widget build(BuildContext context) {
return Container(
height: 60,
width: MediaQuery.of(context).size.width*0.75,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: pic.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.only(right: 10),
child: InkWell(
onTap: () {
},
child: Stack(
children: <Widget> [
Image.asset('assets/images/'+pic[index].toString()+'.png', height: 70, width: 70,),
Text(pic[index].toString())
])));
}));
}
}
reverse the order of your widgets like so:
First the InkWell Widget with a container child and to that container pass a column widget with the icon and then the text. I've used GestureDetector in this example..
GestureDetector(
onTap: #Do Something
child: Container(
child: Column(
children: <Widget>[
Icon('Your Icon Here'),
Text('Your Text Here')
],
),
),
),
this code if u not want use STACk
Container(
constraints: new BoxConstraints.expand(
height: 200.0,
),
alignment: Alignment.bottomLeft,
padding: new EdgeInsets.only(left: 16.0, bottom: 8.0),
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/image.jpg'),
fit: BoxFit.cover,
),
),
child: new Text('Title',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
)
),
);
and this if u want use STACK
Container(
constraints: new BoxConstraints.expand(
height: 200.0,
),
padding: new EdgeInsets.only(left: 16.0, bottom: 8.0, right: 16.0),
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/image.jpg'),
fit: BoxFit.cover,
),
),
child: new Stack(
children: <Widget>[
new Positioned(
left: 0.0,
bottom: 0.0,
child: new Text('Title',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
)
),
),
new Positioned(
right: 0.0,
bottom: 0.0,
child: new Icon(Icons.star),
),
],
)
);
this link if u want see more https://cogitas.net/overlay-text-icon-image-flutter/
You can position elements inside your stack - positioned