Disable Flutter text Baseline - flutter

How can I disable the textbaseline?
because my text is not centered
I try to center a text in a contair. I use this font: https://www.dafont.com/young.font?l[]=10&l[]=1
import 'package:flutte_template/styles/theme_dimens.dart';
import 'package:flutter/material.dart';
class RoundedChip extends StatelessWidget {
final Widget child;
final Color color;
const RoundedChip({#required this.child, #required this.color});
#override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: ThemeDimens.padding4),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: ThemeDimens.padding4),
child: Text('Drama', style: ThemeTextStyles.mediaDetailGenreText),
),
],
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(999),
),
color: color,
),
);
}
}
static const TextStyle mediaDetailGenreText = TextStyle(color: ThemeColors.textColor, fontSize: 15, fontWeight: FontWeight.w500);

I hope it helps after this long time :)
wrap the text widget with baseline widget
Baseline(
baselineType: TextBaseline.alphabetic,
child: Text(
'Some Text',
textAlign: TextAlign.center,
),
baseline: 40.0,
),

Just add an inputDecoration with no input border to the textField like this:
TextField(
decoration: InputDecoration(border: InputBorder.none),
)

Try TextDecoration.none, its work for me.
ex: Text("Hello", style: TextStyle(fontSize: 12, decoration: TextDecoration.none),)

I think the issue is on the line height of the Font...
You can tweak that value directly, is in percentage terms of the font size.
So, try the values by eye:
lets say:
Text( "Drama", height: 0.8 );

Related

How to set container width conditionally in flutter?

I have a component having a container with no width initially. What I want is when I specify the full-width property to true, it takes double.infinity as the width otherwise it takes no width at all. This is my component:
import 'package:flutter/material.dart';
class InfoColumn extends StatelessWidget {
const InfoColumn({
Key? key,
required this.heading,
required this.text,
this.fullWidth = false,
}) : super(key: key);
final String heading;
final String text;
final bool fullWidth;
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
heading,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 10,
),
Container(
// TODO: SET WIDTH HERE
// width: fullWidth ? double.infinity : ,
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 12,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Text(
text,
style: const TextStyle(
fontSize: 12,
),
),
),
],
);
}
}
How can I achieve this?
Container width is nullable, and containers will only take up as much space as their children require.
A simple ternary statement will achieve what you're after:
Container(
width: fullWidth ? double.infinity : null,
// ...
),

How to add a more than one container in a page layout?

So, I'm really new to flutter or dart. I looked at many tutorials, a bit hard to learn.
I need to know if I can, and how can I add more containers that contain Texts or Button in Flutter.
I am building a login page which has a container for some text and form field. I want to insert a second container where I can insert a button on the bottom of login which says 'GET OTP' has the max width the display offers as shown in the image of Login Page.
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class LoginPage extends StatefulWidget {
#override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 180.0,),
Padding(padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Lets Start With Your', style: GoogleFonts.yantramanav(fontSize: 26.0, fontWeight: FontWeight.w300, textStyle: TextStyle(color: Colors.indigo[900])),),
Text('Phone / Email', style: GoogleFonts.robotoCondensed(fontSize: 50.0, fontWeight: FontWeight.w700, textStyle: TextStyle(color: Colors.indigo[900])),),
Padding(padding: EdgeInsets.only(top: 20.0),
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Enter phone number/email id',
hintText: 'Enter phone number/email id',
)
),
Padding(
padding: EdgeInsets.only(top: 170.0),
child: Center(
child: Column(children: <Widget>[
OutlineButton(onPressed: () {}, child: Text('Skip Login', style: TextStyle(color: Colors.grey[500] ),),
borderSide: BorderSide( color: Colors.grey[300], width: 2.0,),
),
],),), ) ,
],
)
)
]
)
),
**# I want to add a container (to insert a button with full width of the display) here**
],)
);
}
}
One of the solutions is to use the Stack widget, that gives you great freedom to position widgets:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(...), //your first container
Positioned( //used to position the given child
bottom: 0,
child: GestureDetector(
onTap: () {
//here what you want to do when the user press the button
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(10),
width: MediaQuery.of(context).size.width, //to give the container the width of the screen
child: Text(
'GET OTP',
style: TextStyle(
color: Colors.white,
fontSize: 22,
),
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.purple,
Colors.blue, //Linear Gradient with 3 colors
Colors.blue[800],
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
),
),
),
],
),
);
}
The result:

Flutter hero transaction container with conditional widgets

