编译产物 JSON 文件详解
本文将为你介绍编译产物之一 JSON 文件的结构。
为了便于讲解,我们用一个例子来说明:
import 'package:fair/fair.dart';
import 'package:flutter/material.dart';
()
class JsonFileExplain extends StatefulWidget {
const JsonFileExplain({Key? key}) : super(key: key);
_JsonFileExplainState createState() => _JsonFileExplainState();
}
class _JsonFileExplainState extends State<JsonFileExplain> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget _buildTitle() {
return Text('title');
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: _buildTitle(),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: TextStyle(
fontSize: 40, color: Color(0xffeb4237), wordSpacing: 0),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
执行:flutter pub run build_runner build
命令后,生成了 JSON 文件,我们打开文件看看:
{
"className": "Scaffold",
"na": {
"appBar": {
"className": "AppBar",
"na": {
"title": "%(_buildTitle)"
}
},
"body": {
"className": "Center",
"na": {
"child": {
"className": "Column",
"na": {
"mainAxisAlignment": "#(MainAxisAlignment.center)",
"children": [
{
"className": "Text",
"pa": [
"You have pushed the button this many times:"
]
},
{
"className": "Text",
"pa": [
"#($_counter)"
],
"na": {
"style": {
"className": "TextStyle",
"na": {
"fontSize": 40,
"color": {
"className": "Color",
"pa": [
"0xffeb4237"
]
},
"wordSpacing": 0
}
}
}
}
]
}
}
}
},
"floatingActionButton": {
"className": "FloatingActionButton",
"na": {
"onPressed": "@(_incrementCounter)",
"tooltip": "Increment",
"child": {
"className": "Icon",
"pa": [
"#(Icons.add)"
]
}
}
}
},
"methodMap": {
"_buildTitle": {
"className": "Text",
"pa": [
"title"
]
}
}
}
在 JSON 文件中,有几个重要的 key:
- className
- na
- pa
- methodMap
下面详细为你解释每一个 key 的含义。
1. className
className
表示对于的 Widget 的名字,如 JSON 文件第一行:"className": "Scaffold"
,它对应的是 build
方法里面的 Scaffold
:
2.na
na
表示 命名可选参数。如示例代码中的 Scaffold
的 3 个命名可选参数 appBar
、 body
和floatingActionButton
,都会被存放在 JSON 文件的 na
中。
3.pa
pa
表示 required 类型。如示例代码的 Text
中的 required 参数:String data
。
4.methodMap
methodMap
表示在 State
中用于返回 Widget 的方法,如:
class _JsonFileExplainState extends State<JsonFileExplain> {
......
Widget _buildTitle() {
return Text('title');
}
}
注意,一定要通过 return 的方式去返回 Widget,这样 Fair 才能正确解析。
好,到这里,我们已经把所有 key 的含义讲清楚了。但是,也许你还有疑问,JSON 文件里的 %
、@
、#
、^
等符号是什么意思呢?
别着急,下面我们继续为你介绍。
布局中如果引用了变量、常量和方法在解析成 DSL 时都会被当成一个字符串,像这样:
为了方便在解析 DSL 时区分不同字符串的含义,我们在字符串的前面加上了不同的特殊符号,具体包括:
1.% 代表引用的是一个返回值为 Widget 的方法
Tips:注意只有在布局中引用了返回值是 Widget 的方法时,才会被标记上%符号。
2.@ 代表引用的是一个非 Widget 的方法
Tips:注意只有在布局中引用的方法的返回值,不是一个 Widget 时,才会被标记为@符号。返回值可以是 void ,也可以是 Dart 支持的数据类型,如 int、String、Boolean 等。
3.# 代表引用的是一个外部变(常)量或者 $ 符号引用的本地变量
外部变(常)量比如:MainAxisAlignment.center
、Icons.add
还有一种情况是,使用了 $
符号引用了本地变量或者进行了字符串拼接(aaaa$_counter
):