FractionallySizedCircle? in flutter - flutter

is there any tricks to achieve sth like a FractionallySizedBox
to get a circle the size of a fraction of parent's height or width ?
like this :
FractionallySizedCircle(
heightFactor: .5,
child: ClipRRect(
borderRadius: BorderRadius.circular(2000), // side question : is there a better way to achieve this too ?
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: globals.lightBlue,
),
child: Align(
alignment: Alignment(0, 1),
child: SvgPicture.asset(
'assets/images/boy-id.svg'),
),
),
),
),
[Update] : I needed to have a circular ClipRRect just like the sample code has the ClipRRect in it, changed it with clipOval and did the job, but would come in handy if we could have real FractionallySizedCircle (this ClipOval is actually an oval obviuosly), so the question stays open...

You can use FractionallySizedBox and Container simply like this:
FractionallySizedBox(
heightFactor: 0.5,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.lightBlue,
),
),
)

Related

How can I apply notch curve to Widget?

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.

How to draw a dynamic height line in flutter?

I wanted to draw a dynamic height line, as shown in the given picture below
I did something line this using a continer with one sided border
Container(
child:(content goes here....)
margin: EdgeInsets.symmetric(horizontal:16+20.0),
decoration: BoxDecoration(
border: Border(
left: BorderSide(width: 2.0, color: Colors.lightBlue.shade600),
),
color: Colors.white,
),
)
but the issue is the corners(top and below) of the line is not rounded.
I want to draw a vertical line on the left side of my post, and on the right side goes the content.
You could try something like this:
IntrinsicHeight(
child: Row(
children: [
Container(
width: 5,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
color: const Color(0x7f9e9e9e),
),
),
Expanded(child: **content goes here**),
],
),
)
And here's a DartPad example for you: Example
Which will produce something like this:
Where the bar on the left will size automatically with the contents on the right.

RectangleBox In Flutter

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.

Transformation distorts the border radius of container in flutter

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.

How to add a border/corner radius to a LinearProgressIndicator in Flutter?

