Can I overflow a widget in Container to make it like clipped? - flutter

I'm following the picture below but got some difficulties when I tried to make that white bubble.
I have tried a method using OverFlowBox from another post Flutter mask a circle into a container but I got the circle stuck in the middle of the Container and I don't know why alignment won't help moving it. Here is what I've tried:
return Container(
alignment: Alignment.topCenter,
height: screenHeight/3.5,
width: screenWidth/3.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
gradient: LinearGradient(
begin: FractionalOffset.topLeft,
end: FractionalOffset.bottomRight,
colors: [boxColorBegin, boxColorEnd]
),
),
child: ClipRect(
clipBehavior: Clip.hardEdge,
child: OverflowBox(
maxHeight: screenHeight/3.5 +20,
maxWidth: screenWidth/3.5 + 20,
child:Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
)
),
),
);
And the result was
Is there any ways to overflow something inside a widget so that it looks like clipped?
Thanks in advance!

I found the way to achieve what I want but am still confused why OverFlowBox can't be aligned. I thought it is because the size of the OverFlowBox is larger than its parent but it still don't work when I changed it to a smaller size.
I used Stack and Positioned widget and set the overflow parameter of the Stack as overflow.clip
Here is the code:
return Container(
height: screenHeight/3.5,
width: screenWidth/3.2,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
gradient: LinearGradient(
begin: FractionalOffset.topLeft,
end: FractionalOffset.bottomRight,
colors: [boxColorBegin, boxColorEnd]
),
),
child: Stack(
overflow: Overflow.clip,
alignment: Alignment.topCenter ,
children: <Widget>[
Positioned(
bottom: screenHeight / 8,
right: screenWidth / 12,
child: Container(
width: screenWidth / 3.5,
height: screenHeight / 3.5,
decoration: BoxDecoration(
color: Colors.white38,
shape: BoxShape.circle,
),
)
)
],
)
)
And the result is
EDIT
Turns out you can just use Container as a clipper with the clipBehavior parameter and use FractionalTranslation widget as child to manipulate the position of the white circle. Thanks to pskink for the simple answer.
Here is the new code
return Container(
alignment: Alignment.topLeft,
clipBehavior: Clip.antiAlias,
height: screenHeight/3.5,
width: screenWidth/3.2,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
gradient: LinearGradient(
begin: FractionalOffset.topLeft,
end: FractionalOffset.bottomRight,
colors: [boxColorBegin, boxColorEnd]
),
),
child: FractionalTranslation(
translation: Offset(-0.25, -0.5),
child: Container(
width: screenWidth / 3.5,
height: screenHeight / 3.5,
decoration: BoxDecoration(
color: Colors.white38,
shape: BoxShape.circle,
),
)
)
);

You can easily accomplish this using ClipRRect as your root container for this widget. Provide it a border radius and it will clip all children and prevent them from painting outside the bounds. You can then use Transform.translate to render a circle and offset it outside its parent.
I created a sample pen for you to try
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),
topRight: Radius.circular(125),
),
child: Container(
height: 400,
width: 250,
decoration: BoxDecoration(
color: Colors.red,
),
child: Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: Transform.translate(
offset: Offset(-40, -100),
child: Container(
height: 220,
width: 220,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(110)),
color: Colors.white.withOpacity(0.4),
),
),
),
),
],
),
),
);
For more information on ClipRRect and Transform.translate visit the API docs.

you can use padding to move the OverflowBox. you also need to clip the parent Container with ClipRRect
here is your fix (tested and works):
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
child: Container(
alignment: Alignment.topCenter,
height: screenHeight / 3.5,
width: screenWidth / 3.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
gradient: LinearGradient(
begin: FractionalOffset.topLeft, end: FractionalOffset.bottomRight, colors: [boxColorBegin, boxColorEnd]),
),
child: ClipRect(
clipBehavior: Clip.hardEdge,
child: Padding(
padding: const EdgeInsets.only(right: 130, bottom: 150),
child: OverflowBox(
maxHeight: screenHeight / 3.5 + 20,
maxWidth: screenWidth / 3.5 + 20,
child: Container(
decoration: BoxDecoration(
color: Colors.white.withAlpha(80),
shape: BoxShape.circle,
),
)),
),
),
),
);

