为什么80%的码农都做不了架构师?>>>

目录

一个Java开发快速入门Dart

Flutter使用简报

一个Android开发快速入门Flutter(一)

一个Android开发快速入门Flutter (二)

前言

Flutter个人感觉是移动端开发不错的姿势,相比于其他weex开发也有一定优势。如果你想先初步了解Flutter的话,可以看下这个视频介绍。20多分钟,基本讲述了Flutter的优点和设计思想。对于新入手的人而言,值得花点时间研究下。

另外本篇博客内容取自于Flutter官网教程,用于记录所获,如果你希望更加获得更加官方的咨询,可参见官网。

注意

  1. 上面视频中有个非常炫酷的操作,就是通过改变framework(就是Flutter提供给你的代码),直接修改一个list的表现形式。喂这是正常操作吧,这里的Flutter对于整个ios或者Android来说就是一个三方包,只是经过编译之后变成arm指令。那么你修改三方包里面的源代码,导致表现形式改变不是很正常嘛?忽悠人,差评。
  2. 在Flutter中要建立组件化(widget)的概念,什么都是组件,连整个app都是组件,连padding都是组件,连居中都是组件!
  3. UI从命令式到声明式的转变。怎么理解这句话,这对于Flutter的理解非常重要。

    从上面这张图来说,假设由于某个时间触发,我们需要将当前的view从 左图变到右图。对于从win32就开始的传统的命令式UI来说,首先我们需要获取到ViewB b ,ViewC c1 ViewC c2的实例,然后修改这些实例的状态,比如用android的代码来写可能就差不多是这样的。

    b.setColor(red)
    b.clearChildren()
    ViewC c3 = new ViewC(...)
    b.add(c3)

    但是在声明式的UI系统中,view是不可变的,所以所有的视图都是轻量级的“蓝图”,当需要改变的时候,就会重新构建这个view(Flutter中一遍就是StatefulWidget组件通过State中调用setState()方法):

    return ViewB(color: red,child: ViewC(...),
    )

    至于那种模式好,效率高当然是各家之言,等到我足够体验之后才能做出自己的判断。

Hello world!

//使用了material的包,Flutter还提供一个cupertion包,用于表示谷歌和苹果两种界面风格
//当然我们完全可以自定义自己的风格
import 'package:flutter/material.dart';
//引入了一个三方库 english_words ,需要在pubspec.yaml中的dependencies: 下面添加 english_words: ^3.1.0
import 'package:english_words/english_words.dart';//main是dart的主方法,主方法很简单,调用系统方法runApp,运行一个App
void main() => runApp(MyApp()); //MyApp 就是我们的app了,它继承与StatelessWidget组件
class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) { //build是组件类的基本方法,用于构建这个组件的显示样式final wordPair = WordPair.random();return MaterialApp( //一个MaterialApp widgettitle: 'Welcome to Flutter',home: Scaffold( //一个Scaffold widget相当于主界面,包含一个组件树appBar: AppBar( //标题栏组件title: Text('Welcome to Flutter IOS'),),body: Center( //center组件,居中显示child: Text(wordPair.asPascalCase),),),);}
}

这段代码以及注释希望能够让你对Flutter有一个初步映像,至于其中包含的上面appBar啊Center啊这些组件,真的是在开发过程中逐步积累的过程,并不是入门时的重点。

Widget

组件widget分为两种,一种不不可变的StatelessWidget他内部的变量都是final类型的,所以是属性不可变的组件。另一种是StatefulWidget组件。

实现StatefulWidget至少需要两个类:一个StatefulWidget类 2)State<?>类的实例。 StatefulWidget类本身是不可变的,但State类在窗口小部件的生命周期内持久存在。

扩展一下上面代码

