How to add space between words on separate lines in Flutter? - flutter

I want to add space between "Radio Frequency" and "Propagation" vertically i.e something like margin. and also make sure that text does not cut from top or bottom if I increase the font size.
Below is my code, I tried with spacing of letters, words and also decoration param but it did not get desired results. Thank you for your patience :)
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
padding: const EdgeInsets.fromLTRB(0, 20, 0, 0),
childAspectRatio: 1.5,
mainAxisSpacing: 30,
crossAxisCount: 3,
children: List.generate(
12,
(index) {
return Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 5),
child: CircleAvatar(
child: Transform.scale(
scale: 1,
child: Image.asset(
'assets/icons/radar_icon.png',
height: 30,
width: 30,
fit: BoxFit.fitWidth,
),
),
backgroundColor: Colors.grey.shade300,
radius: 30,
)),
Flexible(
child: Text(
"Radio Frequency Propagation",
textAlign: TextAlign.center,
style: GoogleFonts.roboto(color: Colors.black87, fontSize: 14,height: 0.8),
),
),
],
));
},
),
));
}

You are using height is correct. But I think the problem is the placement of the style parameters.
It should be like this:
Flexible(
child: Text(
"Radio Frequency \nPropagation",
textAlign: TextAlign.center,
style: GoogleFonts.roboto(
textStyle: TextStyle(
color: Colors.black87,
fontSize: 14,
height: 1.5,
),
),
),
);
}

Related

Flutter align specific widget in column with min width

I'm implementing a chat on my flutter app, and I want my chat-time to be align at the right side of the column (all other widgets should be align left).
My problem is that when I'm using alignment.bottomRight in my column, it extends the column width to max (and I want to keep it min).
The problem:
What I'm trying to achieve:
my column:
return Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
alignment: Alignment.topLeft,
nip: BubbleNip.leftTop,
radius: Radius.circular(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
getUserChatTitle(document['userId']),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: SelectableLinkify(
onOpen: onOpenLink,
text: "Text Text Text",
textAlign:
intl.Bidi.detectRtlDirectionality(document['content'])
? TextAlign.right
: TextAlign.left,
textDirection:
intl.Bidi.detectRtlDirectionality(document['content'])
? ui.TextDirection.rtl
: ui.TextDirection.ltr,
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
fontFamily: 'Arimo',
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
);
This is indeed not as easy, because you want the bubble to have an "undefined" width - it should adapt to the length of the actual message which is not known before actually placing / drawing the widget on runtime. My suggestion would be to make use of a Stack - I also used it inside a ListView.builder which will probably be the desired use case. Make sure to read my comments in the code block as well:
ListView.builder(
itemCount: 5,
itemBuilder: (context, index) => UnconstrainedBox(
/// Decide whether a message has been received or written by yourself (left or right side)
alignment:
index % 2 == 0 ? Alignment.centerLeft : Alignment.centerRight,
/// ConstrainedBox to make sure chat bubbles don't go from left to right if they are too big - you can change it or even remove it if it's not what you want
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width / 1.5),
child: Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
/// Alignment and nip has to be adjusted here too
alignment:
index % 2 == 0 ? Alignment.topLeft : Alignment.topRight,
nip: index % 2 == 0 ? BubbleNip.leftTop : BubbleNip.rightTop,
radius: Radius.circular(10),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('TestUser'),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: Text(
'Text ' * Random().nextInt(50),
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
),
),
),
/// Adjust the space you want between the actual message and the timestamp here, you could also use a Text widget to use the same height as the actual timestamp - as you like
SizedBox(height: 18.0),
],
),
Positioned(
bottom: 0,
right: 0,
child: Text(
'08.09.2021',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
),
),
),
),
Replace this:
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
With:
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
)],
),

How to assign a controller for ListWheelScrollView in Flutter?