I am trying to add a border radius to a LinearProgressIndicator in Flutter.
When I replace the LinearProgressIndicator with another widget (e.g. Text) in the code below, it works, as expected.
Container(
decoration: new BoxDecoration(
borderRadius:
new BorderRadius.all(const Radius.circular(20.0))),
child: LinearProgressIndicator(
value: _time,
),
)
1) Using Widget
Container(
margin: EdgeInsets.symmetric(vertical: 20),
width: 300,
height: 20,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: LinearProgressIndicator(
value: 0.7,
valueColor: AlwaysStoppedAnimation<Color>(Color(0xff00ff00)),
backgroundColor: Color(0xffD6D6D6),
),
),
)
2) Using dependency
List of different types indicator https://pub.dev/packages/percent_indicator
Try this template code
child: Padding(
padding: EdgeInsets.all(15.0),
child: LinearPercentIndicator(
width: MediaQuery.of(context).size.width - 50,
animation: true,
lineHeight: 20.0,
animationDuration: 2000,
percent: 0.9,
linearStrokeCap: LinearStrokeCap.roundAll,
progressColor: Colors.greenAccent,
),
)
Edit: I just wanted to point out my answer doesn't account for rounding the end of the 'value' fill inside the bar, which the OP wanted. However it seems many people came to this question looking for the answer I provided, (as did I before I found the answer and came back to respond).
So if you need the inside of this indicator also to have a rounded edge, as of now I think the accepted answer from Amit is the best route. If the inside of the indicator can have a flat edge and you don't want to use a third party package, I think my answer below is still the best option.
Original:
You actually don't need to use a third party package, and can wrap your LinearProgressIndicator with the ClipRRect widget and give it a circular border radius. If you want to give it a specific thickness/height then you could use a container as an intermediary:
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
height: 10,
child: LinearProgressIndicator(
value: 0.35, // percent filled
valueColor: AlwaysStoppedAnimation<Color>(Colors.orange),
backgroundColor: Color(0xFFFFDAB8),
),
),
)
would produce this, if placed in another widget with a defined width:
Let's try my custom progress bar, simple and don't use any library :)
class ProgressBar extends StatelessWidget {
final double max;
final double current;
final Color color;
const ProgressBar(
{Key? key,
required this.max,
required this.current,
this.color = AppColors.secondaryColor})
: super(key: key);
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (_, boxConstraints) {
var x = boxConstraints.maxWidth;
var percent = (current / max) * x;
return Stack(
children: [
Container(
width: x,
height: 7,
decoration: BoxDecoration(
color: Color(0xffd3d3d3),
borderRadius: BorderRadius.circular(35),
),
),
AnimatedContainer(
duration: Duration(milliseconds: 500),
width: percent,
height: 7,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(35),
),
),
],
);
},
);
}
}
You can try this code:
Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(40.0))),
child: const ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20)),
child: LinearProgressIndicator(
minHeight: 5.0,
value: 0.2,
color: Colors.white,
backgroundColor: Color(0xFF3B2D73),
),
),
I am going to leave my answer in case someone is looking for something custom, basic with custom BorderRadius
Container(
height: 24.0,
margin: EdgeInsets.only(top: 12.0, bottom: 2.0),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
clipBehavior: Clip.antiAlias,
child: FractionallySizedBox(
alignment: Alignment.centerLeft,
widthFactor: 0.57,
heightFactor: 1.0,
child: Container(
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
clipBehavior: Clip.antiAlias,
),
),
),
Feel free to try it out :)
Do not need to wrap LinearPercentIndicator inside a Container widget. You could get the desired output only using LinearPercentIndicator.
See the template code
LinearPercentIndicator(
lineHeight: 40.0,
barRadius: const Radius.circular(20.0),
percent: 0.7,
animation: true,
animationDuration: 1000,
backgroundColor: Color(0xFFD6D6D6),
progressColor: Color(0xFF5BFB82),
),
To make the inner bar rounded, we need to use the following logic :
Make the Outer progress bar rounded, use ClipRRect and set borderRadius
To make the inner bar rounded, we can use Container, where we will make one side (right side) rounded using borderRadius. Then, we will place it on top of our progress bar, using Stack.
The width of the container will be actually the progress shown in the progress bar.
Container(
width: (MediaQuery.of(context).size.width - 30) *
calculateProgressBarValue(Data1, Data2),
height: 6,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(CommonDimens.MARGIN_10),
bottomLeft: Radius.circular(CommonDimens.MARGIN_10),
),
color: progressBarColor,
),
Full code :
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(10)),
child: Stack(
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(10)),
child: LinearProgressIndicator(
minHeight: 6.0,
valueColor:
AlwaysStoppedAnimation<Color>(Colors.grey),
value: 1,
),
),
Positioned(
right: 0,
child: Container(
width: ((MediaQuery.of(context).size.width) - 30) *
calculateProgressBarValue(Data1,Data2),
height: 6,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(CommonDimens.MARGIN_10),
bottomLeft: Radius.circular(CommonDimens.MARGIN_10),
),
color: progressBarColor,
),
),
],
),
);
You can make use of
curved_progress_bar , It has both CurvedCircularProgressIndicator as well as CurvedLinearProgressIndicator, and it works just like normal CircularProgressIndicator and LinearProgressIndicator.
You could try my library (capped_progress_indicator) that does what you want and works exactly like Flutter's original LinearProgressIndicator and CircularProgressIndicator. It not only rounds the ends of the track/background but also the ends of the progress/indicator.
So its just a matter of installing the package and changing your code from
LinearProgressIndicator(
// ...
)
to
import 'package:capped_progress_indicator/capped_progress_indicator.dart';
LinearCappedProgressIndicator(
// ...
)
You can also change the corner radius to your liking
LinearCappedProgressIndicator(), // Circle end (default).
LinearCappedProgressIndicator(cornerRadius: 5), // Rounded end.
LinearCappedProgressIndicator(cornerRadius: 0), // Square end.