随着SDK版本的迭代，Flutter官方已经很好地支持了暗黑模式了，想适配暗黑模式并非是一件难事。本文从最简单基础的写法开始，逐步引入provider、shared_preferences完善暗黑/夜间模式的适配，并提供Demo演示和源代码。[...]
Flutter BouncingScrollPhysics回弹无效、回弹不会恢复原位
ListView内容不足以撑满全屏的情况下：ListView.builder( physics: AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()), // ListView内容不足也能搞出回弹效果 ... );如果是普通的Scaffold套SingleChildScrollView，而内容却不是ListView等滚动组件例如Column支撑不满剩余空间：（暂时没想到更好的解决方式）Scaffold( appBar: AppBar(), body: SingleChildScrollView( physics: AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()), // 添加这一行 child: Container( // 添加这一行，使得SingleChildScrollView填充满；还解决了滑动回弹不会回到原位的问题 constraints: BoxConstraints( minHeight: MediaQuery.of(context).size.height - kToolbarHeight - MediaQuery.of(context).padding.top), child: Column( children: [...] ), ), ), ), NestedScrollView套SingleChildScrollView套Column就正常。如果是CustomScrollView，可以尝试使用SliverFillRemaining充满剩余大小
前言我的Flutter项目有保存图片功能，需要用到相册的访问权限，在IOS那边搞了半个下午的权限配置还是获取不到权限，记录下解决方式。本文所用权限依赖插件：permission_handler，版本8.1.6我仔细排查，网上各种搜索，info.plist配置确定是没有问题的，就很谜。Podfile也参照一些文章配置了也一样不生效（后来才发现有坑）？？之后卸载了，重新Build也还是一样。并且在系统设置里也找不到自己的APP（你可以看到设置里是有其他APP可以配置权限的）。之后查看了下permission_handler官方的配置说明，点开了这个东西：好家伙，权限的配置说明原来在这，之前都没发现（才不是因为都是英文不想看）配置方式打开./ios/Runner/info.plist文件，在标签里插入权限标签，（插入自己需要的权限即可不用全部）全部权限例如：... NSPhotoLibraryUsageDescription App需要您的同意,才能访问相册 NSLocationWhenInUseUsageDescription App需要您的同意,才能在使用期间访问位置 NSLocationAlwaysUsageDescription App需要您的同意,才能始终访问位置 NSCameraUsageDescription App需要您的同意,才能访问相机 NSMicrophoneUsageDescription App需要您的同意,才能访问麦克风 NSLocationUsageDescription App需要您的同意,才能访问位置 NSCalendarsUsageDescription App需要您的同意,才能访问日历 NSRemindersUsageDescription App需要您的同意,才能访问提醒事项 NSMotionUsageDescription App需要您的同意,才能访问运动与健身 NSHealthUpdateUsageDescription App需要您的同意,才能访问健康更新 NSHealthShareUsageDescription App需要您的同意,才能访问健康分享 NSBluetoothPeripheralUsageDescription App需要您的同意,才能访问蓝牙 NSAppleMusicUsageDescription App需要您的同意,才能访问媒体资料库 ... ...打开./iosPodfile文件，找到post_install do |installer|那一行，像下面这样插入代码，或者干脆整个代码块替换掉post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', ## dart: PermissionGroup.photos 'PERMISSION_PHOTOS=1', # 相册权限，这里等于1是启用该权限，等于0是禁用该权限！ 'PERMISSION_CAMERA=1', # 相机权限 # ...其他权限参考官方文档里的IOS配置 end end end检查是否成功在系统设置里找自己的APP，找不到就是失败了；找到的话点进去，就会看到可以配置的权限，像我配置了相册权限就可以看到这个照片的选项。后话详细配置可以查看官方文档。之前看的那些文章都有点旧了，虽然有的给了Podfile的配置但是给权限赋值成了0导致没生效，以后还是得留意官方的文档说明...
关于OAuth2.1 PKCE利用crypto的sha256哈希结果转换base64url计算结果不一致的问题（Flutter）
前言最近在写第三方flutter app并抓包分析某原生app登录逻辑的时候，遇到了使用OAuth2.1 PKCE授权码模式的登录方式，该模式下需要将code_verifier先进行sha256哈希后再进行base64(URL-Save) 编码成最终的code_challenge。OAuth2.1 PKCE授权码模式详解：https://shanhy.blog.csdn.net/article/details/114080598code_verifier转code_challenge的工具：https://tonyxu-io.github.io/pkce-generator/问题详情在对code_verifier进行sha256哈希+base64URL编码后，所得结果与预期的完全不一致；在进行初步对比排查后发现是在base64URL这一步骤出现的差异。并且在使用各种线上工具对已经sha256哈希后的字符串进行base64URL编码，也与预期结果完全不一致。[...]
Flutter调用JSON序列化出现type 'String' is not a subtype of type 'MapString, dynamic'
问题情况本来按照书上的思路都封装好了Dio，半自动生成了Json Model，结果在实际应用上出现了以下异常：Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>'[...]
问题详情：在执行flutter packages pub run build_runner build自动生成JSON序列化模板的时候出现了以下报错：Generator cannot target libraries that have not been migrated to null-safety. package:flutter_test2/model/recommender.dart:6:7 ╷ 6 │ class Recommender { │ ^^^^^^^^^^^ ╵ [INFO] Running build completed, took 1.0s [INFO] Caching finalized dependency graph... [INFO] Caching finalized dependency graph completed, took 41ms [SEVERE] Failed after 1.1s pub finished with exit code 1[...]