Chop child view so it doesn't exceed the parent view - dart

I need to rotate a text inside a card. What I would like to obtain is this:
But I don't know how can i do this with flutter. The problem I am facing is that the text view exceeds the card.
Here is what I have so far:
Widget cardDetails(String title, String imgPath) {
return Material(
elevation: 8.0,
borderRadius: BorderRadius.circular(15.0),
child: Container(
height: 135.0,
width: 135.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0), color: Colors.white),
child: Stack(
alignment: Alignment.topLeft,
children: <Widget>[
Transform.rotate(
angle: -pi / 4,
child: Container(
height: 15.0,
width: 55.0,
alignment: Alignment.topCenter,
color: const Color(0xFFFFd77B),
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 12.0,
),
),
),
),
],
),
),
);
}
And here it's how it looks like:
Thanks in advance

The simplest way to make a banner is to use the Banner widget. However, it still paints outside the bounds of the item you're using, and unfortunately is not nearly as configurable as it could be (and doesn't handle things like longer text).
To fix the painting outside the bounds, all you need to do is add a ClipRect right under your card widget, and that should fix the overflow with the Banner widget or for what you're doing with the rotated box.
Depending on how configurable you need the banner to be, you could re-implement the Banner widget - using TextPainter you could figure out the length of the text and resize automatically based on it if need be (and to remove the dropshadow...)

Related

Rendering issue while centering Font Awesome icon

I don't understand why this FAB doesn't center it's child. I've tried different things but cannot make it to center perfectly. Because adding for example padding only bottom to the icon could make it center on a Device but maybe not for all.
this is my code
Theme(
data: Theme.of(context).copyWith(
highlightColor: Colors.red, splashColor: Colors.red),
child: SizedBox(
height: MediaQuery.of(context).size.height / 7,
width: MediaQuery.of(context).size.height / 7,
child: FloatingActionButton(
elevation: 100,
shape: new CircleBorder(
side: new BorderSide(
color: Colors.black, width: 5.0)),
backgroundColor: Colors.orangeAccent,
onPressed: () {},
child: new Icon(
FontAwesomeIcons.chevronUp,
size: 80,
)),
),
),
and this is the not centered FAB with it's icon child.
does it seems only to me that the icon isn't centered?
Same code with Icons.person
same code with Text widget
Same code with chevronCircleUp
I've used Show Debug Paint by the way. And I've used chevronCircleUp, just to see clearly the area of widget. I think you are right, it's not centered enough, however, this examples made me think that the problem is related to FontAwesome icons.
There are also this issues
Font Icon Render Box not large enough for some characters
Rectangular icons are centered incorrectly
So I've applied the workaround on the first issue, here is the code. It must be good enough now.
Theme.of(context)
.copyWith(highlightColor: Colors.red, splashColor: Colors.red),
child: SizedBox(
height: MediaQuery.of(context).size.height / 7,
width: MediaQuery.of(context).size.height / 7,
child: FloatingActionButton(
elevation: 100,
shape: new CircleBorder(
side: new BorderSide(color: Colors.black, width: 5.0)),
backgroundColor: Colors.orangeAccent,
onPressed: () {},
child: Text(
String.fromCharCode(
FontAwesomeIcons.chevronUp.codePoint),
style: TextStyle(
fontSize: 72.0,
fontFamily: FontAwesomeIcons.chevronUp.fontFamily,
package: FontAwesomeIcons.chevronUp.fontPackage)),
)),
),
Edit after 3 years:
Issue still exists with Material icon (Icons.ios_share) on Flutter 2.10.0

Container shadow disappear when the child container background color is filled

I'm trying to get a Material Card with custom shadow (that why I don't use the Card's elevation), It work fine when the color of the child controller is set to white, but the shadow disappear (become much weaker) when the child container is filled with darker color like brown.
This is the code
Container(
padding: EdgeInsets.only(
top: 16.0,
left: 16.0,
right: 16.0,
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.10),
blurRadius: 8.0,
),
],
),
child: Card(
clipBehavior: Clip.antiAlias,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius),
),
child: Container(
/// If this Container is filled then the shadow is gone
color: Colors.brown,
),
),
),
);
I even tried putting a CropRRect over the Card or container, but does not work. Can anyone explain to be why this is the case or anything I can do to keep the shadow the same?
It does not disappear, it's just a visual effect, you can try with:
BoxShadow(
color: Colors.black.withOpacity(0.50),
blurRadius: 18.0,
),
and
color: Colors.brown,

