'Flutter Hebrew font causes Text widget overflow
The following layout causes an overflow error, only when using Hebrew text / font. Not in all cases (some works fine - see attached image).
Works just fine with English text / font: just replace loremHeb with loremEng (in line 11) and see for yourself.
This is a running example (copy paste into DartPad):
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
var rnd = Random();
const String loremEng =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
const String loremHeb = 'לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית להאמית קרהשק סכעיט דז מא, מנכם למטכין נשואי מנורךגולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט. קונסקטורר אדיפיסינג אלית. סת אלמנקום ניסי נון ניבאה. דס איאקוליס וולופטה דיאם. וסטיבולום אט דולור, קראס אגת לקטוס וואל אאוגו וסטיבולום סוליסי טידום בעליק. קונדימנטום קורוס בליקרה, נונסטי קלובר בריקנה סטום, לפריקך תצטריק לרטי';
runApp(
MyApp(
items: List<String>.generate(100, (index) => loremHeb.substring(1, 50 + rnd.nextInt(200))),
),
);
}
class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({Key? key, required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Overflow',
home: Scaffold(
appBar: AppBar(
title: const Text('Overflow'),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 0.0),
child: Row(
children: [
Expanded(
child: buildContent(context, items[index]),
),
],
),
);
},
),
),
);
}
}
Widget buildContent(BuildContext context, String text) {
return IntrinsicHeight(
child: Row(
children: [
AspectRatio(
aspectRatio: 1.0,
child: Container(color: Colors.pink),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildText(context, text),
],
),
),
),
],
),
);
}
Widget _buildText(BuildContext context, String text) {
return Container(
color: Colors.yellow,
child: Text(
'$text\n\n\n\n\n',
maxLines: 6,
overflow: TextOverflow.ellipsis,
),
);
}
The error: A RenderFlex overflowed by X pixels on the bottom.
What I'm trying to achieve here is a row, which its height is determined by the Text widget height (6 lines height).
It worth mentioning that the pink square on the left also shows weird behavior when using Hebrew text / font (its width should be fixed).
Any idea how to solve this?
Solution 1:[1]
Don't use aspect ratio for the pink container. Instead use fixed width and height.
I believe, this is what you're looking for.
class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({Key? key, required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Overflow',
home: Scaffold(
appBar: AppBar(
title: const Text('Overflow'),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return _Content(text: items[index]);
},
),
),
);
}
}
class _Content extends StatelessWidget {
final String text;
const _Content({Key? key, required this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
// calculating dimens of pink box, 30% of screen width. adjust it as you want.
var size = MediaQuery.of(context).size.width * 0.3;
return Padding(
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 0.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(color: Colors.pink, width: size, height: size),
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_buildText(context, text),
],
),
),
),
],
),
);
}
}
Widget _buildText(BuildContext context, String text) {
return Container(
color: Colors.yellow,
child: Text(
'$text\n\n\n\n\n',
maxLines: 6,
overflow: TextOverflow.ellipsis,
),
);
}
EDIT
If you want row height to be determined by Text, remove maxLines and overflow from Text widget. Also, there is no need to wrap the Text inside a Column
class _Content extends StatelessWidget {
final String text;
const _Content({Key? key, required this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
// calculating dimens of pink box, 30% of screen width. adjust it as you want.
var size = MediaQuery.of(context).size.width * 0.3;
return Padding(
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 0.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(color: Colors.pink, width: size, height: size),
SizedBox(width: 4), // to add space between text and pink box
Expanded(
child: Container(
color: Colors.yellow,
child: Text(text),
),
),
],
),
);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |


