flutter高级开发,flutter开源项目

Flutter 开发笔记

下面这种情况下,为 InkWell 设置的 splashColor 不会生效:

成都创新互联公司服务项目包括桓仁网站建设、桓仁网站制作、桓仁网页制作以及桓仁网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,桓仁网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到桓仁省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

需要用 Material 去除背景色,然后将颜色设置在 InkWell 外部:

在 Dialog builder 中使用 WillPopScope 禁用返回键返回:

注意:使用此方法同时也会禁用 iOS 上的手势滑动返回功能,推荐判断平台后再使用。

修改对话框中的复选框状态,最简便的方法是通过 Element 中的 markNeedsBuild 方法:

当然,更推荐的做法是通过 StatefulBuilder ,然后就可以在 Dialog 中调用 setState 方法了,不过在调用 setState 时需要判断 Dialog 是否已经关闭,否则会造成 setState() called after dispose() 的错误,可以通过添加一个标志位来解决,如下:

在 Web 中加载网络图片有时会失败,遇到这样的报错: Exception caught by image resource service... ,造成该错误的原因通常是,图片跨域了(见 跨域资源共享 )。最简单的解决办法是, 使用 HTML 渲染加载 ,而不是默认的 CanvasKit。

Flutter 中所有的 list 默认都是没有 ScrollBar 的,必须使用 ScrollBar 组件。ScrollBar 组件通过监听 ScrollView 的 ScrollNotification 来刷新位置,所以 List 的长度必须是固定的。

当使用 WebView 等高度不定的组件时会出现内容被截断的情况,通常可以使用 NestedScrollView 来解决该问题,需要在 WebView 外部嵌套 SingleChildScrollView。

虽然使用了缓存,而且也是用 builder 加载图片的,但是发现一个现象:滑动屏幕后图片短暂消失并重新加载了。图片高度很高时这种现象更加明显,其原因是超出屏幕范围一定距离的组件被重新渲染了。解决方法是在 ListView 上设置 cacheExtent 参数:

该参数的作用是改变超出屏幕高度后继续渲染的范围(以像素为单位),比如设置成 9999 后意味着超出屏幕 10000 像素以内的内容都会被保留下来。

借助 IntrinsicHeight 组件:

另外,IntrinsicHeight 还可以用于 Dialog 或者 BottomSheet 中,使得其中的元素 显示内在元素的高度 ,从而避免元素因为约束的存在而不显示或者高度太高(比如在使用了 Column 或者 Row 的时候)。

在通过 Uri 的 queryParameters 获取 query 参数时,发现有些链接会抛出下面异常:

造成该异常的原因是 Uri 默认使用 utf-8 解码超链接字符串,如果链接中包含非 utf-8 字符,就会造成上面的错误,相关 issue 见: issue #31621 。目前该 issue 处于 open 的状态,暂时的解决办法是,在所有使用到 queryParameter 的地方用 try..catch 捕捉可能抛出的异常。

Flutter 开发非常依赖各种官方或第三方的插件,而在使用这些插件时多少都会遇到一些问题,大部分问题都可以通过搜索和查找 issue 来解决。这里记录下一些我在使用部分插件时遇到的问题及其解决方法。