How to make flutter TextField height match parent of container?

I want to make my TextField height the same as my container height. Please check my code below and let me know how can I make TextField match_parent of my container. I've checked this question The equivalent of wrap_content and match_parent in flutter? but I didn't find any solution. I need to make TextField to take full height and width of my container.
new Container(
height: 200.0,
decoration: new BoxDecoration(
border: new Border.all(color: Colors.black)
),
child: new SizedBox.expand(
child: new TextField(
maxLines: 2,
style: new TextStyle(
fontSize: 16.0,
// height: 2.0,
color: Colors.black
),
decoration: const InputDecoration(
hintText: "There is no data",
contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
),
),
)
Please check the screenshot below. As said, I need my TextField to take full height of Container
Here is my solution:
Container(
height: 200,
color: Color(0xffeeeeee),
padding: EdgeInsets.all(10.0),
child: new ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 200.0,
),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: SizedBox(
height: 190.0,
child: new TextField(
maxLines: 100,
decoration: new InputDecoration(
border: InputBorder.none,
hintText: 'Add your text here',
),
),
),
),
),
),
),
It works pretty good for me. And here is a screen shot.
Answering this in 2021. There is an expands property available now. This code works:
Column(
children: [
Expanded(
child: TextField(
maxLines: null,
minLines: null,
expands: true,
),
flex: 1),
],
)
Let's remove a few lines in code and understand how flutter works.
Why we are giving height 200 to Container. Can't the Container adjust the height based on its child (in this case SizedBox.expand)
If we remove height 200, then Container occupied the entire screen because of SizedBox.expand
Do we really need the SizedBox for our use case. Let's remove that also see what happens.
Now our Container wraps the TextField. But there is some space above and below.
Who decided that space? TextField's decoration's contentPadding. Let's remove that also. It looks like below where textField wrapped by Container. Hope this is what you want. If not, please comment, we can tweak a bit and get what you want. Cheers
Final version of code which displays the above image
new Container(
// height: 200.0,
decoration: new BoxDecoration(
border: new Border.all(color: Colors.black)
),
child: new TextField(
maxLines: 2,
style: new TextStyle(
fontSize: 16.0,
// height: 2.0,
color: Colors.black
),
decoration: const InputDecoration(
hintText: "There is no data",
// contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
),
)
Currently the only way to achieve the TextField to fill the available vertical space is:
TextField(maxLines: 1000000) //maxlines: any large int
While it is tempting to use TextField(maxLines: null), it will just set the TextField to expand with its content, until it reaches its container limit.
I think there needs to be a bool stretchVertically parameter. TextField(stretchVertically: true) would mean that the TextField will try to fill as much vertical space as it can. stretchVertically and maxLines would have to be mutually exclusive.

How to get constraints like Height and Width of container in flutter

I'm currently working on a chat app's interface on flutter. I tried to customize the chat message with the following container, to show a vertical line beside each message, like Snapchat does:
child: new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
alignment: Alignment.centerRight,
width: 300.0,
child: new Text(text),
),
new Container(width: 2.0, height: 10.0, color: Colors.amber, child: null)
],
),
)
Problem is, this:
new Container(width: 2.0, height: 10.0, color: Colors.amber, child: null)
When I specify an explicit height, like the 10.0 above, it doesn't scale with the message, it just stays at the top like this:
So I was wondering if there was a way to scale the height for the line(container) dynamically as the other container for the message Text increases in height.
LayoutBuilder is what you want.
The builder delegate receives a BoxConstraint as parameter, corresponding to the container's size.
While the answer by Darky is correct, in your case, you don't need to know the container dimensions. A much simpler way is to just have a border on the right side of your container.
For example:
new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
decoration: new BoxDecoration(
border: new Border(
right: new BorderSide(
width: 2.0,
color: Colors.amber,
),
),
),
child: new Text('Hello World!'),
);