Related

How to make curve border using dart flutter?

I have tried borders, but I didn't get the actual result. Actually, I need this type of border/shape like bottomRight.[enter image description here][1]
See image: https://i.stack.imgur.com/LVtTQ.png
You can achieve it by using Container with BorderRadius.only like below:
return Container(
width: 100.0,
height: 150,
padding: const EdgeInsets.all(20.0),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.zero,
topRight: Radius.zero,
bottomLeft: Radius.zero,
bottomRight: Radius.circular(20.0),
),
),
);
or if you have that triangle png image, you can stack it to the bottom right like this:
return Stack(
alignment: Alignment.bottomRight,
children: [
Container(
width: 100.0,
height: 150,
padding: const EdgeInsets.all(20.0),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.zero,
topRight: Radius.zero,
bottomLeft: Radius.zero,
bottomRight: Radius.circular(20.0),
),
),
),
Image.asset("images/paper_flip.png", width: 30, height: 30,),
],
);
Try to put a container in the stack with box-shadow and use a positioned widget to bring it to the bottom right corner.
For example:
use stack and this stack have 3 widgets
one is the rectangle with border and
the other one is the smaller white rectangle on the first widget to cover the black border and
the last one is the triangle with box-shadow
remember to use box-shadow with both widgets and
positioned widget will put both of them to the right bottom corner
A different solution you can use is a custom image, but you will struggle with the responsiveness.
I hope it helped. 😊
Refer this code:
Container(
height: 90,
width: 90,
padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
margin: EdgeInsets.only(left: 3.0, right: 3.0, bottom: 5.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(0.0),
topRight: Radius.circular(0.0),
bottomLeft: Radius.circular(0.0),
bottomRight: Radius.circular(18.0)),
),
child: Text(
"Hai hello" ?? "",
),
),

How can I have a three sided border with border radius around a container in Flutter?