目前该库没有图片加载完成的回调(见 issue #545 ),不过我们可以通过在 imageBuilder 中来添加回调:

这是一个应用内更新插件,安卓 10 以上安装时需要在 manifest 中添加以下内容:

目前功能最强大的 WebView 插件,基本能满足绝大部分移动端网页加载的需求,而且可定制化程度高。

一般通过 CookieManager 修改 Cookie,拦截请求并修改请求对象的 Header 不会生效。

InAppWebViewOptions 的 userAgent 只在 iOS 上生效,而 applicationNameForUserAgent 只在 Android 上生效,所以最好的做法是分平台设置 InAppWebViewOptions ,而且需要注意,由于设置 userAgent 后会覆盖默认的 UserAgent,所以如果需要在默认的 UserAgent 上添加其它参数,iOS 上需要通过 InAppWebViewController.getDefaultUserAgent() 获取默认 UserAgent 参数,而 Android 不需要添加。

如果图片源或者请求是 http 的,为了在 Android 上正常加载请求,必须在 AndroidInAppWebViewOptions 中将 mixedContentMode 设置为 AndroidMixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW 。

当我们想要设置全屏图片的时候,由于默认的 Constraint 会将图片居中显示,所以图片四周会留有空隙。为了去除这个限制,我们需要 Xcode 中打开 LaunchScreen.storyboard,然后在 View Controller 的 View 和 LaunchImage 上的 Safe Area 去掉。

具体设置方法:右侧 Inspector 面板 Show the Size inspector 解选 Layout Margins 中的 Safe Area Relative Margins,拖动图片占满全屏,然后根据 View Controller Scene 的 Warning,更新 Constraint 就可以了。

在集成某些三方库之后,在使用命令行运行 iOS 模拟器的时候可能会遇到下面这个报错:

这是因为 iOS 模拟器未来将会兼容 arm64 架构,但是目前还不支持,所以我们需要修改 Build Setting 使得能够在 x86_64 的模拟器上运行,操作步骤见 这里 。

flutter开发体验总结

flutter目前最火的混合开发技术,作为苦逼的移动开发人员了解下总是没有错的,针对最近自己的学习,进行相关总结,希望在座的看官,看完此文后,能对flutter移动开发有个大概的了解,希望能给你开发flutter带来个大体的认知,由于学习接触时间不过,如有讲错的地方,请在评论区指出,谢谢;

注:经过多重比较,个人觉得AS是比较适合flutter移动开发的,集成方便,插件支持多,不亏是google大佬的亲儿子,安卓开发人员过渡也比较方便;

程序入口指定,也可以指定为别的widget;

从左往右的功能对应:

在文章开篇的时候,我有提过,在flutter开发里面,可谓一切界面皆是widget,对于安卓开发人员,可以理解为增强版fragment(碎片),基本所有的和界面相关的实现都在当中实现。

说到widget就必须聊到今天一个很重要的主题,StatelessWidget, StatefulWidget,因为大部分界面的实现都需要通过集成他们来实现界面显示。

注:有前端用flex开发使用的经验的同学,完全可以参考flex属性使用。

Flutter开发——Linux嵌入式应用开发

上文中 介绍了Linux平台下Flutter环境搭建和桌面应用开发,现在需要更深入了解如何将该应用运行在Linux系统的嵌入式设备上。

安装及示例

在 ~/.bashrc 中配置 export PATH=$PATH:/opt/flutter-elinux/bin

打开weston虚拟机,此时发现 flutter-elinux devices 连接设备变成两个,如下图

即可编译及运行基于wayland显示后端的demo

避坑

flutter 插件开发

new flutter project,选择Flutter Plugin,next,输入插件名,包名,运行平台及编写语言,finish!

如上图,笔者的插件名为log_plugin,选用Android,java语言开发

在自动打开和插件名同名的dart文件,声明要使用其他语言的方法,本例使用java 语言实现Android原生的log输出

编辑 android/src/main/java/com/whh/log_plugin/LogPlugin.java

在onMethodCall方法中,区别声明方法名,以实现该方法逻辑

至此,简单的插件开发完成,接下来测试

example是插件测试工程,打开其中的main.dart

打开已有的或者新建一个flutter app project,在其pubspec.yaml引入插件

使用pub get 关联到插件

详见官网文档

此文为 flutter 初学者记录学习过程,附上 github ,小小分享~

每天进步一点点。。。(2021-08-10)

Flutter开发--如何布局?

相对于iOS开发,Flutter的布局更具有灵活性,每个页面设计都不一样,相同页面可选择的布局方式也不一样,如果单纯的说应该如何去布局,我觉得不现实,大家可以参考下 Flutter官方的布局教程 。接下来,笔者,通过项目中的一个页面,来一步一步的拆解布局的流程。整个过程,基本上按照拆解、组件封装、具体布局这三步来的。

根据设计图,可以看出整体可以分成两部分,上面一部分是系统介绍模块,下面一部分是真正的登录内容,因为涉及到叠加,因此考虑用Stack;

系统介绍模块部分:整体也是涉及到叠加,考虑用Stack,分为四部分。最底部渐变色背景用一个contanier,无须指定位置,全视图扩展;载放logo图标在上一层,用Image。最后两个Text同级放在最上层。Image,Text各用Positioned包裹去指定位置。

登录内容模块是最外层是一个Contanier容器,去控制背景色和圆角。然后是一个Column元素,逐行排列。

第一行为Image,

第二行为Text,

第三行可以看成一个小Column,分两块进行布局

第四行可以看成一个小Column,分两块进行布局

第五行可以看作一个TextButton,

第六行可以看作一个Row,分三块进行布局

通过上面这样一步一步的分析后,基本上对大致的布局有了一个了解,最外层的控件大致选对(只要能实现的话,就是复杂度以及效率的问题),然后一步一步的拆解每一行的元素,如果有重复的或者觉得可以封装出来的部分,则进行下一步。

每一行的拆解,大致也是按照这个思路来进行,因此笔者在这里就不做讲解了。

在做到第三第四行的时候,发现这两个很相似,而且设计到一些交互逻辑,笔者就想对第三第四行的这种展示进行封装,觉得今后的布局可能会用到,因此在这一步,可以先把这一块儿抽离出一个控件。利用TextField来实现这种输入操作,具体的实现笔者不再详细的描述了。

经过这一步,整体的规划设计图已经有了,各个组件也都有了,接下来的工作就是组装了。

具体布局设计到一些细节的地方,例如整体Column的居中对齐(crossAxisAlignment)、间隔(Padding或Container包裹,笔者更喜欢用SizedBox占位)、居左居右居中(Align)、点击事件(GestureDetector)以及圆角(BorderRadius)等一些特殊情况。

像第六行row是放在底部的,就可以在第六行前面增加一个Spacer()去填充空白区域。

对文字颜色大小等,可以用TextStyle直接设置。

对于输入框的删除按钮,可以用Offstage这种Flutter特有的控制显示隐藏的控件。

Flutter开发--视频播放器

目前Flutter平台主流的两个播放器是video_player和fijkplayer

pub

github

1、Flutter平台官方插件,作者是国外的,有问题沟通比较困难,只能通过提交issue

2、硬解码

4、UI封装: better_player

基于video_player和Chewie的高级视频播放器。它解决了许多典型的用例,并且易于运行。

5、播放器宽高比例与视频内容宽高比例不一致时,会出现图像压缩变形的问题

6、调用原生内核播放器:iOS--AVPlayer, Android--ExoPlayer

7、对于分段源 m3u8 的播放不友好,如果一个切片播放超时,会导致整个播放都失败

8、better_player可以缓存视频,但不能自定义缓存的地址,只能指定key,和缓存的最大内存量(还未研究超出最大的话是不能缓存新的,还是删除最旧的)

9、better_player不能完全自定义UI,只能修改类中的一些开放属性,比如说icon图标,文字颜色啥的

10、无网络有缓存时,封面可以正常展示

11、better_player播放失败有手动retry的设计

pub

github

1、fijkplayer 是一个 Flutter 生态的媒体播放器,是对 ijkplayer 的 Flutter 封装,支持 Android 和 iOS。 fijkplayer 使用 ijkplayer 作为播放器内核,ijkplayer 使用 ffmpeg 进行音视频解封装和解码,同时添加了 Android 和 iOS 平台特有的硬件加速解码能力。

2 、国内有QQ群,但是活跃度也是不高。

3、可以缓存视频,可以自定义缓存的地址,方便后续的内存维护。

4、可以通过FijkPanelWidgetBuilder较大程度上自定义UI。

5、无网络有缓存视频时,无法展示封面,因为内部是通过imageProvider去加载网络图片的。

7、播放失败无手动retry的设计

1、两种播放器都是通过外接纹理方案 (Texture),将播放器视频画面渲染接入 flutter 中,性能上优于 PlatformView 的接入方法。

如何自己实现?

下面以video_palyer的iOS源码部分解释:

iOS用CVPixelBufferRef将渲染出来的数据存在内存中,Flutter engine会将Texture的数据在内存中直接进行映射无需通过Channel传输,然后Texture Widget就可以把你提供的这些数据显示出来。在我们传输数据的时候会需要将其与 TextureID 绑定,绑定的过程通过BasicMessageChannel实现数据流的传输,以做到实时展示的效果


本文标题:flutter高级开发,flutter开源项目
当前URL:http://cdiso.cn/article/hoehph.html

其他资讯