//使用了material的包,Flutter还提供一个cupertion包,用于表示谷歌和苹果两种界面风格
//当然我们完全可以自定义自己的风格
import 'package:flutter/material.dart';
//引入了一个三方库 english_words ,需要在pubspec.yaml中的dependencies: 下面添加 english_words: ^3.1.0
import 'package:english_words/english_words.dart';//main是dart的主方法,主方法很简单,调用系统方法runApp,运行一个App
void main() => runApp(MyApp()); //MyApp 就是我们的app了,它继承与StatelessWidget组件
class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) { //build是组件类的基本方法,用于构建这个组件的显示样式return MaterialApp( //一个MaterialApp widgettitle: 'Welcome to Flutter',home: Scaffold( //一个Scaffold widget相当于主界面,包含一个组件树appBar: AppBar( //标题栏组件title: Text('Welcome to Flutter IOS'),),body: Center( //center组件,居中显示child: RandomWords() //使用StatefulWidget组件),),);}
}/** 为了实现StatefulWidget,必须要有一个State类,用于帮助StatefulWidget build它的显示样式。* 实际上,大多数的业务逻辑都是在State中进行处理的。*/
class RandomWordsState extends State<RandomWords>{@overrideWidget build(BuildContext context) {final wordPair = WordPair.random();return Text(wordPair.asPascalCase);}
}/** 定义一个用于显示随机单词的组件,这个组件是一个StatefulWidget组件,所以我们必须要提供一个State<RandomWords>的类* StatefulWidget 内部必须重写createState方法。他的widget的build方法交给这个State去写。*/
class RandomWords extends StatefulWidget{@overrideState<StatefulWidget> createState() {return RandomWordsState();}
}

扩展成无限滑动的list

首先下面代码的主要目的并不是让我们掌握Flutter中list的具体用法,个人觉得应该亲自去写一下代码,知道这里在干什么,去了解Flutter的代码构成方式和体会“一切都是组件”的含义。

