Lors de la création d'un widget Texte avec une longue chaîne dans Flutter, il enveloppe son texte lorsqu'il est placé directement dans une colonne. Cependant, lorsqu'il se trouve à l'intérieur de Colonne-Ligne-Colonne, le texte déborde du côté de l'écran.
Comment encapsuler du texte dans une colonne-ligne-colonne? Et quelle est la raison de cette différence? Il me semblerait logique qu'un enfant de la colonne supérieure ait la même largeur? Pourquoi la largeur est-elle illimitée?
J'ai essayé de mettre le texte dans Expanded, Flexible, Container et FittedBox, basé sur d'autres réponses, mais cela conduit à de nouvelles erreurs que je ne comprends pas.
Exemple:
MaterialApp(
title: 'Text overflow',
home: Scaffold(
appBar: AppBar(title: Text("MyApp"),),
body: Column(
children: <Widget>[
Row(
children: <Widget>[
// The long text inside this column overflows. Remove the row and column above this comment and the text wraps.
Column(
children: <Widget>[
Text("Short text"),
Text("Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. ")
],
),
],
),
],
),
),
)
Row
et Column
sont Flex
widget et ne défilent pas, s'il n'y a pas assez de flottement d'espace, ce qui provoque une erreur de débordement.
Si cela se produit, un widget Expanded
ou Flexible
peut être utilisé pour encapsuler un texte long.
Dans le docs ce n'est pas clairement indiqué, mais au-delà de l'expansion pour remplir l'espace disponible dans l'axe principal, Expanded
et Flexible
s'enroule dans la direction transversale.
Une approche étape par étape peut aider à comprendre le problème.
Considérons d'abord ce scénario:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text overflow',
home: Scaffold(
appBar: AppBar(
title: Text("MyApp"),
),
body: Column(
children: List.generate(100, (idx) => Text("Short text"))
),
),
);
}
}
Il s'agit d'un widget de colonne qui déborde sur la direction verticale, comme l'indique clairement le flottement:
I/flutter ( 8390): The following message was thrown during layout:
I/flutter ( 8390): A RenderFlex overflowed by 997 pixels on the bottom.
I/flutter ( 8390):
I/flutter ( 8390): The overflowing RenderFlex has an orientation of Axis.vertical.
Maintenant, une ligne à l'intérieur d'une colonne:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text overflow',
home: Scaffold(
appBar: AppBar(title: Text("MyApp"),),
body: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(String.fromCharCodes(List.generate(100, (i) => 65)))
],
),
],
),
),
);
}
}
Maintenant, le problème de débordement apparaît sur le côté droit.
J'ai inséré une ligne dans une colonne juste pour ressembler à votre cas, mais le même problème se pose si vous utilisez un simple widget Row: Row
et Column
sont les deux Flex
widgets :
Considérez cette disposition, une rangée avec deux éléments, cousus ensemble
Column(
children: <Widget>[
Row(
children: <Widget>[Text('AAAA'), Text('ZZZZ')],
),
],
),
Maintenant, le premier élément Expanded
pour remplir tout l'espace disponible:
Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(child: Text('AAAA')),
Text('ZZZZ')],
),
],
),
Enfin, lorsque vous développez une chaîne très longue, vous remarquerez que le texte s'enroule dans le sens transversal:
Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(child: Text(String.fromCharCodes(List.generate(100, (i) => 65)))),
Text('ZZZZ')],
),
],
),
Vous devez envelopper le dernier Column
avec - Expanded
ou Flexible
widget.
De cette façon, Column
peut occuper l'espace disponible requis pour le texte.
body: Column(
children: <Widget>[
Row(
children: <Widget>[
// The long text inside this column overflows. Remove the row and column above this comment and the text wraps.
Expanded(
child: Column(
children: <Widget>[
Text("Short text"),
Text(
"Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. Very long text. ")
],
),
),
],
),
],
),
Pour éviter le débordement des textes en ligne ou en colonnes. Assurez-vous de placer le texte sous des widgets flexibles ou étendus. Après avoir enveloppé le texte sous l'un des widgets ci-dessus, il encapsulera le gros texte sur plusieurs lignes. Partager un exemple:
Avant le widget étendu:
return Center(child:
Container(
padding: EdgeInsets.only(left: 50, right: 50),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 200,
child: Text('It is a multiline text It does not auto warp the text.', textAlign: TextAlign.center,style: TextStyle(fontSize: 20.0, color: Colors.white)),
)
],
))
);
Capture d'écran :
Après avoir wappé à l'intérieur de Expanded:
return Center(
child: Padding(padding: EdgeInsets.only(left: 50, right: 50),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text('It is a multiline text It does not auto warp the text.', textAlign: TextAlign.center,style: TextStyle(fontSize: 20.0, color: Colors.white))),
],
),
)
);
Vous pouvez utiliser RichText
import 'package:flutter/gestures.Dart';
RichText(
text: TextSpan(
text: 'Hello ',
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' world!'),
],
),
)
RichText avec Détection de geste
RichText
(
text: TextSpan
(
style: TextStyle( color: Color(0xffaabbcc) ),
text: 'By clicking SIGNUP button you acknowledge that you have read our',
children: <TextSpan>
[
TextSpan
(
text: ' Privacy Policy', style: linkStyle(),
recognizer: TapGestureRecognizer() ..onTap = showPrivacyPolicy
),
TextSpan( text: ' and you agree to our' ),
TextSpan
(
text: ' Terms', style: linkStyle(),
recognizer: TapGestureRecognizer() ..onTap = showTerms
),
],
),
);
[~ # ~] résultat [~ # ~]