Flutter笔记:DefaultTextStyle和DefaultTextHeightBehavior解读

news2024/11/19 9:41:08
Flutter笔记
DefaultTextStyle和DefaultTextHeightBehavior解读

- 文章信息 - Author: 李俊才 (jcLee95)
Visit me at CSDN: https://jclee95.blog.csdn.net
My WebSitehttp://thispage.tech/
Email: 291148484@163.com.
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/138244339
HuaWei:https://bbs.huaweicloud.com/blogs/426427

【介绍】:本文将详细介绍DefaultTextStyle和DefaultTextHeightBehavior这两个类的功能、原理、用法以及设计思想,并提供一些应用示例,以帮助开发者更好地理解和使用这些工具来统一和管理 Flutter 应用中的文本表现。

flutter-ljc


1. 概述

DefaultTextStyleDefaultTextHeightBehavior 是 Flutter 中用于定义和继承文本样式和文本高度行为的两个重要类。这些类允许开发者在小部件树中设置默认的文本样式和行为,这些设置会被下面的 Text 小部件继承。

本文将详细介绍这两个类的功能、原理、用法以及设计思想,并提供一些应用示例,以帮助开发者更好地理解和使用这些工具来统一和管理 Flutter 应用中的文本表现。

2. DefaultTextStyle

2.1 功能

DefaultTextStyle 是一个继承小部件,用于定义整个小部件树中 Text 小部件的默认文本样式。当 Text 小部件在其构造函数中没有指定样式时,它会从其构建上下文中查找 DefaultTextStyle 并应用找到的样式。这使得开发者可以在小部件树的任何级别上设置默认的文本样式,而所有下级 Text 小部件都会自动继承这些样式,除非它们显式定义了自己的样式。

2.2 原理

2.2.1 继承机制

DefaultTextStyle 利用 Flutter 的继承机制来传递文本样式。它是一个 InheritedWidget,这意味着它可以将数据传递给它的子树中的小部件。当 Text 小部件需要确定其样式时,它会向上遍历小部件树,寻找最近的 DefaultTextStyle 从中继承样式。要了解 DefaultTextStyle 的原理,可以从其继承关系入手,如图所示展示了该类在Flutter框架层中的继承关系:

«abstract»
Widget
Widget()
«abstract»
ProxyWidget
ProxyWidget(Widget child)
«abstract»
InheritedWidget
InheritedWidget(Widget child)
bool updateShouldNotify(InheritedWidget oldWidget)
«abstract»
InheritedTheme
InheritedTheme(Widget child)
Widget wrap(BuildContext context, Widget child)
DefaultTextStyle
DefaultTextStyle(Widget child, TextStyle style)
  • Widget: 它是一个抽象的组件基类,定义了 Flutter UI 框架的基本结构和功能。所有 Flutter 小部件的基础。

  • ProxyWidget: 代理小部件,用于包装另一个小部件。它也是是一个抽象类,允许开发者在子小部件和父小部件之间插入额外的逻辑。

  • InheritedWidget: 用于在小部件树中有效地传递数据。它是一个抽象类,允许从父小部件到子小部件的数据继承,通常用于跨多个层级的状态或配置共享。

  • InheritedTheme:专门用于主题数据的继承。
    它是一个抽象类,允许主题数据在小部件树中传递,并提供 wrap 方法来将主题数据应用到子树中。

  • DefaultTextStyle:用于定义默认的文本样式,这些样式会被小部件树中的 Text 小部件继承。它继承自 InheritedTheme,使得文本样式可以作为主题的一部分在小部件树中传递和覆盖。

从上面的继承可以看到,DefaultTextStyle 是一个 InheritedWidget,这是 Flutter 中用于在小部件树中向下传递数据的一种机制。作为 InheritedWidgetDefaultTextStyle 允许在小部件树中的任何位置定义文本样式,而这些样式将自动应用到其子树中的所有 Text 小部件上,除非这些 Text 小部件指定了自己的显式样式。

这种继承机制的工作原理是,当 Text 小部件在构建过程中需要确定其样式时,它会向上遍历小部件树,寻找最近的 DefaultTextStyle 小部件,并从中继承样式。如果在树中找不到 DefaultTextStyle,则会使用 Flutter 的默认文本样式

这种机制极大地简化了文本样式的管理,特别是在大型应用中,可以在顶层定义一个 DefaultTextStyle,这样所有的文本小部件默认都会继承这些样式,除非特别指定了其他样式。这不仅保证了样式的一致性,还减少了重复代码的需要。

2.2.2 样式合并

DefaultTextStyle 提供了一个 merge 构造函数,允许开发者基于当前环境中的 DefaultTextStyle 创建一个新的 DefaultTextStyle,同时可以覆盖某些属性。这是通过合并现有的文本样式与新提供的文本样式属性来实现的,使得开发者可以在保留大部分默认样式的基础上进行细微调整。

在实际开发中,可能需要在某个特定的屏幕或组件中稍微调整文本的样式,而不影响全局的默认样式。使用 merge 方法可以实现这一点,例如,可能需要改变特定区域的字体大小或颜色。

merge 方法首先通过 DefaultTextStyle.of(context) 获取当前 BuildContext 中的 DefaultTextStyle。然后,它创建一个新的 DefaultTextStyle 实例,其中包含从父样式继承的属性,同时将任何非空的新属性值合并进来。

