第一个页面:代码怎样变成文字与按钮
只摆出电量读数和一个按钮,沿着入口、页面对象和布局读代码。先有能看见的结果,再解释框架调用关系。
1 · 从 main 走到页面
独立练习工程 lib/main.dart 的完整内容
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
home: Scaffold(body: Center(child: Text('4000 mV'))),
));
}import 引入框架的界面组件。runApp 把根组件交给 Flutter,MaterialApp 提供应用的基本环境,home 指定首页;Scaffold 提供页面结构;Center 把子组件放在中央;Text 描述要显示的文字。层层括号对应对象包含关系,先从最外层向内读。
Widget 通常译为组件,用来描述界面的一部分。创建 Text 对象没有直接操作屏幕像素,框架会根据这些描述安排布局和绘制。对象嵌套形成组件树,和前面看到的函数调用栈是不同关系。
2 · 把页面命名,才便于继续增加内容
定义放在 main() 外;home 改成 const BatteryPage()
class BatteryPage extends StatelessWidget {
const BatteryPage({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(child: Text("4000 mV")),
);
}
}StatelessWidget 表示这个组件自身不保存会变化的状态。build 接收框架提供的 BuildContext,返回界面描述;context 用于查找位置相关的主题、导航等环境,本篇不用主动操作。key 用来帮助框架辨认组件,这里沿用父类的可选参数。
框架会在需要时调用 build,不要自己写 while(1) 不断调用。build 可能多次发生,因此不能把开始蓝牙扫描、增加监听、发送设置等操作顺手放在里面。
3 · 怎样把两项内容排在一起
替换 Scaffold 的 body 参数
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("4000 mV"),
const SizedBox(height: 16),
ElevatedButton(onPressed: () {}, child: const Text("Refresh")),
],
),
),Padding 留出内边距,Column 让 children 列表沿竖直方向排列,Row 则沿水平方向排列。SizedBox 留出明确的间隔。crossAxisAlignment.start 让这一列的内容靠横向起点对齐。按钮的空回调暂时什么都不做。
父组件会给子组件尺寸约束,子组件在约束中决定尺寸。出现黄色溢出提示时,要先看内容是否超过可用宽高;增加 Row 或固定巨大宽度并不会自动解决。内容较长时再引入滚动组件。
4 · 布局变化与代码位置怎样对应
先修改边距、文字、间隔,观察每个参数改变哪一块。再把两个读数放进 Row,故意放很长的文字看约束错误。阅读项目主页面时,先找到 Scaffold、导航与主要内容容器,暂时不要展开所有装饰属性。
5 · 什么时候才需要拆组件
一张简单页面先直接写清楚。当同一种读数卡片出现多次,或 build 已难以辨认几个区域时,再把那一块提取为独立组件,传入标题、数值和单位。不要在只有一个 Text 时就建立通用卡片系统。
让页面同时显示电压和百分比;用 Column 和 Row 各排一次。指出文字来自哪个参数、按钮的回调在哪里。下一篇让读数真正随点击变化。