在Flutter中,UI的构建是经过Widget的层层嵌套实现的,开发过程当中不可避免地须要频繁修改Widget树,从中插入或者移除一些Widget。git
除了手动写代码和剪切粘贴去修改Widget树以外,在Android Studio和Visual Studio Code中,你还有更高效的方法可使用:github
Flutter所使用的Dart语言,没有相似Java的publice protect private,以_开头的变量、函数和类,意味着它仅在库中是可视的bash
Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore (_) are visible only inside the library.出处ide
观察如下几个例子,加深理解:函数
name变量以_开头后,虽然都是继承于Fruit,可是因为Apple不在同一库中,所以它没法访问父类的name属性。 ![]()
getName方法以_开头后,虽然都是继承于Fruit,可是因为Apple不在同一库中,所以它没法访问父类的getName方法,也无须实现它。 ![]()
Banana类能够访问在同一个库中的_Fruit类,可是因为Apple不在同一库中,所以它没法访问_Fruit类。 ![]()
在Dart中,当你不须要去改变一个变量的时候,应该使用final或者const,而不是使用var去声明一个变量。布局
一个final变量只容许被赋值一次,必须在定义时或者构造函数参数表中将其初始化。ui
const所修饰的是编译时常量,咱们在编译时就已经知道了它的值,它的值是不可改变的。spa
它们的区别就在于,const比final更加严格,看如下几个例子:3d
final List<String> list = [];
list.add('1'); // 正确
const List<String> list = [];
list.add('1'); // 错误,运行时报错:Cannot add to an unmodifiable list
复制代码
final timestamp = new DateTime.now().millisecondsSinceEpoch; // 正确
const timestamp = new DateTime.now().millisecondsSinceEpoch;
// 错误,编译前报错:Const variables must be initialized with a constant value
复制代码
官方文档调试
Flutter提供的Debug Painting能够很方便地协助咱们观察界面的布局,调试界面的开发
咱们在开发App的时候,会常常遇到当点击空白区域时将输入法隐藏的需求。一想到输入法,你们可能都会想经过Method Channle,让原生实现隐藏输入法的办法来解决。其实咱们能够经过FocusScope来转移焦点,一样可以达到隐藏输入法的目的。
Container(
height: 500.0,
child: new GestureDetector(
onTap: () {
// 经过GestureDetector捕获点击事件,再经过FocusScope将焦点转移至空焦点——new FocusNode()
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
margin: EdgeInsets.all(30.0),
child: ListView(children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Username'),
),
TextField(
decoration: InputDecoration(labelText: 'Password'),
)
])),
),
),
复制代码
开发过程当中还发现了Flutter一个bug,这里传递给FocusScope的context不能在MaterialApp下面,即你须要将这部分代码放到独立的一个Widget里面。 具体参考这个issue最后一个评论。