Flutter Boost
场景: iOS
使用 v1.12.13+hotfix.9
版本根据官方 Option B 集成方式集成,可以运行但在 iOS
主工程 archive
的时候发生如下错误: ld: bitcode bundle could not be generated because
ld: bitcode bundle could not be generated because '/Users/n/Library/Developer/Xcode/DerivedData/host_ios-bnbwehcmdjzqgydxspnsnfifvdyh/Build/Intermediates.noindex/ArchiveIntermediates/host_ios/BuildProductsPath/Release-iphoneos/shared_preferences.framework/shared_preferences' was built without full bitcode. All frameworks and dylibs for bitcode must be generated from Xcode Archive or Install build file '/Users/n/Library/Developer/Xcode/DerivedData/host_ios-bnbwehcmdjzqgydxspnsnfifvdyh/Build/Intermediates.noindex/ArchiveIntermediates/host_ios/BuildProductsPath/Release-iphoneos/shared_preferences.framework/shared_preferences' for architecture arm64
分析问题:
分析
v1.12.13+hotfix.9
生成的framework
,发现是不支持bitcode
的,而将Flutter
升级到1.7.0 stable channel
是支持bitcode
的。
解决方案:
将
Flutter
尝试升级到1.7.0 stable channel
或是最新的master channel
可以成功archive
。-
如果
Flutter
项目中有插件需要依赖于v1.12.13
版本,可以先尝试先关闭工程的Enable Bitcode
。如果是私有组件来集成
flutter
可以把组件和主工程的Enable Bitcode
都设置为 NO.
ListView 维护状态的问题
问题:ListView在滚动的时候会将滚出 viewport 的相关的 element 树, status 和 render objects 会销毁。
解决方案:
使用CustomScrollView
混合 AutomaticKeepAliveClientMixin 重写 wantKeepAlive。该套方案可以封装成一个 widget
class AliveKeeper extends StatefulWidget {
final Widget child;
const AliveKeeper({Key key, @required this.child}) : super(key: key);
@override
_AliveKeeperState createState() => _AliveKeeperState();
}
class _AliveKeeperState extends State<AliveKeeper>
with AutomaticKeepAliveClientMixin<AliveKeeper> {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return widget.child;
}
}
ListView 默认顶部内边距问题
问题: 如果导航栏不存在,创建的 ListView 系统会默认增加 20 内边距。文档上已有说明
解决方案:
- 设置 ListView padding zero
- MediaQuery.removePadding
ListView 在水平方向滑动,高度如何做到自适应
分析:由于 ListView 的 children 都是懒加载的,即无法知道 children 的高度,如果确实需要实现这一点首先要确认元素并不是非常多,可以使用 SingleChildScrollView + Row 即没有懒加载的方式来实现。
ListView 在垂直方向滑动,高度如何做到自适应
将 ListView 的 shrinkWrap 为 true,然后将滚动效果关闭。但是需要注意一旦设置了 shrinkWrap 性能开销会较大。
vsync 重复创建问题
在使用动画时候, 如果使用 SingleTickerProviderStateMixin 进行混合则下次重新创建就会报错,可以使用TickerProviderStateMixin 来替代。
如何实现负的内边距?
Flutter 是不支持负的内边距的,但是有两种方式可以模拟实现
transform: Matrix4.translationValues(0.0, -50.0, 0.0)
Stack(overflow: Overflow.visible) + Positioned
Positioned Widget 既想水平居中,又想使用 top 或 bootom 等属性来调整垂直方向的位置如果实现?
调整 Stack 的 alignment 参数来保持水平方向对齐,Positioned 的 child 通过 top 或 bootom 等属性来调整垂直方向位置。
Stack(
alignment: Alignment.bottomCenter,
children: [
_buildImagesBody(),
_buildImageIndex(),
_buildTextInfo(),
],
),
状态栏风格管理
AppBar 自身是可以通过
brightness
属性来管理的。如果页面中没有使用
AppBar
我封装了一个Widget
可供使用。每个页面都可以独立进行管理相应的状态风格。
enum StatusBarStyleType {
dark,
light,
}
class StatusBarStyle extends StatelessWidget {
final StatusBarStyleType type;
final Widget child;
const StatusBarStyle({
Key key,
@required this.child,
this.type = StatusBarStyleType.dark,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final SystemUiOverlayStyle overlayStyle = type == StatusBarStyleType.dark
? SystemUiOverlayStyle.dark
: SystemUiOverlayStyle.light;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: overlayStyle,
child: child,
);
}
}