I am using a ListWheelScrollView that is using physics: FixedExtentScrollPhysics(),. I have used various other ScrollControllers in my app. I want to supply a parameter to my ListWheelScrollView so that it uses the same ScrollController as the rest of my widgets. However it does not allow me to supply the controller:mainController parameter along with FixedExtentScrollPhysics(). How can I solve this?
Here this is the declaration of mainController, the on that I'm trying to call in ListWheelScrollView :
final mainController = ScrollController();
The code for my list is :
ListWheelScrollView.useDelegate(
itemExtent: 90,
perspective: 0.0025,
magnification: 1.2,
physics: FixedExtentScrollPhysics(),
diameterRatio: 4,
// controller: mainController,
offAxisFraction: 0.42,
useMagnifier: true,
childDelegate: ListWheelChildBuilderDelegate(
builder: (
context,
index,
) {
return Column(
children: [
ListTile(
isThreeLine: false,
trailing: indexTrailing(index, duration, true),
title: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
right: 10, top: 5, bottom: 5),
child: ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Container(
height: 60,
width: 60,
child: Image.network(
'https://www.ikea.com/in/en/images/products/smycka-artificial-flower-rose-red__0903311_PE596728_S5.JPG'),
),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hello',
style: GoogleFonts.montserrat(
wordSpacing: 0,
letterSpacing: 0,
textStyle: kTasksStyle.copyWith(
fontSize: 15,
color: kDarkBlue,
fontWeight: FontWeight.w500),
),
),
SizedBox(
height: 5,
),
SizedBox(
width: MediaQuery.of(context).size.width *
0.62,
child: RichText(
maxLines: 2,
overflow: TextOverflow.ellipsis,
text: TextSpan(
text: "This is a rose",
style: GoogleFonts.montserrat(
textStyle: kTasksStyle.copyWith(
fontSize: 12,
color: kGrey,
fontWeight: FontWeight.normal),
),
),
),
)
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 18.0, right: 18, top: 5, bottom: 5),
child: Divider(
height: 1,
color: Colors.grey.withOpacity(0.2),
thickness: 1,
),
),
],
);
},
childCount: 9),
),
This is the error that I get when I supply the controller parameter along with FixedExtentScrollPhysics():
'package:flutter/src/widgets/scroll_position.dart': Failed assertion: line 504 pos 12: 'haveDimensions == (_lastMetrics != null)': is not true.
The relevant error-causing widget was
ListWheelScrollView
and
The following assertion was thrown during performLayout():
FixedExtentScrollPhysics can only be used with Scrollables that uses the FixedExtentScrollController
'package:flutter/src/widgets/list_wheel_scroll_view.dart':
Failed assertion: line 485 pos 7: 'position is _FixedExtentScrollPosition'
Just use;
FixedExtentScrollController();
instead of
ScrollController();

onTap event of InkResponse not working for grid item

I am trying to execute a simple click event on the grid item in my list. Below is my code which was build using many answers present on stack overflow but none of them is working for me. I wanted a ripple effect on click hence I have used InkResponse.
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
padding: const EdgeInsets.fromLTRB(0, 20, 0, 0),
childAspectRatio: 1.5,
mainAxisSpacing: 30,
crossAxisCount: 3,
children: gridItem(parentCalcList),
)
);
}
List<Widget> gridItem(List<ParentCalculators> mParentCalcList) {
List<Widget> tiles = <Widget>[];
for (int i = 0; i < mParentCalcList.length; i++) {
tiles.add(GridTile(
child: InkResponse(
child: getGridColumn(mParentCalcList.elementAt(i)),
onTap: _gridItemClicked(i),
enableFeedback: true,
)));
}
return tiles;
}
getGridColumn(ParentCalculators calc) {
return Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 5),
child: CircleAvatar(
child: Transform.scale(
scale: 1,
child: Image.asset(
calc.icon,
height: 30,
width: 30,
fit: BoxFit.fitWidth,
),
),
backgroundColor: Colors.grey.shade300,
radius: 28,
)),
Flexible(
child: Text(
calc.name,
textAlign: TextAlign.center,
style: GoogleFonts.roboto(
color: Colors.black87,
fontSize: 14,
height: 1.1,
textStyle: Theme.of(context).textTheme.subtitle2,
wordSpacing: 0.5,
letterSpacing: 0.8),
),
),
],
);
}
Thank you for your help and patience.

SingleChildScrollView makes the UI white

