一个新前端开发的Flutter 入坑笔记

851 阅读6分钟

前面关于搭建环境的坑这里就省略掉了,因为今天才想起来记笔记!后面再搭建的时候补上。

第一天

今天就一个小坑。
我用Column进行一个行内两行布局,发现两行文字一直是居中的,即使时使用Align来定位也仍然不起作用。捣鼓了半天找不到问题在哪。于是......

于是决定静下心来看看用到的组件的属性(是的我妥协了)。发现Column有一个crossAxisAlignment属性。

这个属性是用来控制Column中的文本是如何对齐的。把crossAxisAlignment默认值是CrossAxisAlignment.center。这里我们将它改为CrossAxisAlignment.start(也就是文本从起始端开始对齐),就没有问题了!

贴一下代码和效果
            Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.only(top: 15, left: 0),
                    child: Text(dynamics['name'], style: TextStyle(fontSize: 13, color: Color(0xff333333)))
                  ),
                  Padding(
                    padding: EdgeInsets.only(top: 7),
                    child: Text(dynamics['creatTime'], style: TextStyle(fontSize: 11, color: Color(0xff9E9E9E)))
                  )
                ]
              )

其实这个也不算是坑,自己组件没有理解清楚。 Flutter有很多做对齐和定位的组件和属性,在Column上增加这个属性感觉必要性不大。当然在一定程度上避免了Column子组件上每个都要处理文本的对齐方式。但是还是有很多组件上是没有类似属性的,所以Flutter的这个属性让我有点摸不着头脑。

第二天

之前是在公司的电脑上搭建的flutter环境,于是在自己电脑上搭建也搭建一个。 前面下载sdk配置环境变量就不说了,没有什么问题。

但是记得要下在java8, 记得要下在java8, 记得要下在java8。

从flutter doctor说起。 我第一次运行的情况

如图所示(说明一下,我是win10环境)! 百度了一下说是证书问题运行下flutter doctor --android-licenses就行,然后我照做了,情况如下。
提示我们要运行sdkmanager --update,那就试试呗。情况就成了这样。

继续百度吧!不给过这次找了好久,终于找到一个哥们的解决方案。是这样: 在Android Studio 的sdk文件夹下面找到sdkmanager文件,修改其中的DEFAULT_JVM_OPTS这个变量 改成 '"-Dcom.android.sdklib.toolsdir=$APP_HOME" -XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'。我也照做,于是结果就是!

看得出来我试了好几次。再去百度就没有结果过了。 what fuck? 难道我的flutter入坑历程还没开始就要结束了?是的,我放弃了。以后再也不用了!

逗你的。。。。。。

都已经成功配置了win7环境flutter的我怎么可能打自己的脸呢,绝对不允许。

依稀记得之前配置的时候也出现了这种情况,貌似也改了sdkmanager这个文件,但是和这才百度到的不太一样。我凭着记忆和上面出错的结果对DEFAULT_JVM_OPTS这个变量做了一些修改。报错的最后两个说,找不到java.se.ee这个类,我就把这个类从值得字符串里面删掉了。修改后的值应该是 DEFAULT_JVM_OPTS="-Dcom.android.sdklib.toolsdir=%~dp0.." -XX:+IgnoreUnrecognizedVMOptions --add-modules' 再运行一下sdkmanager --update

貌似成功了 再试试flutter doctor --android-licenses

貌似真的可以了(弹出的选项,都选y就行)! 最后再试试flutter doctor

没错成功了,当时仿佛满脑子都是‘阿里路亚’这个声音。坑了我整整3个小时,要不是对之前的搭建有点印象,还真可能弄不出来。赶紧记录一下。这环境实在太坑了!

环境搭建补货

在运行flutter项目的时候,下载https://services.gradle.org/distributions/gradle-4.10.2-all.zip失败了。后来去网上下载下来,也还是不行,吧路径修改成https://services.gradle.org/distributions/gradle-4.6-all.zip就可以正常运行了。个人推测应该是windows版本不一样使用的版本不一样吧!

第三天

断更一个月了,赶紧续上。 今天吧项目首页导航重构了一下,之前是用BottomNavigationBar实现的底部导航。

这样实现没什么问题。但是BottomNavigationBar拥有自己的高度,并且无法直接设置他本身的高度。这里我在BottomNavigationBar外面套一层Container来限制他的高度

只需要在Container上设置宽高,就可以约束BottomNavigationBar的高度和宽度。 scaffold的bottomNavigationBar属性中的widget是被固定在页面底部的,所以无需担心使用了非导航控件导致视图偏移。

Flex布局

如上图所示,是一个Row组件其中Container和Text组件是自由宽度,而Expanded组件则会将剩余的空间全部赋予他的子组件。因此Text组件会被挤到最右方,但是会保留Text本有的宽度。这样就完成了css上简单的flex布局。 另外也可以不使用Expanded组件,将Row的mainAxisAlignment属性设置为MainAxisAlignment.spaceBetween,这样会将除已有组件宽度的剩余宽度用来平均分割已有组件。

第四天

项目进度:已经完成了首页导航 页面做完了就该对接真实数据了,但是请求接口遇到了大坑。 从网上看到的,大家都在吹一个网络请求库,‘dio’,我就试了试。 然鹅,用了官方的post方法请求了一个接口,直接内部报错500(是flutter程序的报错,接口自测过没有问题)。但是谷歌,百度都没有相关的介绍,官方的就更不用说了(新产品的生态,你懂得)。 然后就用了dart原生的网络请求库http,发现可以正常请求接口。所以,dio是有bug吗?

今天也解决了一个问题。 首页的导航用的是PageView和BottomNavigationBar。但是每次切换导航的时候都会触发页面重绘,就是不会记录当前的Widget状态。

这里我们用AutomaticKeepAliveClientMixin来解决,字面意思可以看出这个类是用来保持Widget状态的。 具体的实现是: 将需要存储状态的类继承于AutomaticKeepAliveClientMixin类

然后在当前类中重写AutomaticKeepAliveClientMixin的wantKeepAlive函数,并使它返回true

这样就可以存储当前页面的状态了,其他页面同理。

使用image_picker打开手机相册

这里用了image_picker的ImagePicker类 他有三个静态方法,pickImage,pickVideo和retrieveLostData pickImage是打开手机相册 而这里选择照片又有一下几个参数 source 有cameraImageSource.gallery和ImageSource. 前者是直接打开相册选择,后者是打开摄像头现场拍摄照片进行保存。

maxWidth maxHeight 以上者连个参数不用过多解释是选择图片后的最大宽高。

imageQuality 最后这个参数是选择图片的质量,数值在0到100之间

断点续更(其实就是懒,好久没动Flutter的练手项目了)

是个小坑。先声明一个字符串 String listString = 'a,b,c,d,e,f'。dart的分割字符串和js是同一个api(split)。OK看下我的代码!

listString.split(',').map(item => {}) 是的我们这样写在js上可以正常运行,在Flutter上也没有问题,但是如果过用来渲染一个列表我们需要toList(),这时候会出现语法报错。 我们修改一下写法

List listTest = listString.split(',')

listTest.split(',').map(item => {})

这样就可以个正常的使用toList()导出一个wedgit列表了。具体原因还不清楚,我猜测是在split(',')的时候并没有一个明确的list类型的变量来接收数组,导致无法直接toList()导出。

今天就到这了,又可以偷懒几周了!