I am building a cross-platform application in Flutter, and I am having trouble displaying long text values in a Row
layout. Specifically, the text in the InfoRow
widget sometimes overflows when it's too long, causing layout issues.
I want the value
text to display correctly without overflowing, ideally in a way that it wraps like a paragraph. I have tried using softWrap
and overflow
but the text is still not displaying as expected.
I want the value text to wrap and flow within the available space, like a paragraph, without overflow errors. Below is an image of what I want to achieve:
info_row.dart
:
I am using this InfoRow
widget to display the label and value pair. The value text is sometimes too long, causing it to overflow.
import 'package:flutter/material.dart';
import 'package:solidcheck_admin/core/constants/app_colors.dart';
class InfoRow extends StatelessWidget {
final String label;
final String value;
const InfoRow({required this.label, required this.value, Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 150.0,
child: Text(
label,
style: const TextStyle(
fontWeight: FontWeight.w400,
color: AppColors.textGrey,
fontSize: 14.0,
),
),
),
Text(
value,
textWidthBasis: TextWidthBasis.longestLine,
softWrap: true,
overflow: TextOverflow.ellipsis,
maxLines: 6,
style: const TextStyle(
fontWeight: FontWeight.w400,
color: AppColors.textBlack,
fontSize: 14.0,
),
),
],
),
);
}
}
The text is overflowing in this layout and not wrapping as expected:
applicant_header_widget.dart
:This widget is used across multiple screens with different values.
import 'package:flutter/material.dart';
import 'package:solidcheck_admin/data/models/applicant_list.dart';
import 'package:solidcheck_admin/ui/widgets/app/custom_button.dart';
import 'package:solidcheck_admin/ui/widgets/main/tabbar/info_rows.dart';
class ApplicantHeaderDetails extends StatelessWidget {
final ApplicantListModel applicantModelValue;
const ApplicantHeaderDetails({
Key? key,
required this.applicantModelValue,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_profileInfo(size),
const SizedBox(height: 30.0),
Row(
children: [
CustomButton(title: 'Button 1', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 2', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 3', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 4', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 5', onPressed: () {}),
],
),
],
),
const SizedBox(width: 100.0),
Container(
width: size.width * 0.50,
child: const Wrap(
spacing: 10.0,
runSpacing: 10.0,
children: [
InfoRow(label: 'Date created:', value: 'Monday, 14-Nov-2022 09:50'),
InfoRow(label: 'Last updated:', value: 'Friday, 12-July-2023 22:55'),
InfoRow(label: 'Applicant Status:', value: 'New'),
InfoRow(label: 'Applicant Status Date:', value: 'Friday, 12-July-2023 22:55'),
InfoRow(label: 'Consent user:', value: 'Unknown'),
InfoRow(label: 'Job Title:', value: 'Cleaner'),
InfoRow(label: 'Check requested:', value: 'Basic Disclosure'),
InfoRow(label: 'Online status:', value: 'Applicant created by requester'),
InfoRow(label: 'Requested by:', value: 'Mike Ross\n004407546604213/\n004407546604213\[email protected]'),
],
),
),
],
),
);
}
Widget _profileInfo(Size size) {
return Row(
children: [
Container(
height: size.height * 0.18,
width: size.width * 0.09,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(8.0),
),
child: const Icon(Icons.image, size: 50.0, color: Colors.grey),
),
const SizedBox(width: 10.0),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Thom World', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0, color: Colors.black)),
SizedBox(height: 4.0),
Text('Send disclosure to client (cannot use eBulk)', style: TextStyle(color: Colors.grey, fontSize: 14.0)),
SizedBox(height: 8.0),
Text('Service level 1', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500, fontSize: 14.0)),
SizedBox(height: 4.0),
Text('Primary requester: Test company', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400, fontSize: 14.0)),
],
),
],
);
}
}
wrap your Text
widget with Expanded
or Flexible
widget like this
make some other adjustments as well and make it working.
class ApplicantHeaderDetails extends StatelessWidget {
const ApplicantHeaderDetails({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
body: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_profileInfo(size),
const SizedBox(height: 30.0),
Row(
children: [
CustomButton(title: 'Button 1', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 2', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 3', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 4', onPressed: () {}),
const SizedBox(width: 8.0),
CustomButton(title: 'Button 5', onPressed: () {}),
],
),
],
),
const SizedBox(width: 100.0),
Expanded(
// width: size.width * 0.50,
child: const Wrap(
spacing: 10.0,
runSpacing: 10.0,
children: [
InfoRow(
label: 'Date created:',
value: 'Monday, 14-Nov-2022 09:50'),
InfoRow(
label: 'Last updated:',
value: 'Friday, 12-July-2023 22:55'),
InfoRow(label: 'Applicant Status:', value: 'New'),
InfoRow(
label: 'Applicant Status Date:',
value: 'Friday, 12-July-2023 22:55'),
InfoRow(label: 'Consent user:', value: 'Unknown'),
InfoRow(label: 'Job Title:', value: 'Cleaner'),
InfoRow(label: 'Check requested:', value: 'Basic Disclosure'),
InfoRow(
label: 'Online status:',
value: 'Applicant created by requester'),
InfoRow(
label: 'Requested by:',
value:
'Mike Ross\n004407546604213/\n004407546604213\[email protected]'),
],
),
),
],
),
),
);
}
Widget _profileInfo(Size size) {
return Row(
children: [
Container(
height: size.height * 0.18,
width: size.width * 0.09,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(8.0),
),
child: const Icon(Icons.image, size: 50.0, color: Colors.grey),
),
const SizedBox(width: 10.0),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Thom World',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
color: Colors.black)),
SizedBox(height: 4.0),
Text('Send disclosure to client (cannot use eBulk)',
style: TextStyle(color: Colors.grey, fontSize: 14.0)),
SizedBox(height: 8.0),
Text('Service level 1',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 14.0)),
SizedBox(height: 4.0),
Text('Primary requester: Test company',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 14.0)),
],
),
],
);
}
}
class InfoRow extends StatelessWidget {
final String label;
final String value;
const InfoRow({required this.label, required this.value, Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 150.0,
child: Text(
label,
style: const TextStyle(
fontWeight: FontWeight.w400,
color: Colors.grey,
fontSize: 14.0,
),
),
),
Flexible(
child: Text(
value,
textWidthBasis: TextWidthBasis.longestLine,
softWrap: true,
overflow: TextOverflow.ellipsis,
maxLines: 6,
style: const TextStyle(
fontWeight: FontWeight.w400,
color: Colors.black,
fontSize: 14.0,
),
),
),
],
);
}
}
here is the result