//使用了material的包,Flutter还提供一个cupertion包,用于表示谷歌和苹果两种界面风格
//当然我们完全可以自定义自己的风格
import 'package:flutter/material.dart';
//引入了一个三方库 english_words ,需要在pubspec.yaml中的dependencies: 下面添加 english_words: ^3.1.0
import 'package:english_words/english_words.dart';//main是dart的主方法,主方法很简单,调用系统方法runApp,运行一个App
void main() => runApp(MyApp()); //MyApp 就是我们的app了,它继承与StatelessWidget组件
class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) { //build是组件类的基本方法,用于构建这个组件的显示样式return MaterialApp( //一个MaterialApp widgettitle: 'Welcome to Flutter',home: RandomWords(), //主界面是一个RandomWords类型的组件);}
}/** 为了实现StatefulWidget,必须要有一个State类,用于帮助StatefulWidget build它的显示样式。* 实际上,大多数的业务逻辑都是在State中进行处理的。*/
class RandomWordsState extends State<RandomWords>{final _suggestions = <WordPair>[];final _biggerFont = const TextStyle(fontSize: 18.0);/** 用于创建一个ListView组件*/Widget _buildSuggestions(){//listview的builder工厂方法return ListView.builder(padding: const EdgeInsets.all(16.0),itemBuilder: (context,i){  /* dart写法,类似于匿名类和lambda *///如果是基数,返回分割线if(i.isOdd) return Divider();final index = i ~/ 2; //i除以2 并返回整数结果if(index >= _suggestions.length){_suggestions.addAll(generateWordPairs().take(10));}return _buildRow(_suggestions[index]);}, );}/** 创建listview中的每一个item,每个item都是一个组件*/Widget _buildRow(WordPair pair) {return ListTile(title: Text(pair.asPascalCase,style: _biggerFont,),);}/** 创建RandomWords组件的界面展示。 */@overrideWidget build(BuildContext context) {return Scaffold (appBar: AppBar(title: Text('Startup Name Generator'),),body: _buildSuggestions(),);}
}/** 定义一个用于显示随机单词的组件,这个组件是一个StatefulWidget组件,所以我们必须要提供一个State<RandomWords>的类* StatefulWidget 内部必须重写createState方法。他的widget的build方法交给这个State去写。*/
class RandomWords extends StatefulWidget{@overrideState<StatefulWidget> createState() {return RandomWordsState();}
}

添加页面跳转和点击

继续改造上面的代码,添加了随机单词标星这样的操作。并且能够进行页面跳转。

//使用了material的包,Flutter还提供一个cupertion包,用于表示谷歌和苹果两种界面风格
//当然我们完全可以自定义自己的风格
import 'package:flutter/material.dart';
//引入了一个三方库 english_words ,需要在pubspec.yaml中的dependencies: 下面添加 english_words: ^3.1.0
import 'package:english_words/english_words.dart';//main是dart的主方法,主方法很简单,调用系统方法runApp,运行一个App
void main() => runApp(MyApp()); //MyApp 就是我们的app了,它继承与StatelessWidget组件
class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) { //build是组件类的基本方法,用于构建这个组件的显示样式return MaterialApp( //一个MaterialApp widgettitle: 'Welcome to Flutter',home: RandomWords(), //主界面是一个RandomWords类型的组件theme: new ThemeData(primaryColor: Colors.white), //修改app主题);}
}/** 为了实现StatefulWidget,必须要有一个State类,用于帮助StatefulWidget build它的显示样式。* 实际上,大多数的业务逻辑都是在State中进行处理的。*/
class RandomWordsState extends State<RandomWords>{final _suggestions = <WordPair>[];final _biggerFont = const TextStyle(fontSize: 18.0);final Set<WordPair> _saved = new Set<WordPair>(); //用于存储已经点赞的名字/** 用于创建一个ListView组件*/Widget _buildSuggestions(){//listview的builder工厂方法return ListView.builder(padding: const EdgeInsets.all(16.0),itemBuilder: (context,i){  /* dart写法,类似于匿名类和lambda *///如果是基数,返回分割线if(i.isOdd) return Divider();final index = i ~/ 2; //i除以2 并返回整数结果if(index >= _suggestions.length){_suggestions.addAll(generateWordPairs().take(10));}return _buildRow(_suggestions[index]);}, );}/** 创建listview中的每一个item,每个item都是一个组件*/Widget _buildRow(WordPair pair) {final bool alreadySaved = _saved.contains(pair); //记录是否已经标记过return ListTile(title: Text(pair.asPascalCase,style: _biggerFont,),trailing: Icon(alreadySaved? Icons.favorite : Icons.favorite_border,color: alreadySaved ? Colors.red:null,),//创建一个星形icon//icon点击事件onTap: (){setState(() { //使用setState来更新list中item的状态,setState会先运行下面代码,然后再通知list更改itemif(alreadySaved){_saved.remove(pair);}else{_saved.add(pair);}});},);}/** 创建RandomWords组件的界面展示。 */@overrideWidget build(BuildContext context) {return Scaffold (appBar: AppBar(title: Text('Startup Name Generatorrrrrr'),//为app bar增加左上按钮actions: <Widget>[IconButton(icon: const Icon(Icons.list),onPressed: _pushSaved)],),body: _buildSuggestions(),);}/** appbar 左上按钮点击事件。使用Navigator 跳转到新页面* Navigator 是Flutter中的路由管理器,通过push进行跳转,通过remove进行返回*/void _pushSaved(){//在路由管理器 Navigator中push一个新的路由//这个路由是一个页面路由,通过builder构建这个页面Navigator.of(context).push(MaterialPageRoute<void>(builder: (context){//dart语法,每一个被标星的单词都会生成一个ListTile组件final Iterable<ListTile> tiles = _saved.map((pair){return new ListTile(title: new Text(pair.asPascalCase,style:_biggerFont),);});//在tiles组件之间插入分割线final List<Widget> divided = ListTile.divideTiles(context: context,tiles: tiles).toList();return new Scaffold(appBar: new AppBar(title: const Text('Saved Suggestions'),),body: new ListView(children: divided,),//生成listview);}));}
}/** 定义一个用于显示随机单词的组件,这个组件是一个StatefulWidget组件,所以我们必须要提供一个State<RandomWords>的类* StatefulWidget 内部必须重写createState方法。他的widget的build方法交给这个State去写。*/
class RandomWords extends StatefulWidget{@overrideState<StatefulWidget> createState() {return RandomWordsState();}
}

结语

基本上所有的分析都写在注释中,所以文章本身并没有多少文字,都是贴代码。如果能够跟着上面的步骤,将代码好好读一遍,那么应该就基本上算是初步了解了Flutter的代码构成。当然这只是万里长征的第一步,更多的资源可以参考这里。

另外上面的代码并没有进行非常好的代码结构处理,而是一直在dart提供的函数式编程能力。这样就导致代码层次嵌套很多(如果老老实实用局部变量,就能够极大的减少嵌套),对后续阅读产生困扰,所以语法糖这种东西,并不是在任何时候都讨喜的。

转载于:https://my.oschina.net/zzxzzg/blog/2962136