这里是 merge 方法的具体实现:

static Widget merge({
  Key? key,
  TextStyle? style,
  TextAlign? textAlign,
  bool? softWrap,
  TextOverflow? overflow,
  int? maxLines,
  TextWidthBasis? textWidthBasis,
  required Widget child,
}) {
  return Builder(
    builder: (BuildContext context) {
      final DefaultTextStyle parent = DefaultTextStyle.of(context);
      return DefaultTextStyle(
        key: key,
        style: parent.style.merge(style),
        textAlign: textAlign ?? parent.textAlign,
        softWrap: softWrap ?? parent.softWrap,
        overflow: overflow ?? parent.overflow,
        maxLines: maxLines ?? parent.maxLines,
        textWidthBasis: textWidthBasis ?? parent.textWidthBasis,
        child: child,
      );
    },
  );
}

merge 方法的工作原理如下:

  1. 继承现有样式:首先,它会从当前的 BuildContext 中获取最近的 DefaultTextStyle 实例,这个实例定义了当前文本样式的默认值。

  2. 合并新样式:然后,它将这个现有的样式与通过 merge 方法传入的新样式属性进行合并。这里的合并是指,对于每个样式属性,如果在新样式中明确指定了一个值(即非null),则使用新的值;如果新样式中该属性为null,则保留现有样式中的值。

  3. 应用结果:最终,这个合并后的样式将被应用到 DefaultTextStyle 小部件的子树中,从而影响所有未显式指定自己样式的 Text 小部件。

2.3 用法解析

DefaultTextStyle 可以在任何需要统一文本样式的场景中使用,例如设置整个应用或页面的基本字体样式、颜色、字体大小等。它特别适用于那些需要确保文本样式一致性的大型应用,通过在应用的顶层设置 DefaultTextStyle,可以确保所有子页面和组件都继承相同的基本样式。

  1. 全局文本样式设置

    在 Flutter 应用的根部(通常是在 MaterialAppCupertinoAppbuilder 属性中)设置 DefaultTextStyle,可以定义全应用通用的文本样式。这样,除非在子小部件中显式指定了不同的样式,否则所有的 Text 小部件都会继承这些样式。这种方法特别适用于那些需要确保文本样式一致性的大型应用。

const MaterialApp(
  home: DefaultTextStyle(
    style: TextStyle(color: Colors.black, fontSize: 20),
    child: HomeScreen(),
  ),
);
  1. 局部样式继承和覆盖

    在应用的某个特定部分,如一个特定的屏幕或组件中,可以使用 DefaultTextStyle 来继承并修改上层定义的样式。例如,在一个特定的页面中,你可能想要改变文本的颜色或字体大小,而不影响其他页面。通过使用 DefaultTextStyle.merge,可以在保留大部分样式的基础上进行这些调整。

DefaultTextStyle.merge(
  style: TextStyle(color: Colors.blue),
  child: Text("该文本将是蓝色的,其大小继承自父文本。"),
);
  1. 动态样式调整

    在需要根据应用状态或用户交互动态改变文本样式的场景中,DefaultTextStyle 同样非常有用。例如,可以在用户选择了一个主题偏好后,更新 DefaultTextStyle 来反映这一选择,从而改变整个应用中的文本样式。

setState(() {
  currentStyle = TextStyle(color: userPreferredColor);
});

return DefaultTextStyle(
  style: currentStyle,
  child: ChildWidget(),
);

通过这些方法,DefaultTextStyle 不仅提供了一种高效的方式来管理和继承文本样式,还极大地简化了在 Flutter 应用中实现一致性和可维护性的文本样式的过程。

2.4 设计思想

在深入了解了 DefaultTextStyle 的功能和工作原理后,我们可以从 Flutter 框架的设计层面来探讨其背后的设计思想。DefaultTextStyle 的设计主要目的是为了提供一种简便的方式来统一管理和继承文本样式,这样做有几个显著的优点:

  1. 减少重复代码:通过在小部件树的适当位置设置 DefaultTextStyle,可以确保所有子部件默认继承相同的样式,除非显式指定其他样式。这减少了在每个文本小部件中重复定义样式的需要,从而简化了代码的维护。

  2. 提高样式一致性:在应用的顶层或功能模块层设置统一的文本样式,可以保证整个应用或模块中文本的显示一致性。这对于保持品牌形象和用户界面的专业性至关重要。

  3. 易于调整和扩展:随着应用的发展,可能需要对文本样式进行调整以适应新的设计需求或用户偏好。DefaultTextStyle 的继承机制使得这些调整可以快速地在全局范围内实施,而不需要逐个修改每个文本小部件。

  4. 支持动态主题切换:Flutter 应用常常需要支持动态主题切换,如夜间模式或用户自定义主题。DefaultTextStyle 使得这种切换过程更加平滑,因为只需在顶层更改文本样式,就能影响到整个应用中的所有文本显示。

通过这些设计思想的实现,DefaultTextStyle 不仅提高了开发效率,还增强了应用的可维护性和用户体验。这种设计模式体现了 Flutter 框架对于“一次定义,到处使用”的原则,使得开发者可以更加专注于内容的创造,而不是样式的反复调整。

3. DefaultTextHeightBehavior

