Flutter笔记:DefaultTextStyle和DefaultTextHeightBehavior解读

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.mzph.cn/web/5561.shtml

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

相关文章

Unity涂鸦纹理实现

文章目录 前言实现过程UV坐标和UI坐标对齐修改像素代码 前言 心血来潮实现下场景中提供一张纹理进行涂鸦的功能。 最终实现效果: 实现过程 UV坐标和UI坐标对齐 这里的纹理使用了UGUI的Canvas进行显示&#xff0c;所以这里使用一张RawImage。 因为Unity的视口坐标是以左下角…

Postgresql源码(127)投影ExecProject的表达式执行分析

无论是投影还是别的计算&#xff0c;表达式执行的入口和计算逻辑都是统一的&#xff0c;这里已投影为分析表达式执行的流程。 1 投影函数 用例 create table t1(i int primary key, j int, k int); insert into t1 select i, i % 10, i % 100 from generate_series(1,1000000…

STM32利用硬件I2C读取MPU6050陀螺仪数据

有了前面的基本配置&#xff0c;这节读取MPU6050的数据还算是简单&#xff0c;主要就是初始化时给MPU6050一些配置&#xff0c;取消睡眠模式&#xff0c;MPU6050开机是默认睡眠模式的&#xff0c;读写无效&#xff0c;所以上来就要先更改配置&#xff1a; MPU6050寄存器初始化…

Transformer算法组件详解

自2017年Google推出Transformer以来&#xff0c;基于其架构的语言模型便如雨后春笋般涌现&#xff0c;其中Bert、T5等备受瞩目&#xff0c;而近期风靡全球的大模型ChatGPT和LLaMa更是大放异彩。网络上关于Transformer的解析文章非常大。 前言 Transformer是谷歌在2017年的论文…

【webrtc】MessageHandler 7: 基于线程的消息处理:切换main线程向observer发出通知

以当前线程作为main线程 RemoteAudioSource 作为一个handler 仅实现一个退出清理的功能 首先on message的处理会切换到main 线程 :main_thread_其次,这里在main 线程对sink_ 做清理再次,在main 线程做出状态改变,并能通知给所有的observer 做出on changed 行为。对接mediac…

AC+AP三层组网实验(华为)

一&#xff0c;技术简介 APAC架构是一种常见的无线局域网&#xff08;WLAN&#xff09;组网方式&#xff0c;主要由接入点&#xff08;Access Point&#xff0c;简称AP&#xff09;和接入控制器&#xff08;Access Controller&#xff0c;简称AC&#xff09;组成。 在APAC架构…

AI大模型系列:自然语言处理,从规则到统计的演变

AI大模型系列文章目录 文明基石&#xff0c;文字与数字的起源与演变自然语言处理&#xff0c;从规则到统计的演变AI魔法师&#xff0c;提示工程的力量 自然语言处理&#xff0c;从规则到统计的演变 自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&…

前端 CSS

目录 选择器 复合选择器 伪类-超链接 结构伪装选择器 伪元素选择器 画盒子 字体属性 CSS三大属性 Emmet写法 背景属性 显示模式 盒子模型 盒子模型-组成 盒子模型-向外溢出 盒子模型-圆角 盒子模型-阴影 flex position定位 CSS小精灵 字体图标 垂直对齐方式…

数据库(MySQL)—— DML语句

数据库&#xff08;MySQL&#xff09;—— DML语句 什么是DML语句添加数据给全部字段添加数据批量添加数据 修改数据删除数据 什么是DML语句 在MySQL中&#xff0c;DML&#xff08;Data Manipulation Language&#xff0c;数据操纵语言&#xff09;语句主要用于对数据库中的数…

基础安全:CSRF攻击原理与防范

CSRF的概念 CSRF(Cross-Site Request Forgery)中文名为“跨站请求伪造”。这是一种常见的网络攻击手段,攻击者通过构造恶意请求,诱骗已登录的合法用户在不知情的情况下执行非本意的操作。这种攻击方式利用了Web应用程序中用户身份验证的漏洞,即浏览器在用户完成登录后会自…

eclipse导入工程提示Project has no explicit encoding set

eclipse导入工程提示Project has no explicit encoding set 文章目录 eclipse导入工程提示Project has no explicit encoding set一、Eclipse的工程导入二、可能的问题1.在工程名下有黄色叹号 一、Eclipse的工程导入 用Eclipse的导入可以将原有工程导入到新环境中 具体方法是&…

3.C++动态内存管理(超全)

目录 1 .C/C 内存分布 2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3. C内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 3.3 operator new函数 3.4 定位new表达式(placement-new) &#xff08;了解&#xff09; 4. 常…

Linux搭建靶场

提前准备&#xff1a; 文章中所使用到的Linux系统&#xff1a;Ubantu20.4sqlilabs靶场下载地址&#xff1a;GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based. 一. 安装phpstudy phpstudy安装命令&#xff1a;wget -O install.sh h…

增强大模型高效检索:基于LlamaIndex ,构建一个轻量级带有记忆的 ColBERT 检索 Agent

在自然语言处理领域&#xff0c;高效检索相关信息的能力至关重要。将对话式记忆集成到文档检索系统中已经成为增强信息检索代理效果的强大技术。 在文中&#xff0c;我们专为 LlamaIndex 量身定制&#xff0c;将深入探讨构建一个轻量级的带有记忆的 ColBERT 检索代理&#xff…

后端方案设计文档结构模板可参考

文章目录 1 方案设计文档整体结构2 方案详细设计2.1 概要设计2.2 详细设计方案2.2.1 需求分析2.2.2 业务流程设计2.2.3 抽象类&#xff1a;实体对象建模2.2.4 接口设计2.2.5 存储设计 1 方案设计文档整体结构 一&#xff0c;现状&#xff1a;把项目的基本情况和背景都说清楚&a…

iA Writer for Mac:简洁强大的写作软件

在追求高效写作的今天&#xff0c;iA Writer for Mac凭借其简洁而强大的功能&#xff0c;成为了许多作家、记者和学生的首选工具。这款专为Mac用户打造的写作软件&#xff0c;以其独特的设计理念和实用功能&#xff0c;助你轻松打造高质量的文章。 iA Writer for Mac v7.1.2中文…

第2节:UIOTOS前端零代码应用 蓝图连线 信号值变化小示例02

目标 通过连线&#xff0c;实现信号值随机变化。 最终效果 实现过程 步骤1&#xff1a;接11节&#xff0c;选中底板设置其背景颜色 步骤2&#xff1a;拖入普通按钮V2组件&#xff0c;设置“text”值为“1”&#xff0c;并做form绑定 步骤3&#xff1a;选中按钮对输入框进行交…

Java 写一个死锁的例子

public class DeadLock {public static void main(String[] args) {Object lock1 new Object();Object lock2 new Object();new Thread(new A(lock1,lock2),"线程A").start();new Thread(new B(lock1,lock2),"线程B").start();} }class A implements Run…

Microsoft Universal Print 与 SAP 集成教程

引言 从 SAP 环境打印是许多客户的要求。例如数据列表打印、批量打印或标签打印。此类生产和批量打印方案通常使用专用硬件、驱动程序和打印解决方案来解决。 Microsoft Universal Print 是一种基于云的打印解决方案&#xff0c;它允许组织以集中化的方式管理打印机和打印机驱…

2023年蓝桥杯C++A组第三题:更小的数(双指针解法)

题目描述 小蓝有一个长度均为 n 且仅由数字字符 0 ∼ 9 组成的字符串&#xff0c;下标从 0 到 n − 1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。小蓝想要将选出的…