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.
Related
I have created a Card whose height depends on its content, so it's height is not defined anywhere. Now I want to add a left blue border to the Card, whose height adjusts to the current height of the Card (his parent).
So when I type in any fixed height (e.g. 50), the blue border looks like this:
height: 50
This is my Code:
Card(
margin: EdgeInsets.zero,
elevation: 0,
color: Colors.black12,
shape: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(6)),
borderSide: BorderSide.none,
),
child: Container(
width: double.infinity,
child: Stack(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text("This is random text."),
Text("There can be more."),
Text("So the height of this Card is never fix."),
],
),
),
Container(
height: 50, // This height must match the current height of the Card
width: 8,
decoration: const BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(topLeft: Radius.circular(6), bottomLeft: Radius.circular(6))
),
)
],
),
),
)
But I want a dynamic height, with which it should look always like this, whether the content changes or not:
height: matches current height of Card
Neither double.infinity helped me nor an Expanded Widget.
You can use Container's decoration as parent and ClipRRect to round the corners. You can also wrap with Card if you feel needed.
Padding(
padding: const EdgeInsets.all(24.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.grey,
border: Border(
left: BorderSide(
color: Colors.blue,
width: 12,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: const [
Text("This is random text."),
Text("There can be more."),
Text("So the height of this Card is never fix."),
],
),
),
)),
A way to do this with much less code:
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
// add Card-like elevation
boxShadow: kElevationToShadow[4],
gradient: LinearGradient(
stops: const [0.03, 0.03],
colors: [
Colors.blue,
Colors.grey[900]!,
],
),
borderRadius: BorderRadius.circular(3),
),
child: const Text(' Sunt magna irure ut reprehenderit.'),
),
If you use a gradient you might want to add some padding on the left of the text though since it might go into that "Color Marker" in the next line depending on how big the width is.
Result
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.
I am trying to make a gradient colored flat button but left and right edges of the button are not getting colorized as the image.
And here is my flatbutton codes:
return new Container(
width: MediaQuery.of(context).size.width,
height: 40,
child: RaisedButton(
focusNode: buttonFocusNode,
onPressed: () {},
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Colors.pink, Colors.purple],
),
),
),
),
);
}
It happens on both emulator and real device. My hyerarchy to button in build is : SafeArea->Scaffold->Container->Stack->Container->Column->Button. I tried to wrap it inside container, sizedbox, played with width but nothing helped. Any idea why this is happening and how can I solve it? Thanks in advance.
Solution with an ElevatedButton:
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
),
clipBehavior: Clip.antiAlias, // <====== [2]
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), // <====== [1]
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Colors.pink, Colors.purple],
),
),
child: Text(
'CLICK ME!',
style: TextStyle(color: Colors.white, fontSize: 48.0),
),
),
)
Important point 1
Since you remove the padding on the button, remember to add it on the child Container. Otherwise, you'll have problems once you add some text:
Important point 2
If you want rounded corners, remember to set the Clip Behavior of the button. Otherwise, you will not get your rounded corners:
Because RaisedButton adds padding for the child. You need to set the padding to EdgeInsets.zero.
Example
RaisedButton(
padding: EdgeInsets.zero,
In my code, there is this CircleAvtar which I want to replace it with a big rectangular box. I am new to flutter I am finding it difficult to achieve this.
child: Card(
elevation: 3,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
child: Container(
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
10,
),
// border: Border.all(width: 0.5),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
color: whiteColor,
),
child: expertiseSearchModel.userImageURL.isEmpty
? CircleAvatar(
radius: 35,
child: SvgPicture.asset(
'assets/images/default_user_image.svg',
// height: screenUtil.setSp(80),
// width: screenUtil.setSp(80),
fit: BoxFit.contain,
),
)
: CircleAvatar(
radius: 35,
backgroundImage:
NetworkImage(expertiseSearchModel.userImageURL),
),
),
I want it to look like this :
If you can show us what your current code is giving the output maybe I can help you more. But As far as i understood this, you can simple use Image.Network() to show the image and remove the circular avatar
Try this, if it works if not lemme know I will edit it accordingly
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
color: whiteColor,
),
child: expertiseSearchModel.userImageURL.isEmpty
? CircleAvatar(
radius: 35,
child: SvgPicture.asset(
'assets/images/default_user_image.svg',
// height: screenUtil.setSp(80),
// width: screenUtil.setSp(80),
fit: BoxFit.contain,
),
)
: Image.network(expertiseSearchModel.userImageURL)
),
Inside your main container use the column as a child and put another container as a child and use the Image decoration property of the container to display pictures. You can change the border-radius of the child container to have those circular edges.
Align(
alignment: Alignment.bottomCenter,
child: Container(
//padding: EdgeInsets.all(20.0),
height: 50,
width: 320,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(15.0))),
child: Stack(children: <Widget>[
Align(
alignment: Alignment.center,
child: Transform(
alignment: Alignment.topRight,
transform: Matrix4.diagonal3Values(4.0, 1.0, 1.0),
child: Container(
height: 45,
width: 45,
decoration: BoxDecoration(
//color: Color(0xffff8d27),
color: Colors.grey,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(10.0))
)),
),
),
Row(
children: <Widget>[
Expanded(
child: Center(
child: Text(
'Reservation',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
Align(
alignment: Alignment.center,
child: Icon(Icons.attach_money)),
Expanded(
child: Center(
child: Text(
'Now',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
)
],
)
])))
This is the current result
I have used a stack with the bottom layer being a container with grey color and 15.0 border radius aligned in the center, and the top layer containing text in two expandables and an icon in centre. I am trying to implement a two way slider button. I have not implemented the sliding part yet but that won't be an issue. When the user slides on a particular side the grey colored container in the bottom of stack streches on the respective side of the slide in turn depicting a selection. I am using the transform widget to scale the container in x dimension or simply speaking stretching it. The problem is that this transformation tends to distort the border radius of the container which is not producing the desired effect.
How can I stretch or transform the container so that it does not affect the border radius?
final _transformRight = Matrix4.identity()..translate(130.0);
final _transformLeft = Matrix4.identity(); //It means zero.
bool _shouldTransformRight = false;
#override
Widget build(BuildContext context) {
...
body: GestureDetector(
child: Container(
...
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
),
child: Stack(
children: <Widget>[
AnimatedContainer(
...
duration: Duration(milliseconds: 200),
decoration: BoxDecoration(
color: Colors.grey,
//You can create a variable to unify the
//borderRadius for all containers.
borderRadius: BorderRadius.circular(15.0),
),
transform: _shouldTransformRight
? _transformRight
: _transformLeft,
),
Row(...),
],
),
),
onHorizontalDragEnd: (details) {
setState(() {
_shouldTransformRight = !_shouldTransformRight;
});
}
),
...
}
Summary of the edits that I've made to your code:
No need to provide a shape and a corner radius for the container at the same time. Using one of them alone is sufficient.
In the corner radius of the container I used BorderRadius.circular(...) instead of BorderRadius.all(...), because it's shorter.
I've replaced the first child of the Stack with AnimatedContainer and used it's transform argument to position it accordingly. The Matrix4.diagonal3Values(4.0, 1.0, 1.0) it was the cause for the distorted border radius.
Lastly, I wrapped the whole widget tree in a GestureDetector, so that I can get the user input, which based on it I'm gonna translate the AnimatedContainer. You can configure which callBack of GestureDetector to use, here I've used onHorizontalDragEnd.