在实际开发中,DefaultTextStyle 使用得更为频繁,因为文本样式(如字体大小、颜色、字体等)是界面设计中经常需要调整和统一的属性。DefaultTextStyle 提供了一种方便的方式来设置和继承这些样式属性,使得开发者可以轻松地管理整个应用或特定部分的文本外观。

相比之下,DefaultTextHeightBehavior 的使用场景相对较少,这是因为文本的高度行为(如行间距和对齐方式)通常不需要频繁调整。然而,DefaultTextHeightBehavior 在处理复杂文本布局时仍然非常有用,尤其是当需要精细控制文本的行高、行间距或裁剪方式时。

例如,在创建一个具有丰富文本排版需求的阅读应用或文档编辑器时,DefaultTextHeightBehavior 可以帮助开发者统一设置文本的行为,如确保所有文本行的基线对齐或调整行间距以提高可读性。此外,如果应用需要支持多种语言,其中某些语言(如阿拉伯语或泰语)可能需要特定的文本高度行为设置以正确显示,DefaultTextHeightBehavior 就显得尤为重要。

3.1 DefaultTextHeightBehavior的功能

DefaultTextHeightBehavior 是一个专门用于控制文本高度行为的 Flutter 小部件。它的主要功能是为其子树中的 TextEditableText 小部件提供一个默认的 TextHeightBehavior。这个行为决定了文本的行高如何被计算,包括行间距和文本的对齐方式。

TextEditableText 小部件在其构造函数中没有显式指定 textHeightBehavior 时,它们会从其构建上下文中查找最近的 DefaultTextHeightBehavior 并应用找到的行为。如果在小部件树中找不到 DefaultTextHeightBehavior,则这些文本小部件将使用 Flutter 的默认行高行为。

此外,如果 DefaultTextStyle 小部件(它控制文本样式)也指定了 textHeightBehavior,并且位于 DefaultTextHeightBehavior 下方,则 Text 小部件将优先使用 DefaultTextStyle 中的 textHeightBehavior 而不是 DefaultTextHeightBehavior 中的设置。这提供了一种灵活的方式来精细控制文本的显示,特别是在复杂的布局中。

3.2 原理解析

3.2.1 继承机制

DefaultTextHeightBehavior 是一个继承小部件,类似于 DefaultTextStyle,它利用 Flutter 的继承机制来传递文本高度行为设置。作为一个 InheritedWidgetDefaultTextHeightBehavior 允许开发者在小部件树的任何位置定义文本的高度行为,这些设置会自动应用到其子树中的所有 TextEditableText 小部件上,除非这些小部件显式指定了自己的 textHeightBehavior

«abstract»
Widget
Widget()
«abstract»
ProxyWidget
ProxyWidget(Widget child)
«abstract»
InheritedWidget
InheritedWidget(Widget child)
bool updateShouldNotify(InheritedWidget oldWidget)
«abstract»
InheritedTheme
InheritedTheme(Widget child)
Widget wrap(BuildContext context, Widget child)
DefaultTextHeightBehavior
DefaultTextHeightBehavior(Widget child, TextHeightBehavior textHeightBehavior)

通过这种继承机制,DefaultTextHeightBehavior 提供了一种简便的方式来统一管理和继承文本的高度行为,从而简化了在 Flutter 应用中实现一致性和可维护性的文本显示的过程。

这种继承机制的工作原理是,当 TextEditableText 小部件在构建过程中需要确定其高度行为时,它会向上遍历小部件树,寻找最近的 DefaultTextHeightBehavior 小部件,并从中继承 textHeightBehavior。如果在树中找不到 DefaultTextHeightBehavior,则这些文本小部件将使用 Flutter 的默认行高行为。

通过这种机制,DefaultTextHeightBehavior 提供了一种简便的方式来统一管理和继承文本的高度行为,从而简化了在 Flutter 应用中实现一致性和可维护性的文本显示的过程。

3.2.2 行为覆盖

在 Flutter 的布局和继承机制中,DefaultTextHeightBehaviorDefaultTextStyle 都提供了对文本行为的控制。然而,当这两者在小部件树中同时存在时,可能会出现需要确定优先级的情况。

具体来说,如果在 DefaultTextHeightBehavior 下方的小部件树中存在一个 DefaultTextStyle,并且这个 DefaultTextStyle 实例定义了一个非空的 textHeightBehavior,那么在这个范围内的 TextEditableText 小部件将优先使用 DefaultTextStyle 中定义的 textHeightBehavior,而不是从 DefaultTextHeightBehavior 中继承的行为。

这种行为覆盖机制允许更精细的控制文本显示的行为,尤其是在复杂的布局中,开发者可能需要在某些特定区域内调整文本的行高行为,而不影响全局的设置。例如,在一个具有密集文本的新闻阅读应用界面中,可能希望摘要部分的文本行高不同于正文内容,以便提高阅读的舒适度和效率。

通过这种方式,Flutter 提供了一种灵活而强大的方法来处理文本显示的细节,使得开发者可以根据具体的界面需求和设计标准,调整和优化用户的阅读体验。

3.3 用法解析

DefaultTextHeightBehavior 的使用主要集中在需要精确控制文本行高和行为的场景中。这个小部件通过提供一个统一的行为设置,使得开发者可以在整个应用或特定部分的文本显示中实现一致的行高和对齐方式。以下是一些具体的使用场景和方法:

