Icon widget cut off by Image widget - flutter

I'm trying to implement a "Change my profile picture" icon like how it appears in the profile page in Whatsapp, where a clickable camera icon hovers on the bottom right of the image.
This is the code I used inside a stateful widget:
Row(
children: <Widget>[
Stack(
children: <Widget>[
Container(
width: 120,
child: Image(
image: AssetImage('affogato.png'),
),
),
Positioned(
top: 70,
left: 90,
child: FloatingActionButton(
child: Icon(Icons.camera_alt),
onPressed: () {},
),
),
],
),
],
),
Strangely, the Icon seems to take the constraints of the Image container. So when I set the width as 120 and try to push the Icon button to the bottom right edge of the Image, it gets cut off by the Image constraints. How do the constraints of the Container affect the FloatingActionButton even though they're siblings inside the Stack not parent-child widgets? And how can I fix this so that the Icon can float over the edge of the image?

You can probably make use of height property of Positioned widget and adjust other dimensions (left, bottom, right, top) so that the button isn't cut-off at bottom right edge and is displayed properly. Working sample code below:
return Scaffold(
body: Center(
child: Row(
children: <Widget>[
Stack(
children: <Widget>[
Container(
width: 120,
child: Image(
image: AssetImage('assets/Icon-512.png'),
),
),
Positioned(
bottom: 0,
right: 0,
left: 78,
height: 35,
child: FloatingActionButton(
child: Icon(Icons.camera_alt),
onPressed: () {},
),
),
],
),
],
),
)
// This trailing comma makes auto-formatting nicer for build methods.
);
You might need to adjust dimensions per your need, but this way it doesn't cut-off the button.
Hope this answers your question.

Here's how I did it. I removed the Positioned widget completely and used Padding instead. It seemed to solve the problem. I also wrapped the image in a CircleAvatar to complete the Whatsapp style.
Row(
children: <Widget>[
Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: CircleAvatar(
radius: 70,
backgroundColor: Colors.greenAccent,
child: Container(
height: 150,
width: 150,
child: ClipOval(
child: Image(
image: AssetImage('lib/rainy.png'),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(left: 105, top: 80),
child: Container(
width: 50,
height: 50,
child: FloatingActionButton(
backgroundColor: Colors.green,
child: Icon(Icons.camera_alt),
onPressed: () async {},
),
),
),
],
),
],
),

Related

SizedBox() not increasing size of CircularProgressIndicator()

I was having issues increasing the size of my circular progress indicator and after doing some research I landed on this Stack Overflow question: How to set size to CircularProgressIndicator?
So I wrapped my item in a SizedBox() and increased the height and width and nothing changed.
I Also tried adding an expanded to the circular progress indicator but that didnt work either:
return Expanded(
child: PageView(
controller: pageViewController,
children: [
PackSummaryWeightGraph(
categoryWeightList: categoryWeightList,
totalWeight: totalWeight),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 40,
width: 40,
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
],
),
const Center(
child: Text('Third Page'),
),
],
),
);
Edit:
IS there anyway to do this programmatically so I do not need to set the size of the width and height manually? I just want it to fill the space.
It needs a parent with constraint, try to wrap it inside a Center or Align
Center(
child: SizedBox(
height: 40,
width: 40,
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
),
Try wrapping the CircularProgessIndicator in a FittedBox like so:
SizedBox(
height: 40,
width: 40,
child: FittedBox(
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
)

Flutter how to remove default padding from stack positioned

CODE:
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.blue,
body: SafeArea(
child: SingleChildScrollView(
physics: ClampingScrollPhysics(),
child: Align(
alignment: Alignment.center,
child: Container(
width: Get.width,
height: Get.width * 16 / 9,
child: Stack(
children: [
Positioned(top: 16, left: 16, child: BackButton()),
Positioned(
left: 0,
bottom: 0,
child: IconButton(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0),
icon: Icon(
Icons.delete_forever,
color: Colors.greenAccent,
size: 32,
),
onPressed: () {
},
),
),
],
),
),
),
),
),
);
}
There is some margin on IconButton.
I think IconButton should be tight on bottom left.
How to remove margin IconButton and screen side?
Actually it's the default padding of the Icon Button only...
That is, the stack is placing the button at bottom left but icon in the button is padded by default.
You can try using Gesture detector with that icon as a child...
You will get different result...
Please correct me if i am wrong..

Add a button with a size and add icon inside it in flutter

I am trying to add an icon to a button.
What steps I followed: Created an icon button filled in the properties.
After this, I wrapped it in a container because I don't want my button to be big.
Here is the image of what I am getting: [![enter image description here][1]][1]
I want that Icon to be fit inside the button,I even tried to wrap the child with centre but still the same results.
My Code Snippet:
Container(
height:18,
width:20,
decoration:BoxDecoration(
border:Border.all(color:Colors.orangeAccent,width:1),
shape:BoxShape.rectangle,
),
child:Centre(child:IconButton(
icon:Icon(Icons.add,
size:16,
color:Colors.orange,),
onPressed:(){},
),),
You can try this code block
Container(
width: 50,
height: 50,
child: FlatButton(
onPressed: () {},
child: Row(
children: [
Icon(Icons.ac_unit),
Text('Add More')
],
),
),
)
The easiest way you can do like below code.
Container(
width: 50,
height: 50,
child: GestureDetector(
onTap: () {},
child: Row(
children: [
Icon(Icons.ac_unit),
Padding(
padding: EdgeInsets.only(left: 10),
child: Text('Add More'),
)
],
),
),
)
You can use TextIconButton instead of IconButton.

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)),
)
],
),
),
],
),
)
],
),

How do deal with nested InkWell with Flutter?

Suppose you have a few nested InkResponse, if you tap on the inner one, all of the parent will actually trigger the splash effect even though they will loose in the tap arena for the right tapped widget. The effect will be something like this:
How to prevent such behavior? How to display the splash only for the tapped widget? In this example image it's being used a Container > Row (with InkReponse) > Icon (also with InkResponse). This will also happen if you use material buttons.
You might want to try IgnorePointer
I encourage you to use Stack widget because you can be able to put together multiple widgets. Here there is an example of a container with inner container and they are both clickable independently,
Stack(
children: [
InkWell(
onTap: (){},
child: Container(
width: 400,
height: 400,
color: Colors.green,
),
),
Positioned(
top: 30,
left: 20,
child: InkWell(
onTap: (){},
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
))
],
)
This worked for me
Center(
child:Container(
width: 100,
height: 100,
child: Card(
child: InkWell(
splashColor: color3,
onTap: () {
},
child: Column(
children: [
SizedBox(
height: 10,
),
IconButton(
splashRadius: 7,
splashColor: Colors.pink,
onPressed: () {},
icon: SvgPicture.asset(
ImageConst.bellIcon,
width: 20,
height: 20,
color: Colors.black,
),
),
SizedBox(
height: 10,
),
Text("text"),
],
),
),
),
),
)
Try to wrap the icon into GestureDetector with the empty handler + Padding.