Flutter: 没有找到Directionality小部件

6

在运行Android Studio中的Flutter代码时,我遇到了以下异常。

I/flutter ( 5360): ══╡ WIDGETS LIBRARY捕获的异常 ╞═══════════════════════════════════════════════════════════ I/flutter ( 5360): 构建“xyz”文本时出现以下断言错误: I/flutter ( 5360): 找不到方向性小部件。 I/flutter ( 5360): RichText小部件需要Directionality小部件祖先。 I/flutter ( 5360): 未能找到Directionality祖先的特定小部件是: I/flutter ( 5360): RichText(softWrap: 在框宽处换行,maxLines:无限制,text:“xyz”) I/flutter ( 5360):受影响的小部件的所有权链是: I/flutter ( 5360): RichText ← Text ← Center ← Container ←[root] I/flutter ( 5360): 通常,Directionality小部件由MaterialApp或WidgetsApp小部件引入到应用程序小部件树的顶部。它决定环境阅读方向,并且用于 I/flutter ( 5360): 确定如何布置文本,如何解释“start”和“end”值,以及解决I/flutter ( 5360): EdgeInsetsDirectional、AlignmentDirectional和其他* Directional对象。

代码片段:

import 'package:flutter/material.dart';

void main() {
  runApp(
    Container(child: Center(child: Text("xyz"))),
  );
}

我不确定为什么这个异常会这样说:

I/flutter ( 5360): 通常,Directionality widget是由MaterialApp或WidgetsApp widget在...引入的

因为在Flutter中所有东西都是widget,所以任何widget都应该对我们起作用。

5个回答

16

如果您正在使用像ScaffoldMaterial这样的材料小部件组件,您不需要在Text小部件中指定textDirection,因为在这些情况下会隐含地提供Directionality。因此,一个好的解决方案是使用:

Scaffold(body: Text("xyz"))

但如果您不使用它,您将不得不

Text(
    'xyz',
    textDirection: TextDirection.ltr, 
)

5
如果您使用Directionality构造函数,您的问题将得到解决。
Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Container(
        color: myColor,
        child: Center(
          child: RaisedButton(
            onPressed: () {
              print('You pressed me');
              changeColor();
            },
            child: Text('Click', textDirection: TextDirection.ltr)
          ),
        ),
      ),
    );
  }

4

文本小部件需要知道它是否应该从左到右或从右到左显示文本,没有默认值。这个信息可以通过以下两种方式提供:

  • 将其嵌套在 Directionality 小部件中(如错误消息中所述,通常是 MaterialAppWidgetsApp
  • 作为构造函数的参数明确指定:
Text(
    'Hello World',
    textDirection: TextDirection.ltr,
)

显然,第二种方法从长远来看是无法管理的。


2

虽然晚了,但希望能够有所帮助。我没有使用任何预定义的根widget。因此,在main函数中,我将我的App包装在Directionality widget中,这样Flutter就不会再抱怨了:

我的代码:

void main() {
  runApp(
    new Directionality(textDirection: TextDirection.ltr, child: MyApp())
    );
}

0

稍微详细解释一下内部发生的事情。

当使用 Text widget 时没有指定样式,它会自动尝试从父级继承样式。以下是 Text Widget 的 build 方法的前几行。

  @override
  Widget build(BuildContext context) {
    final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
    TextStyle? effectiveTextStyle = style;
    if (style == null || style!.inherit)
      effectiveTextStyle = defaultTextStyle.style.merge(style);
    if (MediaQuery.boldTextOverride(context))
      effectiveTextStyle = effectiveTextStyle!.merge(const TextStyle(fontWeight: FontWeight.bold));

看一下这行代码 - final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);

如果在 Text Widget 出现之前,Widget 树中使用了 Material Widget,它们已经设置了默认文本样式,Text Widget 会自动从 Build Context 继承。如果在 Text 之前没有使用任何 Material Widget,则需要显式指定文本样式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接