3.3.1 全局设置

在应用的顶层设置 DefaultTextHeightBehavior 可以确保所有下层的 TextEditableText 小部件继承相同的文本高度行为。这种方法适用于需要全局统一文本行为的应用,如电子书阅读器或文档编辑器,其中文本的一致性和可读性至关重要。

DefaultTextHeightBehavior(
  // 定义文本的高度行为,不应用高度到第一个上升和最后一个下降
  textHeightBehavior: TextHeightBehavior(
    applyHeightToFirstAscent: false, // 不应用高度到第一个上升
    applyHeightToLastDescent: false  // 不应用高度到最后一个下降
  ),
  child: MaterialApp(
    home: HomeScreen(),
  ),
);

3.3.2 局部覆盖

在特定页面或组件中,可以使用 DefaultTextHeightBehavior 来覆盖上层设置的行为,或为该部分的文本提供特定的行为。这种方法适用于某些页面或组件需要与全局设置不同的文本行为的情况。

DefaultTextHeightBehavior(
  // 定义文本的高度行为
  textHeightBehavior: TextHeightBehavior(
    applyHeightToFirstAscent: true, // 将高度应用于第一个上升
    applyHeightToLastDescent: true  // 将高度应用于最后一个下降
  ),
  // 包裹一个列布局,包含子组件
  child: Column(
    children: [
      Text("该文本遵循特定的高度行为。"), // 显示一个文本部件
      // 其他部件
    ],
  ),
);

3.3.3 动态调整

在应用运行时,根据用户的选择或其他条件动态调整文本的高度行为。例如,用户可以选择不同的阅读模式,每种模式下的文本行高和对齐方式可能不同。通过在状态更改时更新 DefaultTextHeightBehavior,可以实现这种动态调整。

setState(() {
  // 从用户首选项中获取应用的文本高度行为并更新当前文本高度行为
  currentTextHeightBehavior = TextHeightBehavior(
    applyHeightToFirstAscent: userPreference.applyHeightToFirstAscent, // 应用高度到第一个上升
    applyHeightToLastDescent: userPreference.applyHeightToLastDescent  // 应用高度到最后一个下降
  );
});

return DefaultTextHeightBehavior(
  textHeightBehavior: currentTextHeightBehavior, // 设置文本的高度行为
  child: ChildWidget(), // 返回包含子部件的小部件
);

通过这些使用方法,DefaultTextHeightBehavior 提供了一种灵活而强大的方式来控制文本的高度行为,使得开发者可以根据具体的需求和设计标准,优化用户的阅读体验和界面的视觉表现。

4. 更多应用示例

4.1 统一应用主题

在 Flutter 应用开发中,确保整个应用具有统一的文本样式和文本高度行为不仅有助于保持界面的一致性,还能提升用户的使用体验。通过在应用的根部设置 DefaultTextStyleDefaultTextHeightBehavior,我们可以确保所有的页面和组件都能继承相同的文本样式和行为,从而避免在每个单独的页面或组件中重复设置样式。现在我们来看一个比较完整性的例子。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '统一主题示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const DefaultTextStyle(
        // 设置默认的文本样式
        style: TextStyle(
          fontSize: 20,
          color: Colors.black,
          fontFamily: 'Georgia',
        ),
        // 设置默认的文本高度行为
        child: DefaultTextHeightBehavior(
          textHeightBehavior: TextHeightBehavior(
            applyHeightToFirstAscent: true,
            applyHeightToLastDescent: true,
          ),
          child: MyHomePage(title: '文本样式案例'),
        ),
      ),
    );
  }
}

可以看到,上面的代码中,MyHomePage被包裹在DefaultTextStyleDefaultTextHeightBehavior中间,分别设置了默认的文本样式和默认的文本高度行为,下面是MyHomePage类的实现。

class MyHomePage extends StatelessWidget {
  final String title;

  const MyHomePage({super.key, required this.title});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '你好,世界!',
              style: TextStyle(
                fontSize: 24, // 这里的样式会覆盖 DefaultTextStyle 中的样式
                color: Colors.red,
              ),
            ),
            Text(
              '这是一个示例文本。',
            ),
            Text(
              '这些文本将继承应用的默认样式。',
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们首先在 MyApp 类中设置了 DefaultTextStyleDefaultTextHeightBehavior。这两个设置被放置在 MaterialApphome 属性中,确保它们能够影响到整个应用中的所有页面和组件。

  • DefaultTextStyle 设置了全局的文本样式,如字体大小、颜色和字体家族。

  • DefaultTextHeightBehavior 设置了文本的高度行为,如是否应用高度到第一行的上升和最后一行的下降。

代码的运行效果如图所示。
在这里插入图片描述

任何在这之后创建的 Text 组件,如果没有指定自己的样式,都会继承这些默认设置。这样,我们就可以很容易地管理和维护整个应用的文本显示风格,确保风格的统一性。

4.2 特定页面的样式调整

在 Flutter 应用中,虽然我们可以在全局层面设置统一的文本样式,但有时候我们需要在特定页面上调整文本样式以满足特定的设计需求,而不影响全局的文本样式设置。这时,DefaultTextStyle.merge 方法就显得非常有用。

DefaultTextStyle.merge 允许我们在继承全局文本样式的基础上,对特定页面的文本样式进行调整。这种方法的优点是可以保留大部分全局样式的同时,只修改需要改变的部分。

以下是一个使用 DefaultTextStyle.merge 调整特定页面文本样式的示例:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        textTheme: const TextTheme(
          bodyMedium: TextStyle(color: Colors.black, fontSize: 16),
        ),
      ),
      home: const SpecificPage(),
    );
  }
}

