How to set container width conditionally in flutter? - 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,
// ...
),

Related

How to add a TextButton inside ProfileListItem in flutter

how i create a text button inside profile list item?
please check the code and help to create a text button i edited previous code because 2 person said that they need to see my ProfileListItem
i tried to add a TextButton inside ProfileListItem but i can't. here is my code how i create a text
button inside profile list item?
Expanded(
child: ListView(
children: const <Widget>[
ProfileListItem(
icon: LineAwesomeIcons.lock,
text: 'Privacy',
hasNavigation: true,
),
class ProfileListItem extends StatelessWidget {
final IconData icon;
final text;
final bool hasNavigation;
const ProfileListItem({
Key? key,
required this.icon,
this.text,
required this.hasNavigation,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: kSpacingUnit.w * 5.5,
margin: EdgeInsets.symmetric(horizontal: kSpacingUnit.w * 4)
.copyWith(bottom: kSpacingUnit.w * 2),
padding: EdgeInsets.symmetric(horizontal: kSpacingUnit.w * 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(kSpacingUnit.w * 3),
//color: Theme.of(context).backgroundColor,
color: AppColors.deep_orange,
),
child: Row(children: <Widget>[
Icon(
this.icon,
size: kSpacingUnit.w * 2.5,
),
SizedBox(width: kSpacingUnit.w * 2.5),
Text(
this.text,
style: kTitleTextStyle.copyWith(fontWeight: FontWeight.w500),
),
Row(
children: <Widget>[
Icon(
this.icon,
size: kSpacingUnit.w * 2.5,
),
SizedBox(width: kSpacingUnit.w * 2.5),
Text(
this.text,
style: kTitleTextStyle.copyWith(fontWeight: FontWeight.w500),
),
],
),
]));
}
}
Please try the below code :
class ProfileListItem extends StatelessWidget {
final IconData icon;
final String? text;
final bool hasNavigation;
const ProfileListItem({
Key? key,
required this.icon,
this.text,
required this.hasNavigation,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 10.h,
// margin:
// EdgeInsets.symmetric(horizontal: 10.w * 4).copyWith(bottom: 10 * 2),
// padding: EdgeInsets.symmetric(horizontal: 10.w * 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10 * 3),
//color: Theme.of(context).backgroundColor,
color: Colors.deepOrange,
),
child: Row(children: [
TextButton(
onPressed: () {},
child: Text(
text ?? "",
style: const TextStyle(fontSize: 12),
),
),
Expanded(
child: TextButton(
onPressed: () {},
child: Row(
children: <Widget>[
Icon(
icon,
size: 20,
color: Colors.white,
),
Text(
text ?? "",
style: const TextStyle(
fontSize: 12,
color: Colors.white,
),
),
],
),
),
),
]));
}
}
For more detail see here : https://api.flutter.dev/flutter/material/TextButton-class.html

How to give padding for the scrollbar in the dropdown in Flutter?

import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:sizer/sizer.dart';
class LocationDropdown extends StatefulWidget {
final List cities;
final String? selectedCity;
final Color? locationIconColor;
final Color? iconColor;
final Color? textColor;
final Function(String?) onLocationChange;
final double? width;
final Offset? offset;
const LocationDropdown({
Key? key,
required this.cities,
required this.selectedCity,
this.locationIconColor,
this.iconColor,
this.textColor,
this.width,
this.offset,
required this.onLocationChange,
}) : super(key: key);
#override
State<LocationDropdown> createState() => _LocationDropdownState();
}
class _LocationDropdownState extends State<LocationDropdown> {
bool isDropDownButtonClicked = false;
#override
Widget build(BuildContext context) {
return DropdownButtonHideUnderline(
child: DropdownButton2<String>(
onMenuStateChange: (value) {
setState(() {
isDropDownButtonClicked = value;
});
},
isExpanded: true,
hint: Row(
children: [
SvgPicture.asset(
Constants.marker,
height: 16,
color: widget.locationIconColor,
),
const SizedBox(
width: 5,
),
SizedBox(
width: widget.width == null ? null : (widget.width! - 40),
child: Text(
"${widget.selectedCity}",
style: TextStyle(
fontSize: 14,
color: widget.textColor ?? Colors.white,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
const Spacer(),
RotatedBox(
quarterTurns: isDropDownButtonClicked ? 2 : 0,
child: SvgPicture.asset(
Constants.downward_white_icon,
width: 15,
color: widget.iconColor,
),
),
],
),
items: widget.cities
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
"$item",
style: TextStyle(
fontSize: 14,
fontWeight: "Mumbai" == item
? FontWeight.w500
: FontWeight.w300,
color: widget.selectedCity == item
? ColorCode.secondaryColor
: ColorCode.placeholderDefault),
overflow: TextOverflow.ellipsis,
),
))
.toList(),
onChanged: widget.onLocationChange,
icon: const SizedBox.shrink(),
buttonElevation: 2,
itemHeight: 35,
itemPadding: const EdgeInsets.only(left: 14, right: 14),
dropdownMaxHeight: 140,
dropdownWidth: 150,
dropdownPadding: null,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: Theme.of(context).colorScheme.primaryContainer,
),
scrollbarRadius: const Radius.circular(40),
scrollbarThickness: 2.w,
scrollbarAlwaysShow: true,
offset: widget.offset ?? const Offset(0, 0),
),
);
}
}
I'm using "DropdownButton2" package for creating the dropdown. I want to give top and right padding for the scrollbar . I'm not able to find any solutions. Please help.
Currently it looks like this
But it should look like this
Scrollbar should have padding to the top and right like this.
How to achieve padding to the scrollbar in this "dropdownbutton2" package. I searched for other packages as well but didn't find any solution.
Upgrade to latest version and use dropdownScrollPadding parameter.
dropdownPadding: The inner padding of the dropdown menu.
dropdownScrollPadding: The inner padding of the dropdown menu including the scrollbar.
I may not be right but try in this part
dropdownPadding: null,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: Colors.redAccent,
padding: EdgeInsets.only(top: 10.0, right: 10.0)
),
adding to BoxDecoration padding.
https://api.flutter.dev/flutter/painting/BoxDecoration-class.html

