Clipping a row child in flutter - flutter

I want to achieve this
This is my code
Row(
children: [
Expanded(
flex: 1,
child: Text(
"somethinig here..."),
),
Expanded(
child: ClipRect(
child: Wrap(
children: [
SvgPicture.asset(
"assets/3958830.svg",
width: autoHeight(550),
allowDrawingOutsideViewBox: true,
fit: BoxFit.fitHeight,
),
],
),
),
),
],
),
Result:
You can see how the image is clipped, I just want to clip all sides except the left side.

You can wrap the image widget with an Align widget to easily position the image inside the clipper. The widthFactor and heightFactor properties are used to decide the size of the clipper and alignment is used to decide the position of the `clipper
A Nice Example to use the Align Widget with ClipRect will be
ClipRect(
child: Container(
child: Align(
alignment: Alignment.centerLeft,
widthFactor: 0.6,
heightFactor: 1.0,
child: Image.network(
'https://images.unsplash.com/photo-1473992243898-fa7525e652a5'
),
),
),
);
To Know More about the Clippers see This Article

Just wrap your Text widget with Center.
And SvgPicture with Align. (I realize this later.)
Row(
children: [
Expanded(
flex: 1,
child: Center(child: Text("somethinig here...")),
),
Expanded(
child: ClipRect(
child: Wrap(
children: [
Align(
alignment: Alignment.centerRight,
child: SvgPicture.asset(
"assets/3958830.svg",
width: autoHeight(550),
allowDrawingOutsideViewBox: true,
fit: BoxFit.fitHeight,
)),
],
),
),
),
],
)

Related

Stack() Widget not centering all sub widgets flutter

I have a Text() widget I am trying to stack on a CircularProgressIndicator()
I thought it would be as simple as just wrapping them both in a Stack() widget but the text is not centered.
I tried wrapping the Text() in a Center() widget but that did not solve the issue:
return Expanded(
child: PageView(
controller: pageViewController,
children: [
PackSummaryWeightGraph(
categoryWeightList: categoryWeightList,
totalWeight: totalWeight),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Stack(
children: [
Text((packedItemsPercent * 100)
.toString()),
SizedBox(
height: 150,
width: 150,
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
],
),
),
],
),
const Center(
child: Text('Third Page'),
),
],
),
);
Bonus points if there is a way to have the CircularProgressIndicator() fill the space without hard coding its width and height...
Stack has an alignment argument:
Stack(
alignment: Alignment.center,
children: [...],
),
If you want to fill the given space use the SizedBox.expand constructor:
SizedBox.expand(
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
One issue with the above is that if the available space has a different height than width you will end up with an oval shaped indicator rather than a circle. You can avoid this by wrapping it in an AspectRatio widget:
AspectRatio(
aspectRatio: 1,
child: SizedBox.expand(
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
),
See complete demo:
import 'package:flutter/material.dart';
void main() {
double packedItemsPercent = .67;
runApp(
MaterialApp(
home: Scaffold(
body: Stack(
alignment: Alignment.center,
children: [
Text((packedItemsPercent * 100).toString()),
AspectRatio(
aspectRatio: 1,
child: SizedBox.expand(
child: CircularProgressIndicator(
value: packedItemsPercent,
),
),
),
],
),
),
),
);
}
Make sure that any widget like Expanded or SizedBox.expand is not inside of an infinite sized container like a ListView or similar. Expanded means to take up the maximum available space, but that isn't possible if you have an infinite amount of space.
You'll need to set the alignment of the Stack to center:
Stack(
alignment: Alignment.center,
children: [
// ...
],
);
To get the circular progress indicator to fill the space, you should be able to use a FittedBox with a Positioned.fill widget:
Stack(
children: [
Positioned.fill(
child: FittedBox(
fit: BoxFit.fill,
child: CircularProgressIndicator(
value: packedItemsPercent
),
),
),
],
);

how can i set the size of the child inside the row?

I want to make children use flexible sizes
how can i set the size of the child inside the row? can you guys help me? and find the error constraint
anyone help me
return SafeArea(
child: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
color: Colors.lightBlue,
child: Row(
children: [
Expanded(
flex: 5,
child: Container(
color: Colors.green,
),
),
Expanded(
flex: 5,
child: Container(
color: Colors.blue,
),
)
],
),
)
],
),
)
],
),
);
To place children in a row you can use Flexible widget. The value of flex defines how much space each child should take. In the example that you provided.. Both children will be equally spaced since you gave flex value 5 for both.
return Scaffold(
body: Center(
child: SizedBox(
height: 50,
child: Row(
children: [
Flexible(
flex: 5,
child: Container(
color: Colors.red,
)),
Flexible(
flex: 5,
child: Container(
color: Colors.green,
)),
],
),
),
),
);
If you change the flex value to 1 and 5.. Now the total divisions will be 6 and out of that the first child will take 1 part and the second child will take 5 parts like below
return Scaffold(
body: Center(
child: SizedBox(
height: 50,
child: Row(
children: [
Flexible(
flex: 1,
child: Container(
color: Colors.red,
)),
Flexible(
flex: 5,
child: Container(
color: Colors.green,
)),
],
),
),
),
);
Also if you use a singleChildScrollView and an expanded inside that it then the expanded widget has no bounds so it will throw an error. So wrapping the Expanded with a SizedBox with a specific width will give you expected results.
EDIT
To have a SingleChildScrollView with dynamic content in the row you can do this
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize : MainAxisSize.min,
children:[
SizedBox(
width: 100,//this is important since its a row and the row will take full width and throw an error.
child: Image.asset(""),
),
//Another SizedBox or Text or any widget..
]
)
)

Expanding a widget horizontally inside column

I'm facing some problem by composing layout of my App.
My widget at the end sould look like this
This is my code
Row(
mainAxisSize: MainAxisSize.max,
children: [
Column(
children: [
// Widget A
SizedBox(
height: widget.screenHeight * 0.9,
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
color: Colors.red,
),
),
),
// Widget B
Container(
height: widget.screenHeight * 0.1,
color: Colors.green,
)
],
),
// Widget C
Expanded(
child: Container(
color: Colors.pink,
),
)
],
)
I want Widget A to occupy 90% of screen height and mantain a 16/9 aspect ratio, Widget B to occupy remaining 10% height and have the same width of his sibling, and Widget C to fill remaining space
With that code, Widget A and Widget C are showed correctly, but widget B doesn't fill his space as i expect.
What's wrong?
Column(
children: [
Expanded(
child: Row(
children: [
Expanded(
flex: 2,
child: Column(
children: [
Expanded(
flex:4,
child: Container(
color: Colors.yellow,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.blue,
),
)
],
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.green,
),
),
],
),
)
],
),
you have to play with the expanded widget

Flutter align widget horizontaly and verticaly

I am working on a Flutter project. I'm trying to create a widget like the image below and I can't manage to do it.
So what I'm trying to do, is to create a widget with a Text at the top left (the size of this widget is not constant and depends on the text in it).
I'm trying to align 2 other widgets with the Text:
The Widget 1 is aligned horizontaly and centered with the Text widget and at its right with no space between
The Widget 2's right edge is aligned verticaly with the Text widget's right edge, and is positioned under it (and there is no space between the 2 widgets).
I tried to implement this with Column and Row widgets or with a GridView but I couldn't manage to do so.
Also the overall size of this custom widget has to be shrinked.
Does someone know how to do something like that ?
Thank you.
This works
Container(
width: double.infinity,
height: 300,
color: Colors.grey[200],
child: Column(
children: <Widget>[
Row(
children: [
Flexible(
flex: 2,
child: Container(
height: 200,
color: Colors.blue,
),
),
Flexible(
flex: 1,
child: Container(
height: 100,
color: Colors.green,
),
),
],
),
Row(
children: <Widget>[
Flexible(
flex: 2,
child: Align(
alignment: Alignment.centerRight,
child: Container(
width: 150,
height: 100,
color: Colors.orange,
),
),
),
Flexible(
flex: 1,
child: Container(),
),
],
),
],
),
),

Expand widgets inside the Stack widget

I have a stack widgets with two widgets inside.
One of them draws the background, the other one draws on top of that.
I want both widgets to have the same size.
I want the top widget, which is a column, to expand and fill the stack vertically to the size that is set by the background widget.
I tried setting the MainAxis mainAxisSize: MainAxisSize.max but it didn't work.
How can I make it work?
Use Positioned.fill
Stack(
children: [
Positioned.fill(
child: Column(
children: [
//...
],
),
),
//...
],
);
More info about Positioned in Flutter Widget of the Week
How does it work?
This is all about constraints. Constraints are min/max width/height values that are passed from the parent to its children. In the case of Stack. The constraints it passes to its children state that they can size themselves as small as they want, which in the case of some widgets means they will be their "natural" size. After being sized, Stack will place its children in the top left corner.
Positioned.fill gets the same constraints from Stack but passes different constraints to its child, stating the it (the child) must be of exact size (which meant to fill the Stack).
Positioned.fill() is the same as:
Positioned(
top: 0,
right: 0,
left: 0,
bottom:0,
child: //...
)
For even more examples and info: How to fill a Stack widget and why? and Understanding constraints.
You can try wrapping the Column with a positioned widget. Set top to 0 and bottom to 0. This will make the column fill the stack vertically.
sample code:
Stack(
children: <Widget>[
// Background widget rep
Container(
color: Colors.pink,
),
Positioned(
top: 0,
bottom: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('madonna'),
Text('flutter'),
],
),
)
],
)
I think you could wrap you column in a container like this:
Container(
height: double.infinity,
width: double.infinity,
child: Column()
),
The accepted answer did not answer my issue completely. So, I put my code here in case you have a similar issue.
class NoContentView extends StatelessWidget {
const NoContentView({Key? key, required this.message}) : super(key: key);
final String message;
#override
Widget build(BuildContext context) {
return Expanded(
child: Stack(
children: [
Positioned.fill(
child: FittedBox(
child: const Image(image: AssetImage(AppImages.noReceiptsWeb), fit: BoxFit.fitWidth),
),
),
MessageView(message: message),
],
),
);
}
}
In my case, I thought that I needed to expand the container in the light blue color with an expanded widget inside the stack widget.
Problems arose, especially since I was adding the stack widget in the column widget, and the way to make the container double.infinity dimensions I definitely had a problem with the vertical axis.
In the end, I managed to show it like this photo...
Column(
children: [
//filter
Container(
color: orange,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Text(
'All',
style: getRegular(color: white.withOpacity(.6)),
),
),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 10, 0),
child: Text(
'Ready',
style: getRegular(color: white.withOpacity(.6)),
),
),
freeh(),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
],
),
Row(
children: [
Icon(
filter,
color: white.withOpacity(.7),
size: 20,
),
Text(
'FILTER',
style: getLight(
color: white.withOpacity(.7),
),
),
freeh(),
],
),
],
),
),
Expanded(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
color: lightBlue, //here to use map>>>>
),
Container(
height: 35,
width: 120,
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
FontAwesomeIcons.listUl,
color: white.withOpacity(.8),
size: 20,
),
Text(
'List View',
style: getRegular(color: white.withOpacity(.8)),
)
],
),
),
],
),
)
],
),