class SpecificPage extends StatelessWidget {
  const SpecificPage({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("特定页面"),
      ),
      body: DefaultTextStyle.merge(
        style: const TextStyle(color: Colors.red, fontSize: 24), // 覆盖全局颜色和字体大小
        child: const Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("这是特定页面的标题,红色,24号字体"),
            Text("这段文本继承了全局样式,但字体颜色和大小被覆盖"),
            Text("继续保持特定页面的样式设置"),
          ],
        ),
      ),
    );
  }
}

在这个例子中,SpecificPage 使用 DefaultTextStyle.merge 来调整页面内所有文本的颜色和字体大小。这样做的好处是,即使全局样式发生变化,这个页面的特定样式也不会受到影响,从而确保了设计的一致性和专业性。代码运行后的效果如图所示:

在这里插入图片描述

在这个例子中,SpecificPage 使用 DefaultTextStyle.merge 来调整页面内所有文本的颜色和字体大小。这样做的好处是,即使全局样式发生变化,这个页面的特定样式也不会受到影响,从而确保了设计的一致性和专业性。

5. 结论

DefaultTextStyleDefaultTextHeightBehavior 提供了强大的工具来统一和继承文本样式和文本高度行为,使得 Flutter 应用的开发更加模块化和可管理。通过这些工具,开发者可以更容易地维护和更新应用的视觉表现,确保文本的一致性和可读性。

最后,发笔记纯当交个朋友。Flutter早年在相对冷门。近两年卖课的越来越多,目前有一些人的课可能还不如来翻一下我的笔记。

F. 附录

F.1 DefaultTextStyle类源码

/// 用于应用于没有显式样式的后代 [Text] 小部件的文本样式。
///
/// ```dart
///   /// 这个示例展示了如何使用 [DefaultTextStyle.merge] 创建一个默认文本样式,
///   /// 该样式继承当前默认文本样式的样式信息并覆盖一些属性。
///   /// 
///   /// ** 请参见示例代码 examples/api/lib/widgets/text/text.0.dart **
/// ```
///
/// 另请参阅:
///
///  * [AnimatedDefaultTextStyle],它可以在给定的持续时间内平滑地动画变化的文本样式。
///  * [DefaultTextStyleTransition],它接受一个提供的 [Animation],可以在一段时间内平滑地动画文本样式的变化。
class DefaultTextStyle extends InheritedTheme {
  /// 为给定的子树创建默认文本样式。
  ///
  /// 考虑使用 [DefaultTextStyle.merge] 来继承给定 [BuildContext] 的当前默认文本样式的样式信息。
  ///
  /// [maxLines] 属性可能为空(实际上默认为空),但如果它不为空,则必须大于零。
  const DefaultTextStyle({
    super.key,
    required this.style,
    this.textAlign,
    this.softWrap = true,
    this.overflow = TextOverflow.clip,
    this.maxLines,
    this.textWidthBasis = TextWidthBasis.parent,
    this.textHeightBehavior,
    required super.child,
  }) : assert(maxLines == null || maxLines > 0);

  /// 提供回退值的可常量构造的默认文本样式。
  ///
  /// 当给定的 [BuildContext] 没有封闭的默认文本样式时,从 [of] 返回。
  ///
  /// 此构造函数创建一个带有无效 [child] 的 [DefaultTextStyle],这意味着构造的值不能合并到树中。
  const DefaultTextStyle.fallback({ super.key })
    : style = const TextStyle(),
      textAlign = null,
      softWrap = true,
      maxLines = null,
      overflow = TextOverflow.clip,
      textWidthBasis = TextWidthBasis.parent,
      textHeightBehavior = null,
      super(child: const _NullWidget());

  /// 创建一个默认文本样式,覆盖小部件树中此处的文本样式。
  ///
  /// 给定的[style]与插入小部件的[BuildContext]中的默认文本样式合并,
  /// 并且任何其他参数(不为null)都将替换该默认文本样式上的相应属性。
  ///
  /// 此构造函数不能用于覆盖祖先的[maxLines]属性,该属性的值为null,因为此处的null表示“推迟到祖先”。
  /// 若要将祖先的非null[maxLines]替换为null值(以移除对行数的限制),请手动使用[DefaultTextStyle.of]获取环境[DefaultTextStyle],
  /// 然后直接使用[DefaultTextStyle.new]构造函数创建一个新的[DefaultTextStyle]。
  /// 请参阅下面的源代码示例,了解如何执行此操作(因为这基本上就是此构造函数的作用)。
  static Widget merge({
    Key? key,
    TextStyle? style,
    TextAlign? textAlign,
    bool? softWrap,
    TextOverflow? overflow,
    int? maxLines,
    TextWidthBasis? textWidthBasis,
    required Widget child,
  }) {
    return Builder(
      builder: (BuildContext context) {
        final DefaultTextStyle parent = DefaultTextStyle.of(context);
        return DefaultTextStyle(
          key: key,
          style: parent.style.merge(style),
          textAlign: textAlign ?? parent.textAlign,
          softWrap: softWrap ?? parent.softWrap,
          overflow: overflow ?? parent.overflow,
          maxLines: maxLines ?? parent.maxLines,
          textWidthBasis: textWidthBasis ?? parent.textWidthBasis,
          child: child,
        );
      },
    );
  }
  /// 要应用的文本样式。
  final TextStyle style; 