I'm trying to implement a hero transaction which is going smoothly, but the container that I'm transitioning has two variants (small/big).
Big:
Small:
As you can see is the small version the same as the big one, but just with some elements missing. The version that needs to be rendered is set with a property isSmall.
The component looks as followed:
class TicPackage extends StatelessWidget {
TicPackage({this.package, this.onTap, this.isSmall = false});
final Package package;
final bool isSmall;
final Function() onTap;
final NumberFormat currencyFormatter =
NumberFormat.currency(locale: "nl", decimalDigits: 2, symbol: "€");
#override
Widget build(BuildContext context) {
Widget titleText = Text(
package.name,
style: TextStyle(
color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold),
);
return TicCard(
color: package.color,
elevation: 4,
onTap: onTap,
children: <Widget>[
Row(
children: <Widget>[
isSmall
? titleText
: Text("${package.eventCount} evenementen",
style:
TextStyle(color: Color.fromRGBO(255, 255, 255, 0.5))),
Text(
"${currencyFormatter.format(package.price)}",
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold),
),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
if (!isSmall)
Padding(padding: EdgeInsets.only(top: 10), child: titleText),
Padding(
padding: EdgeInsets.only(top: 2),
child: Text(package.description,
style: TextStyle(color: Colors.white))),
if (!isSmall)
Padding(
padding: EdgeInsets.only(top: 12),
child: Text(package.goods,
style: TextStyle(
color: Colors.white, fontStyle: FontStyle.italic))),
if (!isSmall)
Padding(
padding: EdgeInsets.only(top: 10),
child: Container(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 3),
child: Text(
"${currencyFormatter.format(package.discount)} korting",
style: TextStyle(color: Colors.white),
)),
decoration: BoxDecoration(
border:
Border.all(color: Color.fromRGBO(255, 255, 255, 0.5)),
borderRadius: BorderRadius.circular(100)),
))
],
);
}
}
Screen A:
Hero(
tag: "package_${args.package.id}",
child: TicPackage(
isSmall: false,
package: args.package
)))
Screen B:
Hero(
tag: "package_${args.package.id}",
child: TicPackage(
isSmall: true,
package: args.package
)))
Now the transition looks as followed:
As you can see it's working quite well, but it's a little bit snappy since I'm using conditional rendering here. Also the back transition gives an error:
A RenderFlex overflowed by 96 pixels on the bottom.
I guess this is because on the way back the space suddenly overflows because those extra widgets are getting rendered.
Now my question is how to properly create a hero component that needs to transition with conditional elements. Or if a hero widget isn't suited for this how can I achieve the same result with doing some custom animations?
Wrap your Column inside TicCard with SingleChildScrollView
import 'package:flutter/material.dart';
import 'page2.dart';
class TicCard extends StatelessWidget {
final List<Widget> children;
final double elevation;
final Color color;
const TicCard({
Key key,
this.children,
this.elevation,
this.color,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Page2(),
),
),
child: Card(
elevation: elevation,
color: color,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
),
),
),
),
);
}
}
Make use of the flightShuttleBuilder. Within this builder create a new TicCard that takes the hero animation. You can use this animation now to animate all views during flight (screen transition).
One thing that I'm not comfortable with is the _animationWidget. What it does: it wraps all the Widgets inside an FadeTransition and SizeTransition, if there is no animation and isSmall is true it returns an empty Container.
The widget:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:ticketapp_pakket/components/tic-card.dart';
import 'package:ticketapp_pakket/models/package.dart';
class TicPackage extends StatelessWidget {
TicPackage(
{this.heroTag,
this.package,
this.onTap,
this.isSmall = false,
this.animation});
final String heroTag;
final Animation<double> animation;
final Package package;
final bool isSmall;
final Function() onTap;
final NumberFormat currencyFormatter =
NumberFormat.currency(locale: "nl", decimalDigits: 2, symbol: "€");
Widget _animationWidget({Widget child}) {
return animation != null
? FadeTransition(
opacity: animation,
child: SizeTransition(
axisAlignment: 1.0, sizeFactor: animation, child: child))
: !isSmall ? child : Container();
}
#override
Widget build(BuildContext context) {
Widget eventCountText = _animationWidget(
child: Padding(
padding: EdgeInsets.only(bottom: 10),
child: Text("${package.eventCount} evenementen",
style: TextStyle(color: Color.fromRGBO(255, 255, 255, 0.5)))));
Widget goodsText = _animationWidget(
child: Padding(
padding: EdgeInsets.only(top: 12),
child: Text(package.goods,
style:
TextStyle(color: Colors.white, fontStyle: FontStyle.italic))),
);
Widget discountText = _animationWidget(
child: Padding(
padding: EdgeInsets.only(top: 10),
child: Container(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 3),
child: Text(
"${currencyFormatter.format(package.discount)} korting",
style: TextStyle(color: Colors.white),
)),
decoration: BoxDecoration(
border: Border.all(color: Color.fromRGBO(255, 255, 255, 0.5)),
borderRadius: BorderRadius.circular(100)),
)));
Widget titleText = Text(
package.name,
style: TextStyle(
color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold),
);
Widget card = TicCard(
color: package.color,
borderRadius: BorderRadius.circular(10),
margin: EdgeInsets.only(left: 20, right: 20, bottom: 10, top: 5),
onTap: onTap,
child: Container(
padding: EdgeInsets.all(15),
child: Stack(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
eventCountText,
titleText,
Padding(
padding: EdgeInsets.only(top: 2),
child: Text(package.description,
style: TextStyle(color: Colors.white))),
goodsText,
discountText,
],
),
Positioned(
child: Text(
"${currencyFormatter.format(package.price)}",
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold),
),
top: 0,
right: 0)
],
),
));
if (heroTag == null) {
return card;
}
return Hero(
tag: heroTag,
flightShuttleBuilder: (
BuildContext flightContext,
Animation<double> animation,
HeroFlightDirection flightDirection,
BuildContext fromHeroContext,
BuildContext toHeroContext,
) {
return TicPackage(
package: package,
animation: ReverseAnimation(animation),
);
},
child: card);
}
}
How to use the widget:
Use the TicPackage widget on both screens and use the same heroTag.
TicPackage(
heroTag: "package_1",
package: package,
onTap: () {
Navigator.pushNamed(context, '/package-detail',
arguments: PackageDetailPageArguments(package: package));
})
Result:
Result in slow motion:

Flutter widgets best practices: Inner Class vs Function

I am a Java developer and currently learning about Flutter/Dart. I am an adept of clean code with small functions and some widget examples just scare the s*** out of me.
I am trying to implement a Card widget with some transaction information (price, title and date). Currently the code looks like this:
class TransactionCard extends StatelessWidget {
final Transaction _transaction;
TransactionCard(this._transaction);
#override
Widget build(BuildContext context) {
return Container(
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_PriceContainer(_transaction.amount),
_DetailContainer(_transaction.title, _transaction.date),
],
),
),
);
}
}
// Inner Widgets
class _PriceContainer extends Container {
_PriceContainer(double amount)
: super(
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
decoration: BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
padding: EdgeInsets.all(10),
child: Text(
amount.toString(),
style: _amountTextStyle(),
),
);
}
class _DetailContainer extends Container {
_DetailContainer(String title, DateTime date)
: super(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: _titleTextStyle(),
),
Text(
date.toString(),
style: _dateTextStyle(),
),
],
),
);
}
// Text styles
TextStyle _amountTextStyle() {
return TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.purple,
);
}
TextStyle _titleTextStyle() {
return TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
);
}
TextStyle _dateTextStyle() {
return TextStyle(color: Colors.grey);
}
I have used two approaches:
For the inner widgets I extended Containers and gave then specific styling.
For the text styles I created a function returning the desired style.
Is there an approach preferable to the other? A third one? Is there a bad practice to create multiple Widgets on the same file?
Composition > inheritance
As mentioned in the comments and in the Flutter documentation, you should always compose widgets instead of inheriting from e.g. a Container.
In your case, this would look like this:
class _PriceContainer extends StatelessWidget {
final double amount;
const _PriceContainer({
Key key,
this.amount,
}) : super(key: key);
#override
Widget build(BuildContext context) => Container(
margin: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
decoration: BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
padding: EdgeInsets.all(10),
child: Text(
amount.toString(),
style: _amountTextStyle,
),
);
}
This is analogous for your other widgets.
Top-level functions
Declaring top-level functions is generally fine, however, in this case, you should really define a top-level property instead - preferably declare a const to take advantage of compile-time constants:
const _amountTextStyle = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.purple,
);
You should be able to apply the same to your other text styles.

Expand widget to match parent height inside the row in flutter

I want to create below UI
How to draw a line between widget, If try to expand the column line inside the row it gives error of infinity height
//Below some code not able to post all the code.
ListView(
shrinkWrap: true,
children: <Widget>[
new _Row(
label: "1",
body:
"Screening: We will screen your current portfolio to check your Portfolio's health.",
),
SizedBox(
height: 16,
),
],
),
class _Row extends StatelessWidget {
final String label;
final String body;
const _Row({Key key, this.label, this.body});
#override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 28,
height: 28,
decoration: BoxDecoration(
color: Color(0xff76587b).withOpacity(0.5),
shape: BoxShape.circle,
),
child: Center(
child: Text(
label,
textAlign: TextAlign.start,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500),
),
),
),
SizedBox(
width: 16,
),
Flexible(
child: Text(
body,
style: kModelTargetCARGTInactiveTextLabel.copyWith(
color: Colors.black, height: 1.4),
),
),
],
);
}
}
In this code line between bullet points not visible. I tried may option but it not working.