Flutter使用简报相关推荐

  1. 使用Model-View-ViewModel使用Dart Streams使Flutter中的代码更清晰

    by QuickBird Studios 通过QuickBird Studios 使用Model-View-ViewModel使用Dart Streams使Flutter中的代码更清晰 (Use Mo ...

  2. Flutter 拨打电话和跳转网页

    首先需要一如库 url_launcher  如下 具体写法如下 import 'package:flutter/material.dart'; import 'package:url_launcher ...

  3. flutter导入第三方库

    在pubspec.yaml 文件中找到 dependencies 在里面填写 第三方库即可 例如图中我写了fluttertoast库 特别注意:导入的位置要不dependencies下面的flutte ...

  4. Flutter 导包 以及体验

    Flutter 第一个list 体验 具体位置看图吧 是在pubspec.yaml 里面的 dev_dependencies 里面 然后点击packages_get flutter 不用每次都运行,保 ...

  5. Flutter 配置

    参考 Flutter 中文网 配置的 这里说一下 https://flutterchina.club/setup-windows/ 1 如果自己不能翻墙 先配置镜像 使用镜像 由于在国内访问Flutt ...

  6. flutter中的路由跳转

    在前面的基本路由和命名路由中,都演示了如何进行路由跳转,并且在路由跳转以后,可以借用系统自带的按钮就行返回上一级,当然了,也可以自定义按钮返回上一级. 返回上一级 在前面的例子中,当从Home.dar ...

  7. Flutter 网络请求库http

    http 集成http库 https://pub.dartlang.org/packages/http 添加依赖 dependencies:http: ^0.12.0 安装 flutter packa ...

  8. 配置flutter For IOS

    https://www.cnblogs.com/lovestarfish/p/10628205.html 第一步,下载flutter最新版,解压到自己的目录里: 提供网址:https://flutte ...

  9. 转:Flutter Decoration背景设定(边框、圆角、阴影、形状、渐变、背景图像等)...

    1 继续关系: BoxDecoration:实现边框.圆角.阴影.形状.渐变.背景图像 ShapeDecoration:实现四个边分别指定颜色和宽度.底部线.矩形边色.圆形边色.体育场(竖向椭圆).  ...

  10. Flutter中集成Font Awesome

    1.添加引用 在 pubspec.yaml文件中,加入 font awesome的引用 1 dependencies: 2 flutter: 3 sdk: flutter 4 5 # The foll ...

最新文章

  1. 【Android】5.3 单选和复选
  2. redis延迟队列 实现_灵感来袭,基于Redis的分布式延迟队列(续)
  3. sql复杂查询语句总结
  4. java url 返回值_java提交url后返回值怎么取
  5. 临近春招,Kafka是不是忘完了,给你一文概括Kafka
  6. TensorFlow:实战Google深度学习框架(一)计算、数据、运行模型
  7. 【Logstash】Logstash:把MySQL数据导入到Elasticsearch中
  8. 算法笔记:简单的字符串模式匹配-KMP算法(与BF算法对比时间复杂度)
  9. pythonenumapi_python模块之enum_上
  10. linux 标准vruntime,linux – CFS中vruntime的概念是什么
  11. 敏捷开发免费管理工具——火星人预览之二:编辑故事,产品管理,组织结构...
  12. 基于SSM的小说阅读网站
  13. Modelsim 安装步骤详解
  14. 流程图介绍 以及工具推荐
  15. 如何把microsoft store里面的软件添加到桌面
  16. ECU安全访问系列_2(代码篇)
  17. python保存变量_python | 变量-保存与命名规则
  18. 基于模板方法+协调者委托对现有冗余代码的改造案例
  19. vue使用支付宝支付
  20. 小程序进阶-emoji表情

热门文章

  1. easyui tree json php,easyui tree json
  2. lottie动画_设计师和程序员的动画还原神器Lottie+Bodymovin
  3. a ppt of CRF
  4. 最新xmlns:android=http://schemas.android.com/apk/res/android的理解
  5. 线性空间与坐标空间的同构
  6. 柯特斯公式 | 数值积分
  7. 345.反转字符串中的元音字符(力扣leetcode) 博主可答疑该问题
  8. linux下创造进程指令,Linux系统创建一个新进程(下)
  9. c语言0x00如何不截断_数组越界及其避免方法,C语言数组越界详解
  10. Anaconda3安装以及常用命令