I am learning Flutter development. I want to display some rounded square shaped containers with short text in a row. However, the possible shapes are either a circle or rectangle. So I decided to set the width and height of the rectangle so that they would be equal.
The following is the code I used to create the Container
Container(
width: double.maxFinite,
height:
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: ThemeProvider.themeOf(context).data.primaryColor,
borderRadius: BorderRadius.circular(10),
),
child: Text(keyText),
),
When I set the shape in Box decoration alone, the Container resized to the size of the text. When I set the width property of the Container, I was able to divide the available width of the screen among the containers, which ensures flexibility of size if the screen was smaller or bigger, instead of hard coding it. Now I want to make the height the exact same size that the width turns out to be, thus obtaining a square container. Any idea how I could do that?
EDIT: I tried the following code and this is how the containers are looking like in both cases:
Container(
alignment: Alignment.center,
width: double.maxFinite,
height: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: ThemeProvider.themeOf(context).data.primaryColor,
borderRadius: BorderRadius.circular(10),
),
Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: ThemeProvider.themeOf(context).data.primaryColor,
borderRadius: BorderRadius.circular(10),
),
After using MediaQuery.of(context).size.width for height property or both
Here is a solution without using MediaQuery:
AspectRatio(
aspectRatio: 1,
child: Container(
width: double.infinity,
child: Text(),
),
)
Use MediaQuery. MediaQuery.of(context).size.width gives you the Screen width size value.
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: ThemeProvider.themeOf(context).data.primaryColor,
borderRadius: BorderRadius.circular(10),
),
child: Text(keyText),
)
check this quick example that I made just for you!
// This function is just an example
List<Widget> buildContainers(BuildContext context, int containerCount) {
// Here you get the width of all your containers
final containerWidth = MediaQuery.of(context).size.width / containerCount;
// Make height = width for squares!
final containerHeight = containerWidth;
// We will gather all containers in this list
List containerList = <Container>[];
for (var i = 0; i < containerCount; i++) {
containerList.add(
Container(
// Use the predefined width and height here!
width: containerWidth,
height: containerHeight,
// Random color to differentiate each container
// You could replace this with your child widget
color: Color(
Random().nextInt(0xFFFFFFFF),
),
),
);
}
return containerList;
}
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
// If you are wondering what are these dots (...)
// they are called "spread operators" and you can find more about them here:
// https://dart.dev/guides/language/language-tour#spread-operator
...buildContainers(context, 7),
],
),
);
}
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: ThemeProvider.themeOf(context).data.primaryColor,
borderRadius: BorderRadius.circular(10),
),
child: Text(keyText),
),
Related
I want to absolutely position a text on a container.
return Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: Color(0xE5E5EAee), borderRadius: BorderRadius.circular(20)),
child: Text('Camping'),
);
This is the present image
This is what need to be acheived
Did tried to position it with the 'align positioned' dependency. But got stuck with the same result.
using your own example considering there is only one child in the container u can do the following but if u do have additional childrens the best way would be to use a Stack widget and use Align/Positioned widget to position the child widgets as per ur needs
Container(
height: 150,
width: 150,
padding: EdgeInsets.only(bottom: 10), // how much space from the bottom
alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
color: Color(0xE5E5EAee),
borderRadius: BorderRadius.circular(20)),
child: Text('Camping'),
)
You can try this, use a Stack and positioned the Text with the widget Positioned as you need it, Positioned has 4 properties for position top, rigth, bottom and left for you to positioned the widget wherever you want.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: Color(0xE5E5EAee), borderRadius: BorderRadius.circular(20)),
child: Stack(
children: [
Positioned(
top: 120,
left: 48,
child: Text('Camping'))
,
],
),
);
;
}
}
Wrap the Text widget with Align widget and give alignment as the below code
Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: Color(0xE5E5EAee), borderRadius:
BorderRadius.circular(20)),
child: Align(
alignment: Alignment.bottomCenter, // ADD THIS
child: Text('Camping')),
),
Then give padding as per your need
I want to add background that has circle like picture below:
And in my Figma, has asset like this:
And my code is like this:
Widget buildArea(int index) => Card(
color: ColorName.brandSecondaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
child: Container(
padding: const EdgeInsets.only(top: 20, bottom: 20),
child: buildAreaItem(),
),
);
Anyone else who know how to add it?
May not be a clean way but try Using a Stack widget and use Positioned widget inside.
Here's a sample for what you are trying to achieve.
Scaffold(
body: Center(
child: Stack(
children: [
Container(
width: 300,
height: 150,
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.circular(20)
),
),
Positioned(
left: -50,
top: -35,
child: Stack(
alignment: AlignmentDirectional.center,
children:
[
Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100)
),),
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.circular(100)
),),
]
))
],
),
)
)
Try This Code:
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'dart:ui';
import 'package:google_fonts/google_fonts.dart';
import 'package:myapp/utils.dart';
class circlescreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
double baseWidth = 428;
double fem = MediaQuery.of(context).size.width / baseWidth;
double ffem = fem * 0.97;
return Container(
width: double.infinity,
child: Container(
// iphone13promax1auq (1:2)
width: double.infinity,
decoration: BoxDecoration (
color: Color(0xff3241a0),
borderRadius: BorderRadius.circular(20*fem),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
// ellipse1hmV (1:4)
margin: EdgeInsets.fromLTRB(0*fem, 0*fem, 237*fem, 272*fem),
width: 318*fem,
height: 318*fem,
decoration: BoxDecoration (
borderRadius: BorderRadius.circular(159*fem),
border: Border.all(color: Color(0xff3c4baf)),
),
),
Container(
// ellipse3jCP (1:6)
margin: EdgeInsets.fromLTRB(0*fem, 0*fem, 0*fem, 113*fem),
width: 198*fem,
height: 198*fem,
decoration: BoxDecoration (
borderRadius: BorderRadius.circular(99*fem),
border: Border.all(color: Color(0xff3c4baf)),
),
),
Container(
// ellipse2oi3 (1:5)
margin: EdgeInsets.fromLTRB(0*fem, 0*fem, 205*fem, 0*fem),
width: 318*fem,
height: 318*fem,
decoration: BoxDecoration (
borderRadius: BorderRadius.circular(159*fem),
border: Border.all(color: Color(0xff3c4baf)),
),
),
],
),
),
);
}
}
export your figma component with the just the background( purple with circles).
Then add that in assets and use it in the child of Card. So your widget tree would be :
Card
=>
Container( //with background decoration as image and necessary padding if any
)
=>
buildAreaItem()
You can also crop the image to get just the top corner ring or play with the fit property in DecorationImage widget.
I wonder how to manage to do this kind of widgets.
I couldn't figure out how to describe and google it.
in this image how to positioned filter and sorting widgets floats on blue world image and background and aligned for perfect i mean responsive
or in this image expand arrow positioned on the edge of column
You can use MediaQuery to get the screen size and use Positioned inside the Stack to adjust the location of the buttons, here's an example i just made:
double screenHeight = MediaQuery.of(context).size.height;
double topContainerHeight = screenHeight / 3;
double buttonLocation = topContainerHeight - 40;
return Stack(
alignment: Alignment.topCenter,
children: [
Container(
color: Colors.red,
),
Container(
height: topContainerHeight,
decoration: const BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0),
),
),
),
Positioned(
top: buttonLocation,
child: Row(
children: [
Container(
height: 80,
width: 160,
color: Colors.white,
),
const SizedBox(width: 30.0),
Container(
height: 80,
width: 160,
color: Colors.white,
),
],
),
),
],
);
The black container in the top uses 1/3 of the screen height and i know my buttons have an height of 80 so i just remove half of the height of my buttons from 1/3 of the screen to position them in the stack.
Here's how it looks:
I want a colour for container but getting error while using colour.
My code:
Container(
color:Colors.red,
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50)
)
),
You can't use "color" and "decoration" at the same time. You need to pass the "color" parameter to the "BoxDecoration" widget like this:
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color:Colors.red,
borderRadius: BorderRadius.circular(50)
)
),
You cannot add color to the container if you add decorations. The solution is to enter color into the decoration box as follows
Container(
width: 50,
height: 50,
decoration: BoxDecoration(color: Color.red)
)
Please use color in BoxDecoration like this
Container( width: 50, height: 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50),color:Colors.red,)),
You can't give both colors and decoration to Container(). If you are looking to give color and decoration to Container, give color inside Boxdecoration
Container(
width: 50,
height: 50,
decoration: BoxDecoration(color: Color.red)
)
Use color inside container directly to set the background for the children. If you use any decoration then it will conflict with outside color. In those case you need to give color inside decoration.
FullCode : here
Column(
children: [
Container(
padding: EdgeInsets.all(10),
color: Colors.green,
child: Text('test'),
),
SizedBox(height: 10),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(10),
),
child: Text('test'),
)
],
)
Output for the above code is
The container does not accept the color parameter when there is a decoration parameter. This happens because the BoxDecoration has a color parameter. Just put the color inside the BoxDecoration and remove the color parameter from the Container and your problem will be solved.
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.red
)
),
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.