How to center Text widget vertically inside a container of fixed height in Flutter

I want to center a Text Widget vertically inside a container with a fixed height. But, I want to keep the width of the container dynamic which will change according to the length of the Text.
I tried using the Center and Align over the Text widget and the parent container widget, but it expanded along the whole width.
Point to be noted Container is residing inside another Column.
import 'package:flutter/material.dart';
class CustomIconButton extends StatelessWidget {
final String name;
final Function()? onTap;
final TextStyle? textStyle;
final BorderRadius? borderRadius;
const CustomIconButton({
Key? key,
required this.name,
this.onTap,
this.textStyle,
this.borderRadius,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.2,
decoration: BoxDecoration(
color: Color(0xFFE2D9FB),
borderRadius:
borderRadius ?? const BorderRadius.all(Radius.circular(15)),
),
child: Text(
name,
style: textStyle,
),
);
}
}
This is the actual outcome
This is the desired outcome
I don't want to use vertical padding to center the Text
You can try this below code easy and simple
import 'package:flutter/material.dart';
class CustomIconButton extends StatelessWidget {
final String name;
final Function()? onTap;
final TextStyle? textStyle;
final BorderRadius? borderRadius;
const CustomIconButton({
Key? key,
required this.name,
this.onTap,
this.textStyle,
this.borderRadius,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
height: MediaQuery.of(context).size.height * 0.2,
decoration: BoxDecoration(
color: Color(0xFFE2D9FB),
borderRadius:
borderRadius ?? const BorderRadius.all(Radius.circular(15)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
name,
textAlign: TextAlign.center,
style: textStyle,
),
],
),
),
),
);
}
}
you can wrap you text in a Column that will take the whole container size then you can use mainAxisAlignment to center it
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
name,
style: textStyle,
),
],
),
you can wrap your Text widget inside Column then set mainAxisAlignment to center, like this:
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
name,
style: textStyle,
),
],
),
for working example see: https://dartpad.dev/?id=e66e420f2f0201c772f73819711bf290
check this screenshot:
Try below code and set alignment: Alignment.center, to your container.
Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.2,
decoration: BoxDecoration(
color: Color(0xFFE2D9FB),
borderRadius: const BorderRadius.all(Radius.circular(15)),
),
child: Text(
'Button',
style: TextStyle(),
),
);
Other Way using Column
Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.2,
decoration: BoxDecoration(
color: Color(0xFFE2D9FB),
borderRadius: const BorderRadius.all(Radius.circular(15)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Button',
style: TextStyle(),
),
],
),
);
Refer layout
Result Screen->
You should put an column with the parameter "mainAxisAlignment: MainAxisAlignment.center", who will put all widgets centered... Like this:
import 'package:flutter/material.dart';
class CustomIconButton extends StatelessWidget {
final String name;
final Function()? onTap;
final TextStyle? textStyle;
final BorderRadius? borderRadius;
const CustomIconButton({
Key? key,
required this.name,
this.onTap,
this.textStyle,
this.borderRadius,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.2,
decoration: BoxDecoration(
color: Color(0xFFE2D9FB),
borderRadius:
borderRadius ?? const BorderRadius.all(Radius.circular(15)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
name,
style: textStyle,
),
],
),
);
}
}
Try this:
return Container(
height: MediaQuery.of(context).size.height * 0.2,
width: MediaQuery.of(context).size.width * name.length/50,
decoration: BoxDecoration(
color: Color(0xFFE2D9FB),
borderRadius:
borderRadius ?? const BorderRadius.all(Radius.circular(15)),
),
child: Center(
child: Text(
name,
style: textStyle,
),
),
);
name : "Button"
name : "ButtonButtonButton"

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.

Disable Flutter text Baseline

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 );