I am trying to build a widget that is made out of 2 different components:
image
container with text
I could just make a vertical split between the image but my aim is to have the split diagonal with diagonal text align aswell (or that the items would align themselves with the diagonal).
I was able to achieve most of the part with this resource: Custom flutter widget shape, but I am having problems with aligning text diagonally with the parent line. It is shown like this
This is my code for now
Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
alignment: Alignment.centerLeft,
fit: BoxFit.fitHeight,
image: NetworkImage(
'https://media.sproutsocial.com/uploads/2014/02/Facebook-Campaign-Article-Main-Image2.png'),
),
),
),
ClipPath(
clipper: TrapeziumClipper(),
child: Container(
color: Colors.white,
padding: EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Text('1'),
Text('2'),
Text('3'),
Text('4'),
Text('5'),
Text('6'),
],
crossAxisAlignment: CrossAxisAlignment.center,
),
width: double.infinity,
),
)
],
),
And this is my clipper line draw.
class TrapeziumClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
final path = Path();
path.moveTo(size.width, 0.0);
path.lineTo(size.width * 53 / 100, 0.0);
path.lineTo(size.width * 1 / 3, size.height);
path.lineTo(size.width, size.height);
path.close();
return path;
}
#override
bool shouldReclip(TrapeziumClipper oldClipper) => false;
}
So after trying out with CustomMultiChildLayout and much more other widgets I have come to the conclusion that there is really not any way around other than to have comlpicated "hacks".
The one simpeples for me was this:
Container(
height: double.infinity,
width: double.infinity,
padding: const EdgeInsets.only(top: 15, bottom: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
width: (mediaQuery.size.width * 53 / 100) - mediaQuery.size.width * 0.14,
padding: EdgeInsets.only(right: 15),
height: 15,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'23. feb 2020',
style: TextStyle(
fontSize: 11,
fontFamily: 'Red Hat Text',
fontWeight: FontWeight.bold,
color: AppColors.lightGrey,
),
),
Text(
'21.00',
style: TextStyle(
fontSize: 11,
fontFamily: 'Red Hat Text',
fontWeight: FontWeight.bold,
color: AppColors.lightGrey,
),
)
],
),
),
SizedBox(
height: 5,
),
Container(
width: (mediaQuery.size.width * 57 / 100) - mediaQuery.size.width * 0.14,
padding: EdgeInsets.only(right: 15),
height: 20,
child: FittedBox(
alignment: Alignment.centerLeft,
fit: BoxFit.scaleDown,
child: Text(
'item title name',
style: TextStyle(
fontSize: 18,
fontFamily: 'Red Hat Text',
fontWeight: FontWeight.bold,
color: AppColors.white),
),
),
),
SizedBox(
height: 5,
),
Container(
width: (mediaQuery.size.width * 61 / 100) - mediaQuery.size.width * 0.14,
padding: EdgeInsets.only(right: 15),
height: 15,
child: Text(
'address',
style: TextStyle(
fontSize: 11,
fontFamily: 'Red Hat Text',
fontWeight: FontWeight.bold,
color: AppColors.lightGrey,
),
),
),
Expanded(
child: Container(),
),
Container(
width: (mediaQuery.size.width * 3.7 / 5) - mediaQuery.size.width * 0.14,
padding: EdgeInsets.only(right: 15),
height: 32,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'GOING',
style: TextStyle(
fontSize: 24,
fontFamily: 'Red Hat Text',
fontWeight: FontWeight.bold,
color: AppColors.green,
),
),
Container(
alignment: Alignment.bottomRight,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(
AppIcons.guests,
size: 15,
color: AppColors.white,
),
SizedBox(
width: 15,
),
Text(
'24',
style: TextStyle(
fontSize: 20,
fontFamily: 'Red Hat Text',
fontWeight: FontWeight.bold,
color: AppColors.white),
),
],
),
)
],
),
),
Basically what I did was get the screensizes of the elements and then by simply testing, I calculated how much width can Container() take in order to stay in the trapezoid area. The only thing I am concerned about is the responsivness with larger/smaller devices, but I hope that it will work since it's based on mediaquery sizes and not fixed ones.
Related
i am trying to make the home screen scrollable with SingleChildScrollView but reading other questions on Stackoverflow, it seems that Expanded causes problems. I am new to Flutter, so i am here to ask you if you know how could i fix this. I noticed that if i wrap the Column in a SingleChildScrollView widget it works without the Expanded widget, so that's the problem for sure. Do you know how could i replace the Expanded widget? I don't know what height it is going to have, since i am probably going to add more buttons.
Here there is the code:
return Scaffold(
body: Stack(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: size.width * 0.10),
child: Column(children: [
SizedBox(height: statusBarHeight), // spazio per statusbar
Align(
alignment: Alignment.topLeft,
child: Container(
margin: EdgeInsets.only(top: size.height * 0.04),
height: 20,
// color: Colors.orange,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(Icons.wb_sunny_sharp, size: 20, color: Color(0xff8276f4)),
SizedBox(width: 8), // Spazio laterale da icona
Text("MER 18 AGO", style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Color(0xff8276f4),
),),
],)
),
),
Container(
margin: EdgeInsets.only(top: 15, bottom: 20),
width: size.width * 0.80,
decoration: BoxDecoration(
// color: Color(0xffaf8eff),
borderRadius: BorderRadius.circular(29.5)
),
child: Text("Ciao, Andrea!", style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 30,
color: Color(0xff2e3760),
),),
alignment: Alignment.centerLeft,
),
Container(
height: size.height * 0.30,
width: size.width * 0.80,
decoration: BoxDecoration(
color: Color(0xffdee0e3),
image: DecorationImage(
scale: 0.5,
image: AssetImage('assets/images/standing.png')
),
borderRadius: BorderRadius.circular(29.5)
),
),
SizedBox(height: 20),
Align(
alignment: Alignment.topLeft,
child: Container(
child: Text("Cosa vuoi fare oggi?", style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Color(0xff2e3760),
),),
),
),
Expanded(
child: Container(
// color: Colors.orange,
margin: EdgeInsets.only(top: 20),
child: GridView.count(
padding: EdgeInsets.all(0),
childAspectRatio: 0.8,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
children: <Widget>[
CategoryCard(
title: "Profilo",
numeroicona: 60307,
numerocolore: 0xFF8c7ffd,
),
CategoryCard(
title: "Università",
numeroicona: 58713,
numerocolore: 0xffb08dff,
),
CategoryCard(
title: "Idee",
numeroicona: 58235,
numerocolore: 0xFF1a88ff,
),
CategoryCard(
title: "Progetti",
numeroicona: 61080,
numerocolore: 0xFF4b5982,
),
],
crossAxisCount: 2),
),
),
],),
),
Now it will scroll like this
I used SliverToBoxAdapter on Column, then replaced GridView with SliverGrid.count. I'm making pr to the repo. After checking, let me know this is what you wanted?
I need to add an image on the full background and then needed to add a gradient on the image. I have added the image in the background but the issue is not able to add the gradient colors.
My code.
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/sidebg.png"),
fit: BoxFit.cover,
),
),
padding: EdgeInsets.only(top: 50, bottom: 70, left: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
CircleAvatar(),
SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Miroslava Savitskaya',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
Text('Active Status',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold))
],
)
],
),
Column(
children: drawerItems
.map((element) => Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(
element['icon'],
color: Colors.white,
size: 30,
),
SizedBox(
width: 10,
),
Text(element['title'],
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20))
],
),
))
.toList(),
),
Row(
children: [
Icon(
Icons.settings,
color: Colors.white,
),
SizedBox(
width: 10,
),
Text(
'Settings',
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
SizedBox(
width: 10,
),
Container(
width: 2,
height: 20,
color: Colors.white,
),
SizedBox(
width: 10,
),
Text(
'Log out',
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
)
],
)
],
),
);
you can see in image here is background and some gradient color on image. I have added the image i want some gradient like in this image
You can add gradient and blendMode to BoxDecoration in order to apply a gradient over the background image.
I want to create a listview item design something like
Click here
and which I have tried so far is Click here
Here is my code
ListTile(
leading: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 44,
minHeight: 44,
maxWidth: 64,
maxHeight: 64,
),
child: Image.network(catData[index]['icon'].toString(),
width: 150,
height: 150,
fit: BoxFit.cover,
headers: headersMap,
)
),
title: Padding(
padding: EdgeInsets.only(left: 10,bottom: 5, right: 10, top: 10),
child: Text(
getCategoryName(catData, index),
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
fontFamily: 'Mada-Medium',
letterSpacing: 0.25,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
),
subtitle: Padding(
padding: EdgeInsets.only(left: 10,bottom: 5, right: 10),
child: Text(
getText(catData[index]['catId'], subCatData),
style: TextStyle(
color: parseColor('##A2A2A2'),
letterSpacing: 0.25,
fontSize: 14,
fontFamily: 'Mada',
fontWeight: FontWeight.w500),
maxLines: 2,
overflow: TextOverflow.ellipsis,
)
),
)
The image portion is not setting properly on listTile title. Please help to create this design
Try this
class ListItem extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0), bottomLeft: Radius.circular(20.0)),
child: Image.asset(
'assets/images/nilesh.jpg',
fit: BoxFit.cover,
height: 120,
width: 100,
),
),
SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(height: 20),
Text(
'Dummy Text',
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
SizedBox(height: 30),
Text(
'Dummy Text',
style: TextStyle(color: Colors.grey, fontWeight: FontWeight.normal),
),
],
))
],
),
);
}
}
OUTPUT
I am building an app facing a singleChildScrollView not able to scroll the page the text has been cut from bottom after the contact button i want to scroll the page but but spending so much time can't fix problem.
enter image description here
enter code here
import 'package:flutter/material.dart';
class DetailScreen extends StatefulWidget {
final electricain;
DetailScreen(this.electricain);
#override
_DetailScreenState createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 3 + 20,
width: MediaQuery.of(context).size.width,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(
'assets/images/detail_bg.jpg',
fit: BoxFit.fill,
),
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.purple.withOpacity(0.1),
),
],
),
),
Positioned(
top: 50,
left: 20,
child: IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
},
),
),
Positioned(
top: MediaQuery.of(context).size.height / 3.6 - 40,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60),
),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 130,
),
Text(
'Description',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
SizedBox(
height: 10,
),
Text(
'${widget.electricain['desc']}',
style: TextStyle(
color: Colors.grey,
),
textAlign: TextAlign.justify,
),
SizedBox(
height: 10,
),
Text(
"\n Services List",
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${widget.electricain['services']}',
style: TextStyle(
color: Colors.grey,
),
),
SizedBox(height: 30),
MaterialButton(
onPressed: () {},
color: Colors.orange,
child: Text(
"Contact",
style: TextStyle(
color: Colors.white, fontSize: 16.0),
),
),
SizedBox(height: 10),
Text(
'${widget.electricain['services']}',
style: TextStyle(
color: Colors.grey,
),
),
],
),
),
),
),
),
),
Positioned(
top: MediaQuery.of(context).size.height / 3 - 90,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 3 - 20,
height: MediaQuery.of(context).size.height / 6 + 20,
decoration: BoxDecoration(
color: widget.electricain['bgColor'],
borderRadius: BorderRadius.circular(20),
),
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 10,
right: -25,
child: Image.asset(
widget.electricain['imgUrl'],
scale: 1.7,
),
),
],
),
),
SizedBox(
width: 20,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
widget.electricain['electricainName'],
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
SizedBox(
height: 5,
),
Text(
widget.electricain['shopName'],
style: TextStyle(
fontWeight: FontWeight.w300,
color: Colors.grey,
),
),
SizedBox(
height: 10,
),
Row(
children: <Widget>[
Icon(
Icons.star,
size: 16,
color: Color(0xffFF8573),
),
SizedBox(width: 5),
Text(
widget.electricain['rating'],
style: TextStyle(
color: Color(0xffFF8573),
),
),
SizedBox(
width: 5,
),
Text(
'(${widget.electricain['rateAmount']})',
style: TextStyle(
color: Colors.grey,
),
),
],
)
],
),
],
),
),
),
],
),
),
);
}
}
try this:
LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//your children here
]
),
)
)
);
})
IntrinsicHeight class
A widget that sizes its child to the child's intrinsic height.
This class is useful, for example, when unlimited height is available and you would like a child that would otherwise attempt to expand infinitely to instead size itself to a more reasonable height.
My banner is overlapping the slack widgets i need to show the ad on bottom or footer but problem is its overlapping the container need to know how can i add in end but not overlap the containers
Here is my code
body: Stack(
children: [
GestureDetector(
onTap: () {
percengtageTrigger();
API.voteplusQuestion(snapshot.data[index], 0);
},
child: Container(
height: stackHeight * 0.5,
width: stackWidth,
color: Color(0xffF9D342),
child: Column(
children: <Widget>[
shouldShow
? Container(
padding: const EdgeInsets.only(
top: 10, right: 10),
height: stackHeight * 0.1,
color: Color(0xffF9D342),
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.end,
children: <Widget>[
Text(
'${percentage1.toStringAsFixed(0)}%',
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontFamily: 'NewsCycle',
),
),
],
))
: Container(
height: stackHeight * 0.1,
color: Color(0xffF9D342),
width: double.infinity,
),
Container(
color: Color(0xffF9D342),
height: stackHeight * 0.4,
width: double.infinity,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(
snapshot.data[index].would,
style: TextStyle(
color: Color(0xff292826),
fontSize: 23,
fontWeight: FontWeight.bold,
fontFamily: 'NewsCycle',
),
),
),
],
)),
],
),
),
),
GestureDetector(
onTap: () {
percengtageTrigger();
API.voteplusQuestion(snapshot.data[index], 1);
},
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: stackHeight * 0.5,
width: stackWidth,
color: Color(0xff292826),
child: Column(
children: <Widget>[
shouldShow
? Container(
padding: const EdgeInsets.only(
top: 10, right: 10),
height: stackHeight * 0.1,
color: Color(0xff292826),
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.end,
children: <Widget>[
Text(
'${percentage2.toStringAsFixed(0)}%',
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontFamily: 'NewsCycle',
),
),
],
))
: Container(
height: stackHeight * 0.1,
color: Color(0xff292826),
width: double.infinity,
),
Container(
color: Color(0xff292826),
height: stackHeight * 0.4,
width: double.infinity,
child: Column(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(top: 40),
child: Text(
snapshot.data[index].rather,
style: TextStyle(
color: Color(0xffF9D342),
fontSize: 23,
fontWeight: FontWeight.bold,
fontFamily: 'NewsCycle',
),
),
),
],
)),
],
),
),
),
),
Align(
alignment: Alignment.center,
child: Container(
width: stackWidth,
height: stackHeight * 0.015,
color: Colors.white,
),
),
Align(
alignment: Alignment.center,
child: Container(
width: stackWidth,
height: stackHeight * 0.15,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: () {
nextQuestion();
},
child: Text(
"SKIP",
style: TextStyle(
color: Colors.black,
fontFamily: 'FredokaOne',
fontSize: 27),
),
),
)),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
child: AdmobBanner(
adUnitId: getBannerAdUnitId(),
adSize: bannerSize,
),
),
),
],
));
As you see in the image it's overlapping the grey container I need a yellow and grey containers in same size but on top of banner no with overlap with banner.
If your content will be scrollable in the future, then I suggest you stick with the floating ad and maybe add a wide grey background to cover some space as I've seen some apps do.
Otherwise, assign it to a small row at the bottom (And assign the rest of the elements to rows as needed). The ad will take up a lot of space though so be sure to adjust the other elements accordingly.
Since you are using stack the children in the stack will overlap. If don't want them to overlap you can use other layout widgets such as Column or ListView according to your need. You can refer to flutter docs for more info on layout widgets.