龙空技术网

入坑Flutter ,弃坑React-Native(简单体验)

爱音乐的程序员小新人 7855

前言:

现时小伙伴们对“xcode是vscode吗”大致比较着重,大家都想要分析一些“xcode是vscode吗”的相关文章。那么小编也在网摘上搜集了一些对于“xcode是vscode吗””的相关内容,希望兄弟们能喜欢,兄弟们一起来学习一下吧!

前言

由于业务需要之前用react-native重写了公司项目,中间碰到各种坑,莫名其妙红屏,适配坑,页面刷新坑,打包坑,热更新坑.折磨了两个月终于完成.年初就听说了Flutter,看一下是用Google的Dart语言,据说是有望代替JavaScript这个一周完成的奇葩.咳咳,看了下国内咸鱼团队已经在项目中使用了Flutter技术,这是他们的社区社区博文深入理解flutter的编译原理与优化,想不到竟然如此强大.忍不住就参考官方文档写了个demo

Flutter官网

克隆Flutter仓库

git clone -b beta 

配置环境变量

export PUB_HOSTED_URL= //国内用户需要设置export FLUTTER_STORAGE_BASE_URL= //国内用户需要设置export PATH= flutter所在目录/flutter/bin:$PATH

可直接将环境变量写入~/.bash_profile文件中执行source $HOME/.bash_profile生效(如果未生效请重启终端或电脑)

配置命令行工具sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

安装链接设备工具

brew updatebrew install --HEAD libimobiledevicebrew install ideviceinstaller ios-deploy cocoapodspod setup

VScode 配置

搜索dart code安装dart 插件

快捷键 shift + command + p 输入 ‘doctor’, 然后选择 ‘Flutter: Run Flutter Doctor’ 验证操作

同样 shift + command + p 输入 ‘flutter’, 然后选择 ‘Flutter: New Project’ action 创建一个测试项目 vscode 底部展示附加设备

点击Debug>Start Debugging即可运行项目

创建

按照之前的方法创建一个模板 shift + command + p 输入 ‘flutter’, 然后选择 ‘Flutter: New Project’ action

替换 lib/main.dart. 删除lib / main.dart中的所有代码,然后替换为下面的代码,它将在屏幕的中心显示“Hello World”

//应用入口 //main函数使用了(=>)符号, 这是Dart中单行函数或方法的简写void main() => runApp(new DemoApp());class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) {  return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Center( child: new Text('Royce and Owen'), ), ),  ); }}

外部包使用

您可以 在pub.dartlang.org上找到english_words软件包以及其他许多开源软件包

将english_words添加到pubspec.yaml文件中(pubspec文件管理Flutter应用程序的assets(资源,如图片、package等))

在终端中运行flutter packages get安装依赖

flutter packages getRunning "flutter packages get" in startup_first... 0.6s
导入import 'package:english_words/english_words.dart';使用 English words 包生成文本来替换字符串“Hello World”.修改代码
class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { final wordPair = new WordPair.random(); return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Center( child: new Text(wordPair.asUpperCase), ), ),  ); }}

添加一个 有状态的部件(Stateful widget)

Stateless widgets 是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.

Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:

一个 StatefulWidget类。一个 State类。 StatefulWidget类本身是不变的,但是 State类在widget生命周期中始终存在.新建一个组件类RandomWords新建一个State组件类RandomWordsState

class RandomWordsState extends State<RandomWords> { @override Widget build(BuildContext context) { final wordPair = new WordPair.random(); return new Text(wordPair.asPascalCase); }}class RandomWords extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return new RandomWordsState(); }}
修改代码 final wordPair = new WordPair.random(); // 删除此行
class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) {  return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Center( child: new RandomWords(), ), ),  ); }}

创建一个无限滚动ListView

扩展(继承)RandomWordsState类,以生成并显示单词对列表。 当用户滚动时,ListView中显示的列表将无限增长

在RandomWordsState添加一个变量_suggestions(下划线前缀标识符,会强制其变成私有的)添加一个_biggerFont变量来孔子字体大小新建_buildSuggestions()方法 显示建议的单词对在RandomWordsState中添加一个_buildRow函数更新RandomWordsState的build方法以使用_buildSuggestions()更新MyApp的build方法