  /// 文本小部件中每行文本应如何在水平方向上对齐。
  final TextAlign? textAlign; 

  /// 文本是否应在软换行处中断。
  ///
  /// 如果为false,则文本中的字形将被定位,就好像有无限的水平空间一样。
  ///
  /// 这也决定了[overflow]属性的行为。如果这是true或null,
  /// 导致溢出的字形以及随后的字形将不会被呈现。
  final bool softWrap; 

  /// 应如何处理视觉溢出。
  ///
  /// 如果[softWrap]为true或null,则导致溢出的字形以及随后的字形将不会被呈现。
  /// 否则,将以给定的溢出选项显示。
  final TextOverflow overflow; 

  /// 文本跨度的可选最大行数,必要时进行换行。
  /// 如果文本超出给定行数,将根据[overflow]进行截断。
  ///
  /// 如果为1,则文本不会换行。否则,文本将在框的边缘处换行。
  ///
  /// 如果这是非null的,则即使是[Text.maxLines]的显式null值也会被覆盖。
  final int? maxLines;

  /// 计算文本宽度时要使用的策略。
  ///
  /// 可能的值及其含义,请参阅[TextWidthBasis]。
  final TextWidthBasis textWidthBasis;

  /// {@macro dart.ui.textHeightBehavior}
  final ui.TextHeightBehavior? textHeightBehavior;

  /// 包围给定上下文的最近的此类实例。
  ///
  /// 如果不存在这样的实例,则返回由[DefaultTextStyle.fallback]创建的实例,其中包含回退值。
  ///
  /// 典型用法如下:
  ///
  /// ```dart
  /// DefaultTextStyle style = DefaultTextStyle.of(context);
  /// ```
  static DefaultTextStyle of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<DefaultTextStyle>() ?? const DefaultTextStyle.fallback();
  }

  
  bool updateShouldNotify(DefaultTextStyle oldWidget) {
    return style != oldWidget.style ||
        textAlign != oldWidget.textAlign ||
        softWrap != oldWidget.softWrap ||
        overflow != oldWidget.overflow ||
        maxLines != oldWidget.maxLines ||
        textWidthBasis != oldWidget.textWidthBasis ||
        textHeightBehavior != oldWidget.textHeightBehavior;
  }

  
  Widget wrap(BuildContext context, Widget child) {
    return DefaultTextStyle(
      style: style,
      textAlign: textAlign,
      softWrap: softWrap,
      overflow: overflow,
      maxLines: maxLines,
      textWidthBasis: textWidthBasis,
      textHeightBehavior: textHeightBehavior,
      child: child,
    );
  }

  
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    style.debugFillProperties(properties);
    properties.add(EnumProperty<TextAlign>('textAlign', textAlign, defaultValue: null));
    properties.add(FlagProperty('softWrap', value: softWrap, ifTrue: 'wrapping at box width', ifFalse: 'no wrapping except at line break characters', showName: true));
    properties.add(EnumProperty<TextOverflow>('overflow', overflow, defaultValue: null));
    properties.add(IntProperty('maxLines', maxLines, defaultValue: null));
    properties.add(EnumProperty<TextWidthBasis>('textWidthBasis', textWidthBasis, defaultValue: TextWidthBasis.parent));
    properties.add(DiagnosticsProperty<ui.TextHeightBehavior>('textHeightBehavior', textHeightBehavior, defaultValue: null));
  }
}

F.1 DefaultTextHeightBehavior类源码

/// 将应用于未明确设置 [Text.textHeightBehavior] 的后代 [Text] 和 [EditableText] 小部件的 [TextHeightBehavior]。
///
/// 如果此小部件下方存在具有非空 [DefaultTextStyle.textHeightBehavior] 的 [DefaultTextStyle],
/// 则将使用 [DefaultTextStyle.textHeightBehavior] 而不是此小部件的 [TextHeightBehavior]。
///
/// 另请参阅:
///
///  * [DefaultTextStyle],它定义了要应用于后代 [Text] 小部件的 [TextStyle]。
class DefaultTextHeightBehavior extends InheritedTheme {
  /// 为给定的子树创建默认文本高度行为。
  const DefaultTextHeightBehavior({
    super.key,
    required this.textHeightBehavior,
    required super.child,
  });

  /// {@macro dart.ui.textHeightBehavior}
  final TextHeightBehavior textHeightBehavior;

