How to stop shrinking the text in flutter web - flutter

I am new to flutter, need to know about a problem I am facing. I have built a web app using flutter. Which contains columns, containers, grid views, and other flutter widgets.
The problem I am facing is, though my layout is responsive when I shrink the chrome browser, it starts shrinking the content. Usually, in sites like Amazon, and other web pages, the shrink browser shows an extra scroll bar horizontally and vertically, and the content size remains the same.
How the same can be done using flutter?
Before
After
Here is the code:
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: DateCard(
eventName: 'Code Freeze', date: DateTime.now())),
SizedBox(width: 5),
Flexible(
child: DateCard(
eventName: 'Switchover', date: DateTime.now())),
SizedBox(width: 5),
Flexible(
child: DateCard(eventName: 'SP GA', date: DateTime.now())),
],
),
class DateCard extends StatelessWidget {
final String eventName;
final DateTime date;
const DateCard({this.eventName, this.date});
#override
Widget build(BuildContext context) {
return Column(
children: [
Material(
shape: SuperellipseShape(
borderRadius: BorderRadius.circular(28),
),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 3),
child: FittedBox(
fit: BoxFit.contain,
child: Column(
children: [
Text(
date.day.toString(),
// maxLines: 1,
// overflow: TextOverflow.visible,
style: TextStyle(
fontSize: SizeConfig.blockSizeHorizontal * 3,
letterSpacing: -1),
),
Text(
DateFormat("MMM").format(date),
// overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: SizeConfig.blockSizeHorizontal * 1.2,
),
),
],
),
),
),
),
SizedBox(height: 5),
Text(
eventName,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 14),
)
],
);
}
}

Related

How to build widget with certain order?

Hi I'm trying to create a widget of container that contain a list of profile picture and person name (max 3 people). I manage to build them but the problem is I wanted to make the current logged in user to always be on the left side, not on the middle or right side. How can I achieved it ? Thanks before
Here's my code:
if (ticketData['solver_id'] != null && ticketData['solver_id'].isNotEmpty) {
await Future.forEach(ticketData['solver_id'], (solver) async {
solverWidgets.add(
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
BuildRoundedRectProfile(
height: 40,
width: 40,
name: solverTicket[solver]['nickname'],
profileLink: solverTicket[solver]['profile_picture_link'] ?? '',
),
SizedBox(height: 3),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text(
solverTicket[solver]['nickname'],
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: weight600Style.copyWith(
color: primaryColor,
fontSize: 13,
),
),
),
],
),
),
);

TextSpan's text doesn't show if it overflows

That's how it looks when I have a WidgetSpan and a TextSpan, and the text inside the TextSpan is too long:
problem
A similar question has already been asked here TextSpan's text doesn't show if it overflows and is placed after WidgetSpan, but the one answer isn't suitable for my problem.
I have two Text.rich() widgets (which each host one WidgetSpan and one TextSpan) inside an Expanded widget, both Expanded with flex:1, because I want them to be the same size and take as much space as they can. That's why a row is not an option, you can't (as far as I know) put two rows side by side, at this happens...
using rows
This is how it's supposed to look like, just with the TextOverflow.ellipsis, if the text is too long:
target UI
Here is my code:
Row(
children: [
Expanded(
flex: 1,
child: Text.rich(
TextSpan(children: [
WidgetSpan(
child: Container(
margin: const EdgeInsets.only(right: 4.0),
child: SvgPicture.asset("assets/icons/building.svg", color:
htLightGrey),
),
),
TextSpan(
text: incident.building.name,
style: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16.0,
color: htLightGrey, /*overflow: TextOverflow.ellipsis*/
),
),
]),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Expanded(
flex: 1,
child: incident.department != null
? Text.rich(
TextSpan(children: [
WidgetSpan(
child: Container(
margin: const EdgeInsets.only(right: 4.0),
child: SvgPicture.asset("assets/icons/department.svg",
color: htLightGrey),
),
),
TextSpan(
text: incident.department!.name,
style: const TextStyle(fontWeight: FontWeight.normal,
fontSize: 16.0, color: htLightGrey, overflow:
TextOverflow.ellipsis),
),
]),
maxLines: 1,
overflow: TextOverflow.ellipsis,
)
: const SizedBox.shrink(),
)
],
)
To achieve your target Ui, use the Wrap widget instead of the Row widget. Here, when the contents of the widget overflow/exceed it will break it to the next line, hence you'll achieve your target Ui.
While we like to archive this UI, we are using Row as parent widget, which is perfect. Then we can split the row into tree part, left two part will get same and maximum available width. For this scenario, widget structure as follows.
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.green,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, //start from left
children: [
buildItem(
text:
"incident.buildi cident.buildi cident.buildi cident.buildi cident.building.name"),
buildItem(text: "incide ing.ssss"),
],
),
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildItem(text: "i ent.building.name"),
buildItem(text: "incident.building.ssss"),
],
),
),
),
IconButton(
onPressed: () {},
iconSize: 33,
icon: Icon(Icons.arrow_right),
),
],
),
And inside Text.rich add use alignment: PlaceholderAlignment.middle, on WidgetSpan to set the middle.
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
And you will get
I am using extra container to point the UI, simply remove the container from the column. Also, you can use Row instead of Rich Text.
Test widget
class _TestGroundState extends State<TestGround> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.green,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start, //start from left
children: [
buildItem(
text:
"incident.buildi cident.buildi cident.buildi cident.buildi cident.building.name"),
buildItem(text: "incide ing.ssss"),
],
),
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildItem(text: "i ent.building.name"),
buildItem(text: "incident.building.ssss"),
],
),
),
),
IconButton(
onPressed: () {},
iconSize: 33,
icon: Icon(Icons.arrow_right),
),
],
),
],
));
}
Text buildItem({
required String text,
}) {
return Text.rich(
TextSpan(
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
child: Icon(Icons.ac_unit),
),
),
TextSpan(
text: text,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16.0,
),
),
],
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
);
}
}
More about flutter layout

