手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:Flutter

flutter 中 getx 如何监听list

 正常情况下,我们都知道,flutter使用getx的时候,只要在Obx方法中都可以监听变量的变更,同时会局部刷新Obx包裹的Widget,但如果GetxController绑定的变量是list的时候,你会发现,无论你怎么 处理,Widget都不刷新。

有个最简单的办法:在设置变量的时候,同时让他refresh一下。比如:

count.value.add(1);

count.refresh();

这时候再看Widget就都更新了。

纯记录

'MACOSX_DEPLOYMENT_TARGET' is set to 10.6, but the range of supported deployment target versions is 10.9 to 12.3.99.

在开发flutter的macOS版时,报这个错误:./macos/Pods/Pods.xcodeproj: warning: The macOS deployment target 'MACOSX_DEPLOYMENT_TARGET' is set to 10.6, but the range of supported deployment target versions is 10.9 to 12.3.99. 

可以很明确的看到文件是:/macos/Pods/Pods.xcodeproj,虽然这个warning并不影响程序的运行,看确实看了不舒服,于是打开/macos/Pods/Pods.xcodeproj,搜索:MACOSX_DEPLOYMENT_TARGET,一共有3处,将他对应的值10.6,修改为10.9,问题解决。

 

flutter 如何设置桌面APP的最小宽高

 在Windows和MacOs上面程序的宽高是可以随便拖拉的,不象ios/android,总归是一定固定的宽高。为了保证部分输入框或者界面在拖拉时不会UI越界,所以就要设定一个最小宽高。当然你要为了保险,你可以  强制设定最小值和最大值一致,也就是让APPi窗口固定大小。但一般我们都只是限定最小值。。。毕竟,最大的话,丑就丑了(反正我没有UI设计师)

基于此,官方的flutter-desktop--embedding有一个插件:window_size,由于他没有发布到pub.dev,因此只能通过手动改pubspec.yml方法来进行加载

修改:pubspec.yml,在dependencies下增加:

XML/HTML代码
  1. window_size:  
  2.   git:  
  3.     url: https://github.com/google/flutter-desktop-embedding.git  
  4.     path: plugins/window_size  
  5.     ref: a738913c8ce2c9f47515382d40827e794a334274  

 

ref的话,可以直接去github上看,用最新的即可。

然后可以在runApp前进行判断,最简单的办法就是2行代码:

XML/HTML代码
  1. if(Platform.isMacOS || Platform.isWindows) {  
  2.     if( MediaQueryData.fromWindow(window).size.width < 640 ||  MediaQueryData.fromWindow(window).size.height < 480){  
  3.         window_size.setWindowSize(const Size(640,480))  
  4.     }  
  5. }  

 

当然实际情况得从自身出发,不能这样随意。。

参考:

1、flutter桌面版开发设置窗口大小(最小尺寸、最大尺寸、固定尺寸),窗口标题。 | 码海无涯 (yefei572.github.io)

2、flutter-desktop-embedding/README.md at master · google/flutter-desktop-embedding (github.com)

后续就要看看这个什么时候更新了:flutter-desktop-embedding/plugins/menubar at master · google/flutter-desktop-embedding (github.com),这个一更新。menubar就可以派用场了。

 ---EOF

后记:目前还没有判断窗口resize的事件,理论上应该要判断这个。后面会尝试加上

flutter打包android apk和macos等步骤

 用flutter开发后要打包时,需要对项目目录进行微调

1、android,要将keystore进行注册和设置,如果有开发中对minSdkVersion有过微调,这里就不用管了。毕竟每个项目都不一样,但keystore可以一样
   参考:Android平台签名证书(.keystore)生成指南 - DCloud问答生成keystore。
   其实就是一句:keytool -genkey  -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore -alias testalias
   这里面看着keystore和alias,因为最终要在flutter里设置这两个玩意
 
   OK,生成完后,在flutter项目的android下创建:key.properties,输入4行
XML/HTML代码
  1. storePassword=123456  
  2. keyPassword=123456  
  3. keyAlias=testalias  
  4. storeFile=/Users/gouki/test.keystore  
keyAlias,对应了刚才上面的-alias,storeFile,对应了实际路径,可以在项目外,反正只要能够访问得到。
 
然后修改build.gradle,参考 localProperties的写法,加入:
XML/HTML代码
  1. def keystorePropertiesFile = rootProject.file("key.properties")  
  2. def keystoreProperties = new Properties()  
  3. keystoreProperties.load(new FileInputStream(keystorePropertiesFile))  