class RandomWords extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return new RandomWordsState(); }}class RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = const TextStyle(fontSize: 18.0, color: Color.fromARGB(1, 234, 111, 22)); @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('StartUp'), ), body: _buildSuggestions()); } Widget _buildSuggestions() { return new ListView.builder( padding: const EdgeInsets.all(16.0), // 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中 // 在偶数行,该函数会为单词对添加一个ListTile row. // 在奇数行,该行书湖添加一个分割线widget,来分隔相邻的词对。 // 注意,在小屏幕上,分割线看起来可能比较吃力。 itemBuilder: (context, i) { // 在每一列之前,添加一个1像素高的分隔线widget if (i.isOdd) return new Divider(); // 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整),比如i为:1, 2, 3, 4, 5 // 时,结果为0, 1, 1, 2, 2, 这可以计算出ListView中减去分隔线后的实际单词对数量 final index = i ~/ 2; if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); } return _buildRow(_suggestions[index]); }); } Widget _buildRow(WordPair pair) { return new ListTile( title: new Text( pair.asPascalCase, style: _biggerFont, ), ); }}

添加交互

添加一个 _saved Set(集合) 到RandomWordsState。这个集合存储用户喜欢(收藏)的单词对在 _buildRow 方法中添加 alreadySaved来检查确保单词对还没有添加到收藏夹中。同时在 _buildRow()中, 添加一个心形 ❤️ 图标到 ListTiles以启用收藏功能在 _buildRow中让心形❤️图标变得可以点击。如果单词条目已经添加到收藏夹中, 再次点击它将其从收藏夹中删除。当心形❤️图标被点击时,函数调用setState()通知框架状态已经改变。

Widget _buildRow(WordPair pair) { //判断是否收藏 final bool alreadySaved = _saved.contains(pair); return new ListTile( title: new Text( pair.asPascalCase, style: _biggerFont, ), subtitle: new Text('哈哈哈'), trailing: new Icon( alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), onTap: () { setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, ); }

导航到新页面

在Flutter中,导航器管理应用程序的路由栈。将路由推入(push)到导航器的栈中,将会显示更新为该路由页面。 从导航器的栈中弹出(pop)路由,将显示返回到前一个路由。这点类似iOS的导航机制

给AppBar的actions属性添加一个按钮子组件,由于是复数用 <Widget>[]包装当用户点击导航栏中的列表图标时,建立一个路由并将其推入到导航管理器栈中。此操作会切换页面以显示新路由在MaterialPageRoute的builder属性中构建,builder是一个匿名函数。

 @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( actions: <Widget>[ new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved) ], title: new Text('嘿嘿嘿', style: const TextStyle( fontSize: 18.0, color: Color.fromRGBO(150, 22, 123, 1.0))), ), body: _buildSuggestions()); } void _pushSaved() { Navigator.of(context).push(new MaterialPageRoute(builder: (context) { //便利以保存的单词 创建tile 或者叫(cell,item) final tiles = _saved.map((pair) { return new ListTile( title: new Text( pair.asPascalCase, style: _biggerFont, ), ); }); final divided = ListTile.divideTiles(context: context, tiles: tiles).toList(); //返回一个新页面 return new Scaffold( appBar: new AppBar( title: new Text('saved Suggestions'), ), body: new ListView(children: divided), ); })); }

效果

使用主题更改UI

创建ThemeData来定义theme

class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Startup Name Generator', //主题 theme: new ThemeData( primaryColor: Colors.orange, ), home: new RandomWords(), ); }}

ThemeData提供相当多的属性,自定义程度相当高了,不愧是基于OpenGL构建的UI,比起RN自由度高了很多

Material library中的 Colors类也提供了许多可以使用的颜色常量例如Colors.green,Color.fromRGBO(255, 111, 233, 1.0)

部分属性介绍

accentColor → Color 控件的前景色(旋钮、文本、覆盖边缘效果等)。accentColorBrightness → Brightness dividerColor → Color 分隔符和弹窗分隔符的颜色,也用于ListTiles和DataTables的行之间primaryColor → Color 应用程序主要部分的背景颜色(工具栏,标签栏等)

以上第一flutterdemo完成.

Dart语法非常类似JS,相比较RN但少了</>更加易懂,拥类似state状态机,热加载速度很快,C++底层,基于OpenGL,强大的API和文档支持.

代码地址

标签: #xcode是vscode吗