I am trying to make my UI scrollable but when i add the SingleChildScrollView i get this white screen not showing anything at all.I should erase the Column from the begining?Use a container?I already search on internet but i don't know what to add.
Here is my code, please tell me what i can erase or add to make it work ..
class _UserProfilesState extends State<UserProfiles> {
#override
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Expanded(
child: Stack(
children: <Widget>[
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 40.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
iconSize: 30.0,
color: Colors.black,
onPressed: () => Navigator.pop(context),
),
])),
Positioned(
left: 24,
top: MediaQuery.of(context).size.height / 6.5 - 28,
child: Container(
height: 84,
width: 84,
//profilepic
child: CircleAvatar(
radius: 10,
backgroundImage: NetworkImage(widget.avatarUrl != null
? widget.avatarUrl
: "https://icon-library.com/images/add-image-icon/add-image-icon-14.jpg"),
),
),
),
Positioned(
right: 24,
top: MediaQuery.of(context).size.height / 6.5 + 16,
child: Row(
children: <Widget>[
Container(
height: 32,
width: 100,
child: RaisedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ChatScreen(
serviceProviderId:
widget.serviceProviderId,
userName: widget.userName,
avatarUrl: widget.avatarUrl,
)));
},
color: Colors.black,
textColor: Colors.white,
child: Text(
"Message",
style: TextStyle(fontWeight: FontWeight.bold),
)),
),
SizedBox(
width: 16,
),
Container(
height: 32,
width: 32,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://lh3.googleusercontent.com/Kf8WTct65hFJxBUDm5E-EpYsiDoLQiGGbnuyP6HBNax43YShXti9THPon1YKB6zPYpA"),
fit: BoxFit.cover),
shape: BoxShape.circle,
color: Colors.blue),
),
],
),
),
Positioned(
left: 24,
top: MediaQuery.of(context).size.height / 4.3,
bottom: 0,
right: 0,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.userName,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 22,
)),
SizedBox(
height: 4,
),
Padding(
padding: const EdgeInsets.all(1.0),
child: Text(
widget.address == "default"
? "No Address yet"
: "${widget.address}",
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
)),
Padding(
padding: const EdgeInsets.all(1.0),
child: Text(
"${widget.categoryName}",
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
)),
],
),
))
],
))
],
),
),
);
}
}
Using Spacer() might also cause this issue
The reason why your UI became white is that SingleChildScrollView allows it child to take as much space as possible. In your Column, one of your children is Expanded, Expanded tries to take as much space as possible. You are making your UI take an infinite amount of space because of that. That's the reason why you are seeing a white screen. The solution here would be to remove Expanded.
according to me and the knowledge I have this happened because the singlechildscrollview here tries to take as much height as it can take so It is creating an issue to solve this wrap the singlechildscrollview in a container and give height&width to the container it solved in my case
Thanks...
I faced similar issues, but after much research I got it working, by ensuring that the body of the scaffold be a Container that defines it's height and width, or Column. After which you can wrapped your any of these with a SingleChildScrollView.
However, in an attempt to insert an Expanded widget as child element, the expanded widget will look for bounded heights of it's parents/root element. And if it doesn't found any, it will thrown an error. A good example is if the root element is a column or a container with an unbounded height. Which is your case, looking at your code

Bottom overflowed inside column while listing with Grid.count

I have problem with column, inside Column i have 3 containers. 1st one has picture inside other two has text. For the first container i want to apply height like 100 for example. but max what can i apply is 60 then it giving bottom overflowed. I am using Grid.count to make grid view and listing them with List.genarate.
PS: Wrapping with expanded effecting first container height, and the container does not have fixed height
Here is my code :
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 90,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Theme.of(context).focusColor.withOpacity(0.9),
blurRadius: 4,
offset: Offset(0, 2)),
],
),
width: 90,
child: Hero(
tag: widget.heroTag + widget.product.id,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: CachedNetworkImage(
height: 90,
fit: BoxFit.fill,
imageUrl: this.widget.product.imageUrl,
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
height: 150,
),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
),
),
Center(
child: Container(
width: 90,
child: Text(
widget.product.name,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
),
),
Center(
child: Container(
child: Text(
" ${widget.product.salePrice.toString()} Ft ",
style: TextStyle(
color: Colors.blue[800],
fontSize: 13,
fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
),
),
)
],
),
Here i am listing them with grid.count and list.genearte :
GridView.count(
scrollDirection: Axis.vertical,
shrinkWrap: true,
primary: false,
mainAxisSpacing: 15.0,
// crossAxisSpacing: 4.0,
padding: EdgeInsets.symmetric(
vertical: 15),
crossAxisCount:
MediaQuery.of(context)
.orientation ==
Orientation.portrait
? 3
: 3,
children: List.generate(
_con.subCategories
.elementAt(0)
.products
.length, (index) {
return ProductGridItemWidget(
heroTag: 'product-grid' +
0.toString() +
index.toString(),
product: _con.subCategories
.elementAt(0)
.products
.elementAt(index),
onPressed: () {
{
_con.addToCart(_con
.subCategories
.elementAt(0)
.products
.elementAt(index));
}
});
}),
)),
Finally found solution from this post
Give a height to the child of GridView
Just need to write this line of code inside GridView.count
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),