I have two icons in a stack. I want one to hide the other, but instead it's semi-transparent and the other is shown behind it.
This is the code:
Stack(
children: [
Container(child: Icon(Icons.account_circle_rounded), padding: EdgeInsets.only(left: 10),),
Container(child: Icon(Icons.account_circle_rounded), padding: EdgeInsets.only(left: 20),),
],
)
This is how it looks:
Icons are more like SVG, use vector to draw shape. There are some empty spaces inside the icon to draw the path, and we can see the background though this. Also, it contains padding around it, You can use your assets to draw the UI.
We can wrap with another ColoredBox to hide the background icon, but it will get extra padding from IconData.
This snippet shows basic level structure.
SizedBox(
height: 24,
width: 24 * 1.7,
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.centerLeft,
child: Container(
child: const Icon(
Icons.account_circle_rounded,
),
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
child: const Icon(
Icons.account_circle_sharp,
),
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
),
],
),
),
Widget renders bottom to top.
Related
I have a design as you can see below and the question is how can I apply this notch effect on Arrow ? Is there any easy way to do it just like in Floating Action Button ? Thanks in advance.
I have created Dartpad, please look into this and do let me know if you need any help.
Dartpad Link : https://dartpad.dev/flutter?9bd55396e067e71a839851e18905f478
Code:
Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
height: 70,
child: Stack(alignment: Alignment.centerRight, children: [
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: Container(
height: 70,
decoration: BoxDecoration(
color: Colors.cyan, borderRadius: BorderRadius.circular(8)),
),
),
Container(
width: 40,
height: 65,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 5)),
child: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.cyan,
child: const Icon(Icons.chevron_right),
),
)
]),
),
);
Output:
Hey you can achieve it in 2 way
1st one and simple - Create a box decoration widget and a circle shape widget with white border and put these together with Stack and fit as per your requirements.
2nd use Custom Clipper or Custom Paint and draw your shape.
Here I'm taking two widgets one is textfield widget and another one is Icon widget both are placed in seperate container. I'm very new to flutter, I dont know how to place two widgets parallely each other with different size. But somehow designed for my mobile but when i run my app on different mobile its widgets are overflowing.Can anybody help me out from this issue. Thanks in advance!!! For More reference see the image given.
Here is my code
Padding(
padding: const EdgeInsets.only(
top: 10.0, bottom: 4.0, right: 20.0, left: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
child: Material(
color: Colors.white,
elevation: 3.0,
// CONTAINER BACKSIDE SHADOW DEPTH
borderRadius: BorderRadius.circular(5.0),
shadowColor: Color(0xFF90A4AE),
//CONTAINER BACKSIDE SHADOW COLOR
child: Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: IconButton(
icon: Icon(
Icons.search,
color: Colors.pink,
),
onPressed: () {},
),
hintText: "Search for restaurant",
hintStyle: TextStyle(fontSize: 15),
),
onChanged: (input) {
print(input);
},
),
),
),
height: 55.0,
width: MediaQuery
.of(context)
.size
.width - 120,
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
width: 1.0,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(5.0),
),
),
Container(
child: Material(
color: Colors.white,
elevation: 3.0,
// CONTAINER BACKSIDE SHADOW DEPTH
borderRadius: BorderRadius.circular(5.0),
shadowColor: Color(
0xFF90A4AE),
child: IconButton(
icon: Icon(Icons.tune),
color: Colors.pink,
onPressed: () {
[enter image description here][1]
},
), //CONTAINER BACKSIDE SHADOW COLOR
),
height: 55.0,
width: MediaQuery
.of(context)
.size
.width - 300,
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
width: 1.0,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(5.0)),
)
],
),
),
From the screenshot and the code, I see there are two widgets in a row and the screen is overflown as it couldn't accommodate and show both of them.
There are two solutions:
To show the row children in the next line automatically if overflown.
To make the row children scrollable row-wise.
NOTE: SMLink is my custom widget. Just used here for demonstration purposes.
SOLUTION-1
The simple workaround would be to use the Wrap widget instead of the Row widget.
The Wrap widget simply takes the children who are prone to screen overflow and places them on the next line. You can set the direction, spacing etc, in addition to the options that Row widget can offer. Try it & let me know.
// By default, it behaves as Row, you can set the direction attribute to Axi.vertical to mimic the Column widget.
Wrap(
spacing: 8.0,
runAlignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
alignment: WrapAlignment.center,
children:
[
SMLink(logo: 'Medium', link: Constants.LINK_MEDIUM),
SMLink(logo: 'linkedin', link: Constants.LINK_LINKEDIN),
SMLink(logo: 'facebook', link: Constants.LINK_FAEBOOK),
SMLink(logo: 'Qwiklabs', link: Constants.LINK_QWIKLABS),
],
)
SOLUTION-2
From the screenshot, the other way to fix would be by making the row scrollable. This makes UI look consistent in your case. We can use ListView widget for this.
ListView(
scrollDirection: Axis.horizontal,
children:
[
SMLink(logo: 'Medium', link: Constants.LINK_MEDIUM),
SMLink(logo: 'linkedin', link: Constants.LINK_LINKEDIN),
SMLink(logo: 'facebook', link: Constants.LINK_FAEBOOK),
SMLink(logo: 'Qwiklabs', link: Constants.LINK_QWIKLABS),
],
)
I have two Container widgets in a Column, each containing a Text widget. I want the Container with the shortest text to expand to match the width of the other container containing the longer text. The container with the longer text should wrap the Text widget and its padding.
I can't get it to work without resorting to fixed widths on the containers:
return Column(
mainAxisSize: MainAxisSize.min,
children: [
// This container has a shorter text than its sibling, so it should expand
// its width to match its sibling/parent
Container(
alignment: Alignment.center,
width: 50, // I don't want this fixed width
decoration: BoxDecoration(color: Colors.orange, borderRadius: BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4))),
child: Padding(
padding: const EdgeInsets.fromLTRB(8,4,8,4),
child: Text('short'),
)
),
// This container has a longer text, so it should decide the width of the
// other container (and of the parent Column)
Container(
alignment: Alignment.center,
width: 50, // I don't want this fixed width
decoration: BoxDecoration(color: Colors.orange, borderRadius: BorderRadius.only(bottomLeft: Radius.circular(4), bottomRight: Radius.circular(4))),
child: Padding(
padding: const EdgeInsets.fromLTRB(8,4,8,4),
child: Text('long text here'),
)
),
]
);
I've tried a couple of ways to solve it involving Expanded and Flexible, but they all result in the "red screen of death" (or at least "annoyance").
EDIT
Just to be clear - I want the Column to just wrap its content, i.e. adjust its width to the width of the containers. In summary - everything should be as narrow as possible, except for the container with the shortest text, which should instead be as wide as its sibling (the container with the longer text).
I saw your Fiddle on a comment. And what you need is IntrinsicWidth.
IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// This container has a shorter text than its sibling, so it should expand
// its width to match its sibling/parent
Padding(
padding: const EdgeInsets.symmetric(vertical: 1.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Text(
'short',
textAlign: TextAlign.center,
),
),
),
),
// This container has a longer text, so it should decide the width of the
// other container (and of the parent Column)
Padding(
padding: const EdgeInsets.symmetric(vertical: 1.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Text(
'long text here',
textAlign: TextAlign.center,
),
),
),
),
],
),
),
You can use something like this to take the entire width of the Widget (make sure to be inside a MaterialApp and a Scaffold/Material child (home):
Wrap(
children: <Widget>[
Container(
color: Colors.red,
child: IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.black,
height: 200,
child: Align(
alignment: Alignment.bottomRight,
child: Text(
"Hello World",
style: TextStyle(color: Colors.white),
),
),
),
Container(
color: Colors.blue,
height: 100,
child: Align(
alignment: Alignment.topRight,
child: Text(
"Bottom Text Longer Text",
style: TextStyle(color: Colors.white),
),
),
),
],
),
),
),
],
)
The Align is not necessary, is just to showcase how the width actually works with "double.infinity" and moving a text to the bottom right or top right portion of it.
How can i apply a gradient like here to the app background? Can you see the gradient moving down on that the app bar and the scaffold body just like they were one widget and not 2 widgets that each has his own color?
You need to use container as background to your scaffold to add a gradient. You can use Opacity widget as well to make container or any widget transparent. But here is the exact solution what you are looking for:
Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF282a57), Colors.black],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(20, 50, 20, 0),
child: Container(
child: Row(
children: <Widget>[
Icon(Icons.menu,color: Colors.white,),
Spacer(),
Text("Expense",style: TextStyle(color: Colors.white,fontSize: 18,)),
Spacer(),
Icon(Icons.clear, color: Colors.white,)
],
),
),
),
],
),
)
[Update] : I got the solution, If you want the code, comment below or if you just want to know I've written it here :
The solution is to put the Cover Image and the Followers & Following inside a Column (as a single widget) and then put that Column and the Align (profile picture) both inside a Stack, then set the Fixed heightFactor.
So it would look something like this :
Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(), //The Cover Photo
Container(
child: Card() //The Followers and Following Card
)
]
),
Align() //The Profile Picture having fixed heightFactor
]
)
This solution is working on all 4 Devices I have + 2 Android Emulators (2 have 16:9 ratio, 2 have 18:9 and 2 have 19:9 ratio).
The problem is following :
On my device, which is having 18:9 Aspect Ratio there is no Bottom Overflowing issue.
But on devices having 16:9 Aspect Ratio it's having this issue.
This happens only when I try to set heightFactor of Followers & Following Align widget.
I tried to tweak many things in Stack so I could overcome this, but couldn't achieve similar result. So, I'm stuck with this.
Also, as far as I know I can overlap only by using Stack widget. If there is any possible option, do say.
Here is my code :
Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 224.0,
margin: EdgeInsets.all(8.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(8.0),
image: DecorationImage(
image: NetworkImage("https://www.eta.co.uk/wp-content/uploads/2012/09/Cycling-by-water-resized-min.jpg"),
fit: BoxFit.cover
)
),
),
Align(
heightFactor: 5.0,
child: Container(
alignment: Alignment.bottomCenter,
width: MediaQuery.of(context).size.width,
height: 96.0,
margin: EdgeInsets.all(8.0),
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
elevation: 0.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
"Followers",
style: TextStyle(
fontFamily: "Nunito",
fontWeight: FontWeight.bold,
color: Colors.blue
),
),
Text(
"3000",
style: TextStyle(
fontFamily: "Nunito",
color: Colors.blue
),
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
"Following",
style: TextStyle(
fontFamily: "Nunito",
fontWeight: FontWeight.bold,
color: Colors.blue
),
),
Text(
"0",
style: TextStyle(
fontFamily: "Nunito",
color: Colors.blue
),
),
],
),
],
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
heightFactor: 2.75,
child: Card(
color: Colors.transparent,
elevation: 0.0,
child: Container(
alignment: Alignment.bottomCenter,
width: 96.0,
height: 96.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage("https://cdn140.picsart.com/284302087007201.jpg?c256x256"),
fit: BoxFit.fill
),
border: Border.all(width: 4.0, color: Colors.blue)
),
),
),
),
],
),
You've provided the height of widget manually so it'll overflow on smaller screens. So you have to provide the height of widget depending upon the screen. You can use MediaQuery.of(context).size.height to get the height of the device.
And you can also multiply it with some number to get the height in percentage. For example, if you want 80% height of the screen then you can do MediaQuery.of(context).size.height * 80
The answer from #yashthakkar1173 is correct. That's one way of doing it. In addition to that I would say to his solution you can use
ConstrainedBox(
child: Card(),
constraints: BoxConstraints(
minHeight: 96.0,
maxHeight: 106.0,
))
What I observe is that you don't need the entire view to be in a Stack since it's just the top three widgets that overlap so I would wrap that stack in a column and set MainAxisSize to Min. I've done something similar, or you can set it to max so it'll always fill all the space left over.