然后找到buildTypes,会发现里面一有一句:signingConfig signingConfigs.debug,其实你搜索整个文件,都找不到signingConfigs这个节点。所以理所当然的,将debug改成release,在和buildTypes的同级,增加:
XML/HTML代码
  1. signingConfigs {  
  2.     release {  
  3.         keyAlias keystoreProperties['keyAlias']  
  4.         keyPassword keystoreProperties['keyPassword']  
  5.         storeFile file(keystoreProperties['storeFile'])  
  6.         storePassword keystoreProperties['storePassword']  
  7.     }  
  8. }  
保存,然后flutter build apk 即可。
Running Gradle task 'assembleRelease'...                           43.0s
✓  Built build/app/outputs/flutter-apk/app-release.apk (32.9MB).
 
 
2、macos ,相对更方便了,如果没有特殊的调整,其实基本上在开发的时候都有修改过了,即:在macos/Runner下,修改DebugProfile.entitlements和Release.entitlements,增加:
XML/HTML代码
  1. <key>com.apple.security.network.server</key>  
  2. <true/>  
  3. <key>com.apple.security.network.client</key>  
  4.    <true/>  
否则,读取不了网络。。
 
flutter build macos
 
---
最后打完后一看。。。我10M左右的assets,最终打完包:
android apk  32.9M
macos   xxx.app 55.6M
 
项目完成,这是我第一次完整的写完一个flutter项目(还差一个自动更新)。之前都是用uniapp打包的。
代码还没有优化,当然其实在写的过程中已经反复过好几次了,有为了性能上的,有为了显示上的,但怎么说,完成比完美更重要。如果没有完成,天天完善,最后一个APP都出不来。。。完成了,还有机会去完善(虽然可能只是口号)。。。
 
 
 
 
  

花了半天时间实现了flutter swiper。

在学习flutter的过程中,遇到了几个对我来说难度有点大的问题,比如swiper、弹出菜单(含子菜单)等。所幸都一一实现了。

 
swiper的实现相对比较简单,其实就相当于是两个模块:1、pagination 2、实际滚动内容
1的话其实相对简单,只是一个listview.generate就完事了,不过因为我们中间用了连接字符串,所以当屏幕大小可变时,这个连接字符串的长度就要可控。所以我用了 '--' * 100,然后限制maxLine=1,overflow =clip,就处理完了
 
2、最早没有采用滚动的时候,是使用了图片切换,这时候无论怎么做动画效果都没用,比如AnimatedContainer,无效;AnimatedController也没用。毕竟只是换了一个图片地址,容器大小都没变。所以最后还是尝试采用了SingleChildScrollView,然后复杂的就是做联动了。
做联动经历了3个小阶段
a. 点击pagination,采用_controller.animateTo,这样还有动画跳转,跳转到指定page页面。
b. 滑动图片时的手势操作,这个相对比较简单,我用了genstureDetector,只判断了横向的手指更新和滑动结束。更新的时候,只计算 delta.dx,即横向移动的距离,负值则页数减1,正值加1,这样一页页的跳转就完成了。
c.最复杂的就来了:因为我用的是macos的代码,前面是鼠标手势,如果用触摸板,那么刚才的手势就完全无效了,而且触摸板滚动的距离非常长可能一下子会有5~6页,整个下午就卡在这里。
 
第一次尝试,是用_controller.addListener(),确实可以看到 _controller.offset在移动,但addListener只能看到数值在变化,却无法判断停下来。
第二次尝试,是用_controller.position.isScrollingNotifier.addListener,这时候可以判断 !_controller.position.isScrollingNotifier.value,如果无值代表停下来。刚开始还OK,但如果一更新代码,再滚动,立即 报错,说_controller.positions.isNotEmpty 不正常。而且这个listener,是要放在:WidgetsBinding.instance?.addPostFrameCallback中的。所以暂时放弃
第三次尝试:在找了google之后,找到了这里:[Flutter Web] NotificationListener ScrollNotification is bugged with SingleChildScrollView (All possible ScrollNotifications registering on each frame) · Issue #44732 · flutter/flutter (github.com),在ScrollView上包一层NotificationListener,并通过 onNotification进行判断,当scrollNotification is ScrollEndNotification时,获取当前页码并进行跳转。这时候要注意用Future.delayed处理。因为当 跳转新页时,可能 scrollNotification.metrics.pixels还在更新,会导致跳转可能跳一半,变成卡屏效果。而delayed 150ms 之后。还有一个弹回的小效果。
 
至此,全部完成。做个笔记~~~
Records:14123