How can I rotate a Container widget in 2D around a specified anchor point?

I'd like to perform a very simple 2D rotation of a Container widget (that contains a handful of other widgets.) This widget would be rotated around a single fixed point in the center, with no deformations.
I tried using the transform property with Matrix4.rotationZ, which somewhat works – but the anchor point is in the top-left corner, not in the center. Is there an easy way to specify that anchor point?
Furthermore, is there an easier way to 2D-rotate this widget that doesn't require Matrix4?
var container = new Container (
child: new Stack (
children: [
new Image.asset ( // background photo
"assets/texture.jpg",
fit: ImageFit.cover,
),
new Center (
child: new Container (
child: new Text (
"Lorem ipsum",
style: new TextStyle(
color: Colors.white,
fontSize: 42.0,
fontWeight: FontWeight.w900
)
),
decoration: new BoxDecoration (
backgroundColor: Colors.black,
),
padding: new EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 16.0),
transform: new Matrix4.rotationZ(0.174533), // rotate -10 deg
),
),
],
),
width: 400.0,
height: 200.0,
);
You can use RotatedBox Widget to rotate any widget:
RotatedBox(
quarterTurns: 3,
child: Container(
color:Colors.red
),
),
Per Ian's advice, I gave the following a try. It appears to work, at least in my limited testing.
The container is nested within a Transform widget. Using alignment allows one to adjust the transform-origin in relative terms, i.e., in the center, the top left, etc.
var container = new Container (
child: new Stack (
children: [
new Image.asset ( // background photo
"assets/texture.jpg",
fit: ImageFit.cover,
),
new Center (
child: new Transform (
child: new Container (
child: new Text (
"Lorem ipsum",
style: new TextStyle(
color: Colors.white,
fontSize: 42.0,
fontWeight: FontWeight.w900,
)
),
decoration: new BoxDecoration (
backgroundColor: Colors.black,
),
padding: new EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 16.0),
),
alignment: FractionalOffset.center, // set transform origin
transform: new Matrix4.rotationZ(0.174533), // rotate -10 deg
),
),
],
),
width: 400.0,
height: 200.0,
);
In flutter 2.2
Use Transform:
Transform(
transform: Matrix4.rotationZ(...),
alignment: FractionalOffset.center,
child: Container(...)
Or set transformAlignment value in Container:
Container(
...
transform: Matrix4.rotationZ(...),
transformAlignment: Alignment.center,
)
Apply a translation (to and from the fulcrum) before and after the rotation.
You can create yourself a little widget that does this, and thus solve your other problem at the same time (hiding the Matrix4).
For those who want to make an app like me, just using Transform and Gesturedetector. And remember don't use Draggable and Gesturedetector together because you only can drag and drop but you can't zooming widget :)).
Refer:
A Deep Dive Into Transform Widgets in Flutter
barbswatanabe
:
Transform.rotate(
alignment: FractionalOffset.center,
angle: state.listStickerModel[index].angle,
child: Transform(
alignment: FractionalOffset.center,
transform: new Matrix4.diagonal3(vector.Vector3(
state.listStickerModel[index].zoom,
state.listStickerModel[index].zoom,
state.listStickerModel[index].zoom)),
child: GestureDetector(
onScaleStart: (detail) {
_editPhotoBloc.add(UpdateSticker(
index: index,
offset: detail.focalPoint,
previousZoom: state.listStickerModel[index].zoom,
));
},
onScaleUpdate: (detail) {
_editPhotoBloc.add(UpdateSticker(
index: index,
offset: Offset(detail.localFocalPoint.dx,
detail.focalPoint.dy),
angle: detail.rotation,
zoom:
state.listStickerModel[index].previousZoom *
detail.scale));
},
child: Container(
alignment: Alignment.center,
child: SvgPicture.asset(
state.listStickerModel[index].src),
),
),
),
),

Resources