I'm trying to show the title but as you can see, it does not do it correctly.
I tried to put softWrap to true but it is still the same.
The code is from flutter contacts_demo gallery
flexibleSpace: FlexibleSpaceBar(
title: const Text('Fantastic Beasts And Where To Find Them'),
background: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(
'people/ali_landscape.png',
package: 'flutter_gallery_assets',
fit: BoxFit.cover,
height: _appBarHeight,
),
// This gradient ensures that the toolbar icons are distinct
// against the background image.
const DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment(0.0, -1.0),
end: Alignment(0.0, -0.4),
colors: <Color>[Color(0x60000000), Color(0x00000000)],
),
),
),
],
),
),
You can use a ConstrainedBox along with MediaQuery.of(context).size.width
final mediaQuery = MediaQuery.of(context);
final availableWidth = mediaQuery.size.width - 160;
along with
title: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: availableWidth,
),
child: const Text('Fantastic Beasts And Where To Find Them'),
),
I dug into a FlexibleSpaceBar sources and at least now I understand what happens. Turns out that in an expanded state title is scaled up to be 1.5 of its size, so naturally it will overflow offscreen. As user scrolls up, title is scaled down towards its source size of 1.0. At this size it will sit in the top toolbar.
Maybe this information will help someone to base their workarounds on until this is fixed.
I wondered why my hack of wrapping title in ConstraintedBox with maxWidth: MediaQuery.of(context).size.width didn't work. Now I know: I must divide this maxWidth by 1.5.
See also this bug on the Flutter github issue tracker.
The title length in combination with the font size you've set have no way to be displayed on a single line on smaller devices, for obvious reasons.
You may want to play with MediaQuery.of(context).size.width to get the device width and set the header text fontSize accordingly as a fraction of that. Try in the emulator to see which works best for your text length.
const Text(
'Fantastic Beasts And Where To Find Them',
style: TextStyle(fontSize: MediaQuery.of(context).size.width/ SOME_NUMBER),
),
Or just hardcode some font sizes based on some width intervals:
int _getFontSize(BuildContext context) {
int width = MediaQuery.of(context).size.width;
if (width < 300) {
return 10;
} else if (width < 600) {
return 13;
// etc ...
} else {
return 18;
}
}
...
const Text(
'Fantastic Beasts And Where To Find Them',
style: _getFontSize(context),
),
Thanks to dimsuz's answer it is possible to eliminate the upscaling of text in a FlexibleSpaceBar:
SliverAppBar(
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {},
),
],
floating: true,
pinned: false,
snap: false,
flexibleSpace: FlexibleSpaceBar(
title: Text(title, style: TextStyle(fontSize: 20.0 / 1.5)),
centerTitle: false,
background: Container(
color: Theme.of(context).primaryColor,
),
),
expandedHeight: 120,
),
The 20.0 in fontSize I took from here.
Related
I am making my app in which I want the font to look like its going out of the screen or has been cut off. I am unable to find anything in flutter related to it. If anyone knows about it please check the picture and let me know if its possible then how can I make it.
try this:
return Scaffold(
body: Transform.scale(
scaleX: 1.3,
child: Container(
color: Colors.blueGrey,
transform: Matrix4.translationValues(
7.0, 50.0, 0.0),
child: Text('Groupp',
style: TextStyle(fontSize: 100),
),
),
),
);
I am trying to get a text label with graphics over the image. Labels like new arrival, best seller, limited, on sale just like on the pic attached.
enter image description here
Here's what i think the skeletal layout would be :
return Stack(
children: [
Card(
color: Colors.black54,
child: Image.asset('assets/xyz.png'),
),
Align(
//for bottomRight
alignment: Alignment.bottomRight,
child: Image.asset(
'assets/fireimg.png',
), //can be an SVG converted to png
),
Align(
//for topLeft
alignment: Alignment.topLeft,
child: Image.asset(
'assets/label.png',
), //can be an SVG converted to png
),
],
);
Feel free to give the Padding of your choice.
it has so much code to write , so i will give some examples to achieve that output
in this image ,i mentioned 0 and one .
for all 1
solution 1
you can use image like this way
Stack(
children: [
Container(
width: 200,
height: 200,
color: Colors.amber,// added only for view this example
child:Image() // add Product image here
),
Positioned(
top: 20, //change according to your use case position
left: 0,// change according to your use case position
child: Container(
color: Colors.black, // added only for view this example
decoration: BoxDecoration(image: ),// add label image here
width: 100,
height: 50,
child: Row(
children: [Text('hi')],
),
))
],
)
solution 2
you can use custom paint for label layout
not that
in both solution you have to use stack and position widgets , you can control position according to your use case
for all 0
you can use RotationTransition widgets to achieve this
not that
you have to use stack and position widgets , you can control position according to your use case
for the vertical Text
use this example
String exText = "meta";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('hi'),
),
body: Container(
width: 200,
height: 200,
color: Colors.amber,
child: Column(
children: exText.characters
.map((e) => Container(
child: Text('$e'),
))
.toList()),
),
out put will be
I came across a problem with my fonts. Somehow the SizedBox I used which contains some Text doesn't align properly on the left in the Android Emulator like it does on the IOS simulator. It looks like this. In addition, the fontsizes don't match either.
Any Ideas how to fix this?
body: SingleChildScrollView(
child: CustomScrollView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
slivers: [
SliverAppBar(
backgroundColor: Colors.blue,
expandedHeight: 80,
flexibleSpace: FlexibleSpaceBar(
title: FittedBox(
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: const Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Align(
alignment: Alignment.centerLeft,
child: Text("Browse through the individual categories.", style: TextStyle(fontSize: 32, color: Colors.black, fontWeight: FontWeight.w900)),
),
),
)
)
),
),
buildCategories(),
],
),
),
Thanks in advance! :)
I added the centerTitle: true property to the FlexibleSpaceBar and now it looks consistent on both Android and iOS.
Was facing the same issue and upon looking at the FlexibleSpaceBar code, this is because of the default titlePadding being applied based on the centerTitle which is then based on the TargetPlatform (in this case whether iOS or Android) if you did not specify any centerTitle value. Below is the FlexibleSpaceBar code which does the application of titlePadding based on platform:
bool _getEffectiveCenterTitle(ThemeData theme) {
if (widget.centerTitle != null) return widget.centerTitle!;
assert(theme.platform != null);
switch (theme.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
return false;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return true;
}
}
final bool effectiveCenterTitle = _getEffectiveCenterTitle(theme);
final EdgeInsetsGeometry padding = widget.titlePadding ??
EdgeInsetsDirectional.only(
start: effectiveCenterTitle ? 0.0 : 72.0,
bottom: 16.0,
);
And so, the answer is it's either you set a titlePadding or set centerTitle to true.
I am using SfRadialGauge plugin its working fine but there I am facing 2 issues.
Its showing lot of space on top, if I give height to container the sizes of SfRadialGauge is reducing also the top space I don't want to reduce size I just want to remove the space
Same space in GaugeAnnotation. I have column inside GaugeAnnotation and need to show little on top.
My code
Widget getSemiCircleProgressStyle() {
return Padding(
padding: const EdgeInsets.all(0.0),
child: Container(
child: SfRadialGauge(axes: <RadialAxis>[
RadialAxis(
showLabels: false,
showTicks: false,
startAngle: 180,
canScaleToFit: true,
endAngle: 0,
radiusFactor: 0.8,
axisLineStyle: AxisLineStyle(
thickness: 0.1,
color: const Color.fromARGB(30, 0, 169, 181),
thicknessUnit: GaugeSizeUnit.factor,
cornerStyle: CornerStyle.startCurve,
),
pointers: <GaugePointer>[
RangePointer(
value: 100,
width: 0.1,
sizeUnit: GaugeSizeUnit.factor,
enableAnimation: true,
animationDuration: 100,
animationType: AnimationType.linear,
cornerStyle: CornerStyle.bothCurve)
],
annotations: <GaugeAnnotation>[
GaugeAnnotation(
positionFactor: 0,
widget: Container(
child: Stack(
alignment: Alignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(0.0),
child: RatingBarIndicator(
rating: 0.2,
itemBuilder: (context, index) => Icon(
Icons.star,
color: Color(0xffF4D03F),
),
itemCount: 1,
itemSize: 45.0,
direction: Axis.vertical,
),
),
RichText(
text: new TextSpan(
// Note: Styles for TextSpans must be explicitly defined.
// Child text spans will inherit styles from parent
style: new TextStyle(
fontSize: 14.0,
color: Colors.black,
),
children: <TextSpan>[
new TextSpan(
text: '2',
style: new TextStyle(
fontSize: 40, fontFamily: 'UbuntuRegular')),
new TextSpan(
text: ' /5',
style: TextStyle(
fontSize: 25,
color: Colors.grey[400],
fontFamily: 'UbuntuRegular')),
],
),
),
Text(
'FIFTEEN DAYS SCORE',
style: TextStyle(
color: Colors.grey[400], fontFamily: 'UbuntuMedium'),
)
],
)
],
),
))
]),
])),
);
}
This is how its look like
I have marked the space with red pen. IF any one can help to reduce these spacing I am stuck on this from a day :(
Been having the same problem too.
I found that the solution is to set :
canScaleToFit: false
But, this only works if you use the default circular gauge. For the semi-circular gauge, it will still left some blank spaces at the bottom.
I had the same problem, I guess I'm late but hopefully this can be useful to others.
Premises
Note. At the moment I can't find a way to have FULL control of this widget's white space. I only have found the following workaround to get rid of the white space above and under the gauge.
The library's devs mentioned two things:
"... For better understanding, say if the container has different width and height (say 300x800), we will always take the lowest dimension (here it is the width) to render the radial gauge ..."
"... We are sorry that we cannot provide any workaround to trim ..."
"... as this is the default rendering behaviour of the Radial gauge, we cannot consider your suggestion as a feature request."
The first statement is really useful, as it enables a workaround (see below).
The second statement.. I disagree, that's not something "impossible" to work around with.
The third statement... well that's just depressing.
Workaround
Thanks to the Flutter DevTools, I noted that the Gauge renders a NeedlePointer Widget, which is the one rendering the cursed white space. As the devs mentioned, the gauge takes as much space as it can in the smallest direction.
This means that as long as you restrict height and width, you should be fine. I don't know in which context your Gauge is, but in mine the following code works great.
return LayoutBuilder(
(context, constraints) => Container(
padding: const EdgeInsets.all(0),
height: constraints.maxWidth / 1.5, // WORKAROUND
child: Column(
children: [
Flexible(
child: SfRadialGauge(...),
),
MaybeSomeLabelsWidgets(),
SomeOtherWidgets(),
],
),
),
);
So, the fundamental part here is the fact that height is restricted and that there's a Flexible Widget that lets the Gauge take minimum space. LayoutBuilder in my case/context is useful just because I wanted to render the plot with a "3x2" feeling.
As a last note, keep the canScaleToFit=true, so that your plot is centered (why is it called canScaleToFit? That's another mistery I guess...).
Let me know if this helps.
A simple workaround is to use the ClipRect widget. The following will discard the top 20% of the SfRadialGuage.
ClipRect(
child: Align(
alignment: Alignment.bottomCenter,
heightFactor: 0.8,
child: SfRadialGauge(...)
)
)
I need to create a vertical line between two widgets like this: https://imgur.com/a/22ybF6o
I could do it but for a fixed size. If this size changes, layout got messy like this: https://imgur.com/a/kO9NXlJ
Here's my code:
Widget listItem(TripsData item) {
var startDate = DateFormat('dd/MM/yy - HH:mm').format(DateTime.parse(item.start));
var endDate = DateFormat('dd/MM/yy - HH:mm').format(DateTime.parse(item.end));
return Card(
child: Stack(
children: <Widget>[
drawDestinationLine(Colors.red),
Column(
children: <Widget>[
ListTile(
leading: drawDestinationCircle('A', Colors.blue),
title: Text(startDate),
subtitle: Text(item.locationStart),
),
const Padding(padding: EdgeInsets.only(bottom: 2.0)),
ListTile(
leading: drawDestinationCircle('B', Colors.blue),
title: Text(endDate),
subtitle: Text(item.locationEnd),
),
],
),
],
),
);
}
Does someone have a solution to help me with this?
Let me know if need more code, but StackOverflow didn't let me put more code here..
I used the package timelines 0.1.0 which makes this easily possible
Check on pub.dev and the corresponding Github repo for nice examples.
One of the sample use-cases looks like what you are looking for:
In this case you should use the Stack, Positioned, and ConstrainedBox widgets to create the desired arrangement.
Something like this pseudocode, you will need to supply correct coordinates:
Stack ( children: [
Positioned ( left: 0.0 , top : 0.0 , child:
ListTile (leading: drawDestinationCircle('A', Colors.blue),
title: Text(startDate),
subtitle: Text(item.locationStart),
)),
Positioned ( left: 0.0 , bottom : 0.0 , child:
ListTile (leading: drawDestinationCircle('B', Colors.blue),
title: Text(endDate),
subtitle: Text(item.locationEnd),
)),
Positioned ( left 20.0 , top : 20.0
, child: ConstrainedBox(
constraints: new BoxConstraints(
minHeight: 5.0,
minWidth: 5.0,
maxHeight: 30.0,
maxWidth: 5.0,
),
child: new DecoratedBox(
decoration: new BoxDecoration(color: Colors.red),
)
),
)
]);