唠唠嗑
上周由于期末考试要复习耽误了一周的时间,好在只有三门考试,复习起来难度也还不大,考完感觉自己应该能稳过吧(非奶)。这周天回到学校又因为疫情反弹的原因不能出校门了,所以感觉接下来有更多的时间来学习flutter这一块的知识体系了。在上上周把demo安装到手机上后其实已经完成了flutter开发环境的搭建。过去这段时间中在使用demo的过程中其实感触最深的便是flutter的热重载,不用等待漫长的安装apk包的时间,修改的结果会在手机界面上直接显示,等确定已经修改正确了达到你想实现的效果后再使用run
安装到手机上,这一交互流程简直对开发人员太友好了(尤其是最近在做项目外包的时候,Android开发板运行速度又慢,每次修改完又要等它安装完才能看效果,实属有点浪费时间)。
动态列表的创建
说回正题,flutter官方教程中在创建完一个默认的app后便开始教你编写你的第一个flutter应用。在看完官方给出来的效果后,其实心中已经有一个大概的架构,实际上就是Android中的listView
+自定义的listAdapter
便可以实现。跟着官方的教程一步步的开始码代码后发现,其实个人觉得flutter采用的Dart
语言在结构化这一块比Java
做的更好,但学习了Java
的面向对象编程的思想也对编写Dart
代码起到一个很好的规范化作用。
例如,在官方的代码中首先定义了一个State类RandomWordsState,个人认为所谓的State类是类似于原生Android中可以交互的组件类型,可以有多个组件状态,如被点击时的状态,常用.setOnclickListener()
方法对此状态下需要进行的操作进行定义(原生安卓中)。在Flutter提供的此案例中,我们调用listview的bilder()方法,在其中我们可以对列表的样式进行创建,如添加分割线,生成的字体样式以及定义当当前列表滑到低即当前生成的随机单词对已经用完时,再添加10个随机的单词对到列表中,并显示,具体代码如下:
class RandomWordsState extends State<RandomWords>{
final _suggestions=<WordPair>[];//创建一个suggestions列表以保存建议的单词
final _biggerFont=const TextStyle(fontSize: 18.0);//创建一个biggerFont变量增大字体大小
@override
Widget build(BuildContext context) {
//以下两行为直接调用单词库,弃用
//final wordPair=new WordPair.random();//此方法通过将生成的单词从Myapp类中移动到RandomWordState来实现生成单词
//return new Text(wordPair.asPascalCase);//返回单词
return new Scaffold(
appBar: new AppBar(
title: new Text("单词列表"),//界面的标题(Appbar)
),
body: __buildSuggestions(),//界面布局layout
);
}
Widget __buildSuggestions(){
return new ListView.builder(
padding: const EdgeInsets.all(16.0),//对于每个随机出来的单词都会调用一次itemBuilder,然后将单词添加到ListTile行中
//对于偶数行,该函数会为单词添加一个ListTile row
//对于奇数行,该函数会添加一个分割线来分割相邻的词对
itemBuilder: (context,i){
if(i.isOdd) return new Divider();//在每一列前,添加一个1像素高的分割线widget
final index=i ~/ 2;//语法“i ~/ 2”表示i除以2,但返回值是向下取整的整型
if(index >= _suggestions.length){//如果是建议列表的最后一个单词对
_suggestions.addAll(generateWordPairs().take(10)); //则在生成10个单词对,然后添加到建议列表
}
return _buildRow(_suggestions[index]);//_buildRow()用于在ListTile中显示每个新单词对
}
);
}
Widget _buildRow(WordPair pair){
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,//文字的字体样式
),
);
}
在其中管理生成字体样式是由_buildRow()实现的,还需注意的是,Dart中对_
开头的变量会将其识别成私有变量,命名时需要注意。
当定义好这一个类后,我们还需要使用一个StatefulWidget
类来接受它。从名字不难看出,statefulwidget直译便是有状态的小部件,此类的主要用途便是创建State
类,但StatefulWidget
类本身还是不可变状态的,能改变的是包裹在其中的State
类,即此处的RandomWordsState
类。具体代码如下:
class RandomWords extends StatefulWidget{
@override
createState() => new RandomWordsState();
}
当定义好这两个类后,此时我们运行程序,发现并没有我们实现的效果。那是因为我们在Dart中程序入口是main()
函数,这点相信有一定编程语言基础的朋友都能明白,此处我们main()
函数定义的程序入口是MyApp()
这个类,所以我们要将我们创建的StatefulWidget
类添加到我们MyApp()
中,至于为什么是添加StatefulWidget
类,个人理解是因为MyApp()
本身是一个StatelessWidget
类,即无状态组件,所以在其中也只能添加同为无状态的StatefulWidget
类,而其中状态的改变则是由StatefulWidget
类中包裹的State
类来实现。具体代码如下:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '测试1',
home:new RandomWords()//使用下方写明的创建随机单词列表类进行界面创建
);
}
工作流程:
实现效果:
如果有写的不妥的地方欢迎指正。