How to solve for 'text overflow.ellipse' in flutter?

I am unable to make my text stop extending the screen and overflowing. My code is as follows:
class OrderTileDisplay extends StatelessWidget {
final MenuOrderData orderItem;
final editable;
OrderTileDisplay(this.orderItem, {this.editable = true});
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
GestureDetector(
onTap: (){},
child: Container(
color: Colors.transparent,
margin: EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
orderItem.quantity.toString() + 'x',
style: Title16,
),
SizedBox(
width: 8,
),
Text(
orderItem.name, // OVERFLOWS WHEN IT IS A LONGER SENTENCE
style: Title18bold,
overflow: TextOverflow.ellipsis,
),
],
),
Row(
children: [
editable? Icon(Icons.edit, color: Colors.grey[200], size: 20,) : Container(),
SizedBox(width: 8,),
Text("£" + Provider.of<CP>(context).getTotalForItem(orderItem).toStringAsFixed(2),
style: Title18bold,),
],
),
],
),
),
),
Container(... and other stuff)
I have tried putting Text inside a container then Expanded widget but I keep getting errors. Not sure how to solve it.
Try to wrap your Row and Text inside a Flexible:
Flexible( //flexible here
child: Row(
children: [
Text(
orderItem.quantity.toString() + 'x',
style: Title16,
),
SizedBox(
width: 8,
),
Flexible( //and here
child: Text(
orderItem.name, // no more overflow
style: Title18bold,
overflow: TextOverflow.ellipsis, //working as expected
),
),
],
),
),
As the documentation states, TextOverflow says how overflowing text should be handled, but it will not work if it's parent don't have a fixed size. In this case, Flexible is been used to restrict the total size of the text to prevent overflow, when it reaches a very large width.

Flutter - assistance with complex widget layout

I'm designing a shopping app that pulls data from an e-commerce store API. I've created this layout for the store items:
Each item is a Card with a Row as the main child, which contains the Image widget and two Columns for the text. The first column holds the title and subtitle, while the second one holds the price. It looks good now, but if the subtitle is any bigger, then this happens:
I'd ideally like the title and price to be grouped together, with the title aligned left and the price justified right, with the subtitle being able to take up the rest of the remaining width of the card.
I am familiar with how the Flutter layout works, but this task seems a bit beyond me. Even getting to this stage was a real challenge. I know that the parent's height and width can be obtained with LayoutBuilder, but this sort of thing requires calculating sibling width (and possibly height), which I'm not sure how to do. So any help here would be good.
Here is the code for the widget:
import 'package:flutter/material.dart';
class ProductItem extends StatelessWidget {
final String name;
final String shortDescription;
final double price;
final String imageUrl;
ProductItem({this.name, this.shortDescription, this.price, this.imageUrl});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Image.network(
imageUrl,
fit: BoxFit.fill,
width: MediaQuery.of(context).size.width * 0.3,
),
SizedBox(width: 15,),
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
name,
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 20.0,
color: const Color(0xFF000000),
fontWeight: FontWeight.w600,
),
),
Text(
shortDescription,
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 16.0,
color: const Color(0xFF000000),
fontWeight: FontWeight.w200,
),
),
],
),
SizedBox(width: 20),
Expanded(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'฿${price.toStringAsFixed(0)}',
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 20.0,
color: const Color(0xFF000000),
fontWeight: FontWeight.w500,
),
)
],
),
)
],
),
),
);
}
}
Try to wrap the shortDescription Text widget with Expanded widget and set the maxLines in Text widget to two or according to your preference, like this:
Expanded(
child: Text(
shortDescription,
maxLines: 2,
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 16.0,
color: const Color(0xFF000000),
fontWeight: FontWeight.w200,
),
),
),

Text Wrapping in Flutter

I am writing a widget in flutter for a project which should look like this, I am new to flutter and I am trying to imitate the card below
So far this is my code for the widget
import 'package:flutter/material.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
class TrailCard extends StatelessWidget {
const TrailCard({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset(
'assets/images/cocoa.jpg',
height: 100,
width: 90,
fit: BoxFit.fitHeight,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Boring Cocoa",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
Text('Rajhamundry, AP'),
Text(
'Feel the authentic flavours of life while you visit the farms around Rajahmundry',
overflow: TextOverflow.ellipsis,
)
],
),
),
],
)),
)),
);
}
}
I tried using flexible and expanded to try and make the content look the way but I am getting overflow error
You can wrap the Padding widget with a Flexible widget so it takes only the amount of space needed:
NOTE: you should also set the maximum amount of lines the Text widget should take before showing the ellipsis.
Flexible(
// new line
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Boring Cocoa",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
Text('Rajhamundry, AP'),
Text(
'Feel the authentic flavours of life while you visit the farms around Rajahmundry more text to cause overflow',
// set maximum number of lines the text should take
maxLines: 3, // new line
overflow: TextOverflow.ellipsis,
)
],
),
),
);
RESULT:
Wrap Padding with Expanded
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Boring Cocoa",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
Text('Rajhamundry, AP'),
Text(
'Feel the authentic flavours of life while you visit the farms around Rajahmundry',
overflow: TextOverflow.ellipsis,
)
],
),
),
)