I need to implement this widget of an image on top and a container with a text underderneath.
The thing is that the container has a three sided border with rounded bottom corners. But flutter won't allow me to have border radius with a non-uniform Border.
here is my code:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
AspectRatio(
aspectRatio: 1,
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4),
topRight: Radius.circular(4),
),
child: Container(
width: MediaQuery.of(context).size.width / 2,
child: CachedNetworkImage(
imageUrl: topic.image,
placeholder: (_, __) => ImagePlaceholder(),
height: (MediaQuery.of(context).size.width / 2) * 1.11,
fit: BoxFit.fill,
),
),
),
),
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(4),
bottomRight: Radius.circular(4)),
border: Border(
bottom: BorderSide(
width: 1, color: Theme.of(context).dividerColor),
right: BorderSide(
width: 1, color: Theme.of(context).dividerColor),
left: BorderSide(
width: 1,
color: Theme.of(context).dividerColor))),
child: Text(topic.title)),
)
],
)
basically I can't get the top border of the container below my image to be transparent.
and here is the exception I get:
The following assertion was thrown during paint():
A borderRadius can only be given for a uniform Border.
The following is not uniform:
BorderSide.color
BorderSide.width
how can i implement this?
Container alone isn't going to cut it here. You are going to need to come up with some sort of workaround. Here's one such workaround using a combination of Container, ClipRRect, and `Column.
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
color: Colors.grey,
child: Column(
children: [
Image(...),
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8)),
),
margin: EdgeInsets.only(left: 4, bottom: 4, right: 4),
child: Text(...),
),
),
],
),
),
),
You will probably want to play with it to get the sizing and layout to look how you want, but that's the general idea.
DartPad example
ClipRRect is what exactly you need to know
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
// Your Image
child: Image()
)
Here is the full code for your goal.
Column(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
child: Image.network(
'imageUrl',
height: 250,
width: 300,
fit: BoxFit.cover,
),
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(40.0),
bottomLeft: Radius.circular(40.0),
),
),
width: 300,
padding: EdgeInsets.symmetric(
vertical: 5,
horizontal: 20,
),
child: Text(
'My Text Here',
style: TextStyle(
fontSize: 26,
),
softWrap: true,
overflow: TextOverflow.fade,
),
),
],
),

Are there a better method to make this effect? [CUSTOM BOTTOMBAR]

I try to make my first app with Flutter.
I have a question i make this custom bottom bar:
Are there better method for make this effect or similar effect?
Is it correct this method with stack and row?
Thanks u and good coding!
Container bottom(Size size) {
double totalElement = size.width / 3;
return Container(
height: size.width * 0.15,
//color: GS.mainColor,
child: Stack(
alignment: Alignment.bottomLeft,
children: [
//LONG ELEMENT
Positioned(
child: Container(
width: totalElement*3,
height: GS.heightBottomElement,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
)
),
)
),
//FIRST ELEMENT
Positioned(
child: Container(
height: GS.heightBottomElement,
width: totalElement*2,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
)
),
)
),
//FIRST ELEMENT
Positioned(
child: Container(
height: GS.heightBottomElement,
width: totalElement,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
)
),
)
),
],
),
);
}
You could extract the Positioned elements into a separate stateless widget, in that way you use the DRY method, and your code will look nicer and cleaner, with less repeated code.
It would look like this:
Container bottom(Size size) {
double totalElement = size.width / 3;
return Container(
height: size.width * 0.15,
//color: GS.mainColor,
child: Stack(
alignment: Alignment.bottomLeft,
children: [
//LONG ELEMENT
MyCutomPositioned(height: blabla, width: blabla, color: blabla),
//FIRST ELEMENT
MyCutomPositioned(height: blabla, width: blabla, color: blabla),
//SECOND ELEMENT
MyCutomPositioned(height: blabla, width: blabla, color: blabla),
],
),
);
}

How to draw rounded rectangle with borders only on top?

There are multiple ways to draw a rounded rectangle. I want to draw a rounded rectangle with content inside. However, only the top of the rectangle should be rounded.
I tried
Container(
decoration:
BoxDecoration(border: Border(top: BorderSide(color: Colors.red))),
child: Column(
children: [Text("hello")],
));
but I get a red line with "hello" on bottom. Makes no sense.
With BorderRadius.vertical you can choose top corners or bottom corners.
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
And with BorderRadius.only you can choose any corner.
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
It's a little trick
Container(
height: 100,
width: 150,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(
const Radius.circular(15.0),
),
),
child: Container(
margin: const EdgeInsetsDirectional.only(top: 2),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(13.0),
topRight: const Radius.circular(13.0),
),
),
child: Column(
children: [
Text("hello"),
],
)
),
)
Try this
Container(
decoration: ShapeDecoration(
color: Colors.yourColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
),
),
),

How to make one side circular border of widget with flutter?

I'm trying to build one side circular border with Container widget in flutter.
I have searched for it but can't get any solution.
Container(
width: 150.0,
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(30.0),
/* border: Border(
left: BorderSide()
),*/
color: Colors.white
),
child: Text("hello"),
),
Use BorderRadius.only and provide the sides
return Center(
child: Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(40),
),
border: Border.all(
width: 3,
color: Colors.green,
style: BorderStyle.solid,
),
),
child: Center(
child: Text(
"Hello",
),
),
),
);
Output
You can achieve this by following code for creating your widget :
return Container(
width: 150.0,
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.zero,
bottomLeft: Radius.zero,
bottomRight: Radius.zero,
),
),
child: Text(
"hello",
),
);
This way you can have your top left sided circular border with Container widget in flutter.
Another way of doing this is to use the ClipRRect widget.
Simply wrap your widget with ClipRRect and give a radius.
You can specify which corner you want to make round.
ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(10)),
child: Container(
height: 40,
width: 40,
color: Colors.amber,
child: Text('Hello World!'),
),
);
If you want one side of a container rounded you want to use BorderRadius.only and specify which corners to round like this:
Container(
width: 150.0,
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(40.0),
bottomRight: Radius.circular(40.0)),
color: Colors.white),
child: Text("hello"),
),
Also You can do it with 'Shape Function'.
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(15.0),
topLeft: Radius.circular(15.0),
),
also do can do as follows,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(30.0),
bottomLeft: const Radius.circular(30.0),
),
You can also set the radius of each side.
margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
fromLTRB= from Left, Top, Right, Bottom