文章目录
1.1 界面刷新
ChangeNotifier & ValueListenableBuilder
- 对于局部组件的刷新,不要频繁使用setState()。或者封装成组件在组件内部setState()
RepaintBoundary
减少没有必要的界面刷新
- 案例
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
debugDumpRenderTree();
},
child: Stack(
alignment: Alignment.center,
children: [
CustomPaint(
painter: ClockBgPainter(
radius: 100,
// painter: ClockBgPainter(),
),
),
RepaintBoundary(
child: CustomPaint(
size: Size(widget.radius * 2, widget.radius * 2),
painter: ClockPainter(
radius: 100,
time: time,
),
// painter: ClockBgPainter(),
),
),
],
),
);
}
界面刷新只刷新指针部分,而不对背景部分刷新。在这种情况下,仅仅依靠Stack,分开是起不了作用的。这时需要用到RepaintBoundary分隔开刷新的区域。当子组件需要刷新时,只会刷新需要刷新的部分,不会超出界限。
- 未隔离绘制区域
- 分隔绘制区域后
快速导出组件的图片
- 用RepaintBoundary包裹需要导出的部分
- 定义GlobalKey
GlobalKey boundaryKey = GlobalKey();
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
debugDumpRenderTree();
},
child: Stack(
alignment: Alignment.center,
children: [
CustomPaint(
painter: ClockBgPainter(
radius: 100,
// painter: ClockBgPainter(),
),
),
RepaintBoundary(
key: boundaryKey,
child: CustomPaint(
size: Size(widget.radius * 2, widget.radius * 2),
painter: ClockPainter(
radius: 100,
time: time,
),
// painter: ClockBgPainter(),
),
),
],
),
);
- 得到Image
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
RenderRepaintBoundary renderRepaintBoundary =
boundaryKey.currentContext?.findRenderObject()
as RenderRepaintBoundary;
OutputUtil.captureImage(renderRepaintBoundary, context);
},
),
body: Center(child: ClockWidget(100)),
);
///捕获组件图片
static void captureImage(
RenderRepaintBoundary? boundary,
BuildContext context,
) async {
double dpr = View.of(context).devicePixelRatio;
var image = await boundary!.toImage(pixelRatio: dpr);
_saveImage(image, "imageName");
}
1.2 图片大小
ResizeImage
import 'package:bilibili_getx/ui/shared/image_asset.dart';
import 'package:flutter/cupertino.dart';
///需要网络加载的图片,默认给以一张图片
class DefaultFadeImage extends StatelessWidget {
///网络加载的图片地址
final String imageUrl;
final double width;
final double height;
final BoxFit fit;
///更改图片大小(减少内存)
final int scaleK;
const DefaultFadeImage({
super.key,
required this.imageUrl,
this.width = double.infinity,
this.height = double.infinity,
this.fit = BoxFit.cover,
this.scaleK = 1,
});
Widget build(BuildContext context) {
return FadeInImage(
width: width,
height: height,
fit: fit,
placeholderFit: BoxFit.cover,
placeholderErrorBuilder: (ctx, error, track) {
return Image.asset(ImageAssets.icUpperVideoDefaultPNG);
},
placeholder: AssetImage(ImageAssets.icUpperVideoDefaultPNG),
image: ResizeImage(
NetworkImage(imageUrl),
width: View.of(context).physicalSize.width ~/ scaleK,
),
);
}
}
1.3 App包大小及混淆
打包之后的apk包大小极大,是因为把不同的CPU架构都加了进去,此时想要减少安装包的大小可以采用命令行打包
flutter build apk --obfuscate --split-debug-info=. --target-platform android-arm,android-arms,android-x64 --split-per-abi --no-tree-shake-icons
- obfuscate 混淆
- split-debug-info Flutter应用大小
- target-platform 针对不同CPU架构分别生成apk包
- no-tree-shake-icons 打包时报出一个警告,建议加上