I'm trying to achieve this design:
I also want to use a Card widget provided by Flutter. It comes with some nice theming support that I'd like to use (CardTheme).
So don't know how to give a LinearGradient to a Card. Here's what I tried to do with combining a Card with Container:
Card(
child: Container(
margin: EdgeInsets.all(5),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
cardBorderColor,
Theme.of(context).colorScheme.surface,
],
stops: [0, 0.8],
),
),
child: ...
As you can see, the border radius of the card is respected when positioning the Container.
Setting the clipBehavior property of the Card to Clip.antiAlias achieves the desired outcome:
Card(
clipBehavior: Clip.antiAlias, // <-- this did the trick
margin: EdgeInsets.all(5),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
cardBorderColor,
Theme.of(context).colorScheme.surface,
],
stops: [0, 0.8],
),
),
child: ...
use DecoratedBox instead of Container
You can use borderRadius: BorderRadius.circular(x), there, and wrap everything with ClipRRect for Card color. You may have good reason to have Card and I don't know that, but you check Material widget and with it will be simple to archive, like not to handling extra border/override color of by Card.
Result
Widget
class DX extends StatelessWidget {
const DX({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.deepPurple,
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(35), //* you can increase it
child: Card(
color: Colors
.transparent, //* or set the bg Color and remove [ClipRRect]
child: Container(
width: 400,
height: 100,
// margin: EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(width: 0, color: Colors.transparent),
borderRadius: BorderRadius.circular(22),
gradient: LinearGradient(
colors: [
Colors.red,
// cardBorderColor,
Theme.of(context).colorScheme.surface,
],
stops: [0, 0.8],
),
),
child: Center(child: Text("asdasd")),
),
),
),
),
);
}
}
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.
Hy everyone,
I need to know, how can I create gradient on top right of the page like this picture?
I tried with this code, but it's still not working for me:
Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Stack(
children: [
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.center,
stops: [
0.01,
0.3,
0.4,
],
colors: [
Color(0xff2DBA61),
Colors.yellow,
Colors.white,
],
),
),
),
],
),
),
),
here is the result
Thank you. any kind of help will be appreciated!
Just wrap your Scaffold inside a DecoratedBox or a Container and set its backgroundColor property to Colors.transparent.
Code sample
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.center,
stops: [0.01, 0.3, 0.4],
colors: [
Color(0xff2DBA61),
Colors.yellow,
Colors.white,
],
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
leading: const BackButton(color: Colors.black),
),
),
);
}
}
Result
Try the full example on DartPad
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
Flutter uses the two-colored warning Containers when a Renderflex is overflowing. However is it possible to color the border of a Container in that way in my flutter app?
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.yellow .... Colors.black) <--- somehow (?)
),
child: Text('My border')
}
You have to define two Containers. First outer container with a gradient background and the second inner container with white background. and as a child of the inner container, you can place anything e.g. TextField, Text, another button, etc.
Decorations
final kInnerDecoration = BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.white),
);
const kGradientBoxDecoration = BoxDecoration(
gradient: LinearGradient(
begin: Alignment.center,
end: Alignment(-0.2, -0.5),
stops: [0.0, 0.5, 0.5, 1],
colors: [
Colors.orangeAccent,
Colors.orangeAccent,
Colors.black,
Colors.black,
],
tileMode: TileMode.repeated,
),
);
And container
Container(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text("child of the container")),
decoration: kInnerDecoration,
)
Result:
Original answer is from -> Outlined transparent button with gradient border 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.