  /// 包围给定上下文的最接近的 [DefaultTextHeightBehavior] 实例,如果找不到则为 null。
  ///
  /// 如果不存在这样的实例,则此方法将返回 `null`。
  ///
  /// 调用此方法将在 [context] 中创建对最近的 [DefaultTextHeightBehavior] 的依赖,如果存在。
  ///
  /// 典型用法如下:
  ///
  /// ```dart
  /// TextHeightBehavior? defaultTextHeightBehavior = DefaultTextHeightBehavior.of(context);
  /// ```
  ///
  /// See also:
  ///
  /// * [DefaultTextHeightBehavior.maybeOf], which is similar to this method,
  ///   but asserts if no [DefaultTextHeightBehavior] ancestor is found.
  static TextHeightBehavior? maybeOf(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<DefaultTextHeightBehavior>()?.textHeightBehavior;
  }
  /// 包围给定上下文的最接近的 [DefaultTextHeightBehavior] 实例。
  ///
  /// 如果不存在这样的实例,则此方法在调试模式下会断言,并在发布模式下抛出异常。
  ///
  /// 典型用法如下:
  ///
  /// ```dart
  /// TextHeightBehavior defaultTextHeightBehavior = DefaultTextHeightBehavior.of(context);
  /// ```
  ///
  /// 调用此方法将在 [context] 中创建对最近的 [DefaultTextHeightBehavior] 的依赖。
  ///
  /// 另请参阅:
  ///
  /// * [DefaultTextHeightBehavior.maybeOf],类似于此方法,但如果找不到 [DefaultTextHeightBehavior] 祖先,则返回 null。
  static TextHeightBehavior of(BuildContext context) {
    final TextHeightBehavior? behavior = maybeOf(context);
    assert(() {
      if (behavior == null) {
        throw FlutterError(
          'DefaultTextHeightBehavior.of() was called with a context that does not contain a '
          'DefaultTextHeightBehavior widget.\n'
          'No DefaultTextHeightBehavior widget ancestor could be found starting from the '
          'context that was passed to DefaultTextHeightBehavior.of(). This can happen '
          'because you are using a widget that looks for a DefaultTextHeightBehavior '
          'ancestor, but no such ancestor exists.\n'
          'The context used was:\n'
          '  $context',
        );
      }
      return true;
    }());
    return behavior!;
  }

  
  bool updateShouldNotify(DefaultTextHeightBehavior oldWidget) {
    return textHeightBehavior != oldWidget.textHeightBehavior;
  }

  
  Widget wrap(BuildContext context, Widget child) {
    return DefaultTextHeightBehavior(
      textHeightBehavior: textHeightBehavior,
      child: child,
    );
  }

  
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<ui.TextHeightBehavior>('textHeightBehavior', textHeightBehavior, defaultValue: null));
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1629453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(树莓派4b下使用sqlite3)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 嵌入式设备下面&#xff0c;有的时候也要对数据进行处理和保存。如果处理的数据不是很多&#xff0c;一般用json就可以。但是数据如果量比较大&…

GPT学术优化推荐(gpt_academic )

GPT学术优化 (GPT Academic):支持一键润色、一键中英互译、一键代码解释、chat分析报告生成、PDF论文全文翻译功能、互联网信息聚合GPT等等 ChatGPT/GLM提供图形交互界面&#xff0c;特别优化论文阅读/润色/写作体验&#xff0c;模块化设计&#xff0c;支持自定义快捷按钮&…

算法学习笔记Day9——动态规划基础篇

一、介绍 本文解决几个问题&#xff1a;动态规划是什么&#xff1f;解决动态规划问题有什么技巧&#xff1f;如何学习动态规划&#xff1f; 1. 动态规划问题的一般形式就是求最值。动态规划其实是运筹学的一种最优化方法&#xff0c;只不过在计算机问题上应用比较多&#xff…

【vscode】2024最新!vscode云端配置同步方案:code settings sync

小tian最近对电脑进行了系统重装&#xff0c;结果vscode相关配置和插件都没有保存记录&#xff0c;还好公司电脑里还有。痛定思痛&#xff0c;决定写一篇vscode云端同步配置方案&#xff0c;以作记录和分享~ 步骤一&#xff1a;安装vscode插件&#xff1a;code settings sync …

根据标签最大层面ROI提取原始图像区域

今天要实现的任务是提取肿瘤的感兴趣区域。 有两个文件&#xff0c;一个是nii的原始图像文件&#xff0c;一个是nii的标签文件。 我们要实现的是&#xff1a;在标签文件上选出最大层面&#xff0c;然后把最大层面的ROI映射到原始图像区域&#xff0c;在原始图像上提裁剪出ROI…

CSS3(响应式布局)

#过渡# 属性连写&#xff1a; transition: width 2s linear 1s; //前一个时间用于表示过渡效果持续时间&#xff0c;后一个时间用于表示过渡效果的延迟。 #转换# #2D转换# 和 #3D转换# 注意&#xff1a;其中angle对应单位为&#xff1a;deg #圆角# #边框# …

基于区间预测的调度方法

《基于区间预测的光伏发电与蓄电池优化调度方法》 为了应对县级市光伏发电与用电需求之间的最优调度问题&#xff0c;提出一种面向蓄电池和光伏发电机的区间预测调度优化方法。该方法分别对发电功率调度、充电/放电功率调度和荷电状态调度进行决策从而获得最优调度的精确范围。…

ReactJS中使用TypeScript

TypeScript TypeScript 实际上就是具有强类型的 JavaScript&#xff0c;可以对类型进行强校验&#xff0c;好处是代码阅读起来比较清晰&#xff0c;代码类型出现问题时&#xff0c;在编译时就可以发现&#xff0c;而不会在运行时由于类型的错误而导致报错。但是&#xff0c;从…

区块链与Web3.0:区块链项目的推广

数字信息时代&#xff0c;一场革命正在酝酿中&#xff0c;那就是区块链与Web3.0的结合。这种结合将会改变我们对于信息传输、存储和使用的方式&#xff0c;并有可能推动媒体行业向新的高度发展。这种转变不仅关系到我们如何获取和使用信息&#xff0c;也涉及到如何用创新的方式…

以太网LAN双向透明传输CH9120透传芯片实现以太网转232串口转485转TTL串口

网络串口透传芯片 CH9120 1、概述 CH9120 是一款网络串口透传芯片。CH9120 内部集成 TCP/IP 协议栈&#xff0c;可实现网络数据包和串口数据的双向透明传输&#xff0c;具有 TCP CLIENT、TCP SERVER、UDP CLIENT 、UDP SERVER 4 种工作模式&#xff0c;串口波特率最高可支持到…

java-springmvc 01 补充 javaweb 三大组件(源码都是tomcat8.5项目中的)

01.JavaWeb三大组件指的是&#xff1a;Servlet、Filter、Listener,三者提供不同的功能 这三个在springmvc 运用很多 Servlet 01.Servlet接口&#xff1a; public interface Servlet {/*** 初始化方法* 实例化servlet之后&#xff0c;该方法仅调用一次 * init方法必须执行完…

vue如何发送请求给后端(包括前后端跨域)

目录 有哪些方法可以发送请求要请求先解决跨域问题代理服务器后端解决跨域问题 axios发送请求vue-resource发送请求 有哪些方法可以发送请求 以前可能了解过&#xff1a; xhr 即&#xff1a;new XMLHttpRequest()jQuery 即&#xff1a;$.get $.postaxios fetch 在vue中特有的…

27.统一网关Gateway-路由断言工厂

在配置文件中写的断言规则只是字符串&#xff0c;这些字符串会被Predicate Factory读取并处理&#xff0c;转变为路由判断的条件。 例如&#xff1a;Path /user/** 是按照路劲匹配&#xff0c;这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRouteP…

数据库锁介绍

数据库锁是一种同步机制&#xff0c;用于控制多个事务对共享资源的访问&#xff0c;防止并发操作造成的数据不一致。在数据库中&#xff0c;锁通常分为两种基本类型&#xff1a;排他锁&#xff08;Exclusive Locks&#xff09;和共享锁&#xff08;Shared Locks&#xff09;。排…

PotatoPie 4.0 实验教程(22) —— FPGA实现摄像头图像对数(log)变换

什么是图像的log变换&#xff1f; 总的来说&#xff0c;对数变换是一种常用的图像增强技术&#xff0c;可以改善图像的视觉质量、减少噪声以及突出图像中的细节&#xff0c;从而提高图像在视觉感知和分析中的效果和可用性。 图像的对数变换&#xff08;log transformation&am…

xLua详解

目录 环境准备xLua导入 C#调用LuaLua解析器Lua文件加载重定向Lua解析管理器全局变量的获取全局函数的获取List和Dictionary映射table类映射table接口映射tableLuaTable映射table Lua调用C#准备工作Lua使用C#类Lua调用C#枚举Lua使用C# 数组 List 字典数组List字典 Lua使用C#扩展…

锂电池SOH预测 | 基于CNN-GRU的锂电池SOH预测(matlab)

锂电池SOH预测 锂电池SOH预测完整代码锂电池SOH预测 锂电池的SOH(状态健康度)预测是一项重要的任务,它可以帮助确定电池的健康状况和剩余寿命,从而优化电池的使用和维护策略。 SOH预测可以通过多种方法实现,其中一些常用的方法包括: 容量衰减法:通过监测电池的容量衰减…

图像处理ASIC设计方法 笔记19 连通域标记ASIC系统设计

目录 核心的模块有:标记ASIC的工作流程如下:该芯片的系统结构具有如下特点:P131 第6章 连通域标记与轮廓跟踪 本章节讲述了多值分割图像连通域标记芯片的系统设计 多值分割图像连通域标记芯片(以下简称"标记芯片",也称"标记 ASIC"),完成图像连通域标…

PotatoPie 4.0 实验教程(27) —— FPGA实现摄像头图像拉普拉斯边缘提取

拉普拉斯边缘提取有什么作用&#xff1f; 拉普拉斯边缘检测是一种常用的图像处理技术&#xff0c;用于检测图像中的边缘和边界。它的主要作用包括&#xff1a; 边缘检测&#xff1a;拉普拉斯算子可以帮助检测图像中的边缘&#xff0c;即图像中亮度快速变化的位置。这些边缘通常…

MAC有没有免费NTFS tuxera激活码 tuxera破解 tuxera for mac2023序列号直装版 ntfs formac教程

Tuxera NTFS 2023破解版是一款非常好用的在线磁盘读写工具&#xff0c;该软件允许mac用户在Windows NTFS格式的硬盘上进行读写操作&#xff0c;Mac的文件系统是HFS&#xff0c;而Windows则使用NTFS格式&#xff0c;这导致在Mac系统上不能直接读写Windows格式的硬盘。然而&#…