【布局 widget】Flutter Baseline

简介: 【布局 widget】Flutter Baseline

image.png

Baseline 是布局 widget,作用是让 child 的基线和指定的位置重合。Baseline 的布局逻辑不难,很多同学不知道如何用这个 widget 是因为对基线不是很理解。下面我们先看一下基线。

image.png

基线(英语:Baseline)指的是多数拉丁字母排列的基准线。如上图所示,大多字母都沿着红色基线排列。

baseline 理解了,但是 Baseline widget 还有一个参数 baselineType,这个参数是一枚举类型。

/// A horizontal line used for aligning text.
enum TextBaseline {
  /// The horizontal line used to align the bottom of glyphs for alphabetic characters.
  alphabetic,
  /// The horizontal line used to align ideographic characters.
  ideographic,
}
复制代码

把注释翻译一下

// 一条用于对齐文本的水平线
enum TextBaseline {
  /// 用于对齐字母字符字形底部的水平线
  alphabetic,
  /// 用于对齐表意字符的水平线
  ideographic,
}
复制代码

在英语中把中文,韩文等东亚文字称为 ideographic(表意)文字。比如 Fluter Widget 天天更新 这几个字放在一起的时候,基线就可以有两个 ,一个是 Fluter Widget 的基线,一个是 天天更新 的基线。

这样说了半天,可能还是不能理解,下面我们自己把这两条基线划出来。上面的是字母基线,下面的是表意基线


image.png

class myPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final textStyle = TextStyle(
      color: Colors.black,
      fontSize: 30,
    );
    final textSpan = TextSpan(
      text: 'Flutter widget每日更新IAM17',
      style: textStyle,
    );
    final textPainter = TextPainter(
      text: textSpan,
      textDirection: TextDirection.ltr,
    );
    textPainter.layout(
      minWidth: 0,
      maxWidth: size.width,
    );
    final paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    // 把 TextBaseline.ideographic 改为 TextBaseline.alphabetic 画字母基线。
    final distanceToBaseline =
        textPainter.computeDistanceToActualBaseline(TextBaseline.ideographic);
    canvas.drawLine(
      Offset(0, distanceToBaseline),
      Offset(textPainter.width, distanceToBaseline),
      paint,
    );
    final offset = Offset(0, 0);
    textPainter.paint(canvas, offset);
  }
  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}
复制代码

关于基线的知识了解了,Baseline 就变得非常简单了。

布局逻辑的代码

void performLayout() {
    if (child != null) {
      final BoxConstraints constraints = this.constraints;
      child!.layout(constraints.loosen(), parentUsesSize: true);
      final double childBaseline = child!.getDistanceToBaseline(baselineType)!;
      final double actualBaseline = baseline;
      final double top = actualBaseline - childBaseline;
      final BoxParentData childParentData = child!.parentData! as BoxParentData;
      childParentData.offset = Offset(0.0, top);
      final Size childSize = child!.size;
      size =
          constraints.constrain(Size(childSize.width, top + childSize.height));
    } else {
      size = constraints.smallest;
    }
  }
复制代码

Baseline 就是让它指定的基线位置和 child 的基线重合。 我们通过示例看下。

Center(child:Container(
   decoration: BoxDecoration(border: Border.all(color: Colors.red)),
   child: Baseline(
       baseline: 100,
       baselineType: TextBaseline.ideographic,
       child: Container(
         width: 100,
         height: 100,
         color: Colors.blue[200],
))));
复制代码

我们给 Baseline 套上一个红框,用来显示它的大小。

  1. baseline 与 child baseline 值相同


image.png

在本例中 child baseline 为 100,与指定的baseline 相同,结果是 size 与 child size 相同。Baseline紧紧包裹住 child。

非文字的基线位置是 box 的底部

  1. baseline 小于 child baseline

baseline: 100  修改为   baseline: 0


image.png


size 为0。chld 在 baseline 正上方。 3. baseline 大于 child baseline

baseline: 100 修改为 baseline: 150

image.png


size 为 150,Baseline 完全包裹 child。child 在 Baseline 底部

  1. baseline 可以为负值

baseline: 100 修改为 baseline: -10


image.png

size 为 0 child 在 Baseline 上方,和 Baseline 间隔 baseline 距离。

通过这样几个示例,我们对 Baseline 的作用已经有了感观上的认识。下面思考一下它的应用场景。

Baseline 的应用场景

通过上面的例子我们可以看出 Baseline 可以做溢出效果,但如果是溢出,最好还是用 OverflowBox。Baseline 的应用应该是在文字对齐方面。比如要实现下面的效果,"IAM17” 这几个字要求紧贴红框下边。


image.png

Container(
    height: 50,
    decoration: BoxDecoration(border: Border.all(color: Colors.red)),
    child: Baseline(
      baseline: 50,
      baselineType: TextBaseline.ideographic,
      child: Text('IAM17', style: TextStyle(fontSize: 24,)),
    ),
  )
复制代码

你可能会说,如果不贴底,可以设置一个偏移,但这个偏移是多少呢?随着字体,字号的变化,这个偏移量也是变化的。

用 Baseline 可以轻松实现基线对齐,遇到基线对齐的问题,应该第一时间想到 Baseline。

目录
相关文章
|
7天前
|
编解码 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的响应式设计与自适应布局
【4月更文挑战第30天】Flutter框架助力移动应用实现响应式设计与自适应布局,通过层次化布局系统和`Widget`树管理,结合`BoxConstraints`定义尺寸范围,实现自适应。利用`MediaQuery`获取设备信息,调整布局以适应不同屏幕。`FractionallySizedBox`按比例设定尺寸,`LayoutBuilder`动态计算布局。借助这些工具,开发者能创建跨屏幕尺寸、方向兼容的应用,提升用户体验。
【Flutter前端技术开发专栏】Flutter中的响应式设计与自适应布局
|
7天前
|
开发框架 前端开发 数据安全/隐私保护
【Flutter 前端技术开发专栏】Flutter 中的布局与样式设计
【4月更文挑战第30天】本文探讨了Flutter的布局和样式设计,关键点包括:1) 布局基础如Column、Row和Stack用于创建复杂结构;2) Container、Center和Expanded等常用组件的作用;3) Theme和Decoration实现全局样式和组件装饰;4) 实战应用如登录界面和列表页面的构建;5) 响应式布局利用MediaQuery和弹性组件适应不同屏幕;6) 性能优化,避免过度复杂设计。了解并掌握这些,有助于开发者创建高效美观的Flutter应用。
【Flutter 前端技术开发专栏】Flutter 中的布局与样式设计
|
5天前
|
Android开发
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
|
7天前
|
开发框架 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
【4月更文挑战第30天】探索Flutter的自定义Widget与渲染流程。自定义Widget是实现复杂UI设计的关键,优点在于个性化设计、功能扩展和代码复用,但也面临性能优化和复杂性管理的挑战。创建步骤包括设计结构、定义Widget类、实现构建逻辑和处理交互。Flutter渲染流程涉及渲染对象树、布局、绘制和合成阶段。实践案例展示如何创建带渐变背景和阴影的自定义按钮。了解这些知识能提升应用体验并应对开发挑战。查阅官方文档以深入学习。
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
|
7天前
|
JavaScript 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的Widget与状态管理
【4月更文挑战第30天】本文探讨了Flutter的Widget和状态管理。Widget是Flutter构建UI的基础,分为有状态和无状态两种。状态管理确保UI随应用状态变化更新,影响应用性能和可维护性。文章介绍了`setState`、`Provider`、`Riverpod`、`Bloc`和`Redux`等状态管理方法,并通过计数器应用展示了其实现。选择合适的状态管理策略对高效开发至关重要。
【Flutter前端技术开发专栏】Flutter中的Widget与状态管理
|
7天前
|
前端开发 开发者 UED
Flutter的自定义Painter:深入探索自定义绘制Widget的技术实现
【4月更文挑战第26天】Flutter的自定义Painter允许开发者根据需求绘制独特UI,通过继承`CustomPaint`类和重写`paint`方法实现。在`paint`中使用`Canvas`绘制图形、路径等。创建自定义Painter类后,将其作为`CustomPaint` Widget的`painter`属性使用。此技术可实现自定义形状、渐变、动画等复杂效果,提升应用视觉体验。随着Flutter的进化,自定义Painter将提供更丰富的功能。
|
7天前
|
编解码 算法 开发者
Flutter的布局系统:深入探索布局Widget与布局原则
【4月更文挑战第26天】Flutter布局系统详解,涵盖布局Widget(Row/Column、Stack、GridView/ListView、CustomSingleChildLayout)和布局原则(弹性布局、约束优先、流式布局、简洁明了)。文章旨在帮助开发者理解并运用Flutter的布局系统,创建适应性强、用户体验佳的界面。通过选择合适的布局Widget和遵循原则,可实现复杂且高效的UI设计。
|
7天前
|
开发框架 搜索推荐 Android开发
Flutter的Widget基础:概念、分类与深入探索
【4月更文挑战第26天】Flutter Widget详解:基础、分类与工作原理。Widget是Flutter UI的核心,描述界面外观而非直接渲染。分为基础、布局、可滚动及状态管理四大类。基于响应式编程,状态变化时自动更新UI。了解其概念、分类和原理,能助开发者高效构建精美应用。随着Flutter生态发展,Widget系统潜力无限。
|
7天前
|
容器
Flutter笔记:Box协议的布局约束原理与应用
Flutter笔记:Box协议的布局约束原理与应用
49 0
|
7天前
|
开发者 索引 容器
Flutter开发笔记:Flutter 布局相关组件
Flutter开发笔记:Flutter 布局相关组件
141 0