Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@410063005
Created January 13, 2020 03:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 410063005/3293c1faa78a01a3d0e7b4e2ce12d1af to your computer and use it in GitHub Desktop.
Save 410063005/3293c1faa78a01a3d0e7b4e2ce12d1af to your computer and use it in GitHub Desktop.
一个统计 Flutter Fps 的 Widget
import 'dart:async';
import 'dart:collection';
import 'dart:ui';
import 'package:flutter/material.dart';
/// https://gist.github.com/yrom/ac4f30b26ee02ce3bd3a1d260bb9ffb4
const maxframes = 60;
const frameInterval =
const Duration(microseconds: Duration.microsecondsPerSecond ~/ 60);
class FpsWidget extends StatefulWidget {
final Color textColor;
const TipFpsWidget({Key key, this.textColor = Colors.red}) : super(key: key);
@override
State<StatefulWidget> createState() => _TipFpsWidgetState();
}
class _TipFpsWidgetState extends State<TipFpsWidget> {
StreamController<num> _controller;
TextStyle _textStyle;
final lastFrames = ListQueue<FrameTiming>(maxframes);
@override
void initState() {
super.initState();
_textStyle = TextStyle(color: widget.textColor);
_controller = StreamController<num>();
WidgetsBinding.instance.addTimingsCallback(onReportTimings);
}
@override
void dispose() {
super.dispose();
lastFrames.clear();
WidgetsBinding.instance.removeTimingsCallback(onReportTimings);
_controller.close();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _controller.stream,
builder: (BuildContext context, AsyncSnapshot<num> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Text('加载中...');
} else if (snapshot.connectionState == ConnectionState.done) {
return Text('已结束.');
} else if (snapshot.connectionState == ConnectionState.active) {
return Text(
'fps: ${snapshot.data.toStringAsFixed(1)}',
style: _textStyle,
);
} else {
return Text('已结束');
}
});
}
void onReportTimings(List<FrameTiming> timings) {
for (FrameTiming timing in timings) {
lastFrames.addFirst(timing);
}
while (lastFrames.length >= maxframes) {
lastFrames.removeLast();
}
if (_controller != null) {
_controller.add(fps);
}
}
double get fps {
var lastFramesSet = <FrameTiming>[...lastFrames];
// for (FrameTiming timing in lastFrames) {
// if (lastFramesSet.isEmpty) {
// lastFramesSet.add(timing);
// } else {
// var lastStart =
// lastFramesSet.last.timestampInMicroseconds(FramePhase.buildStart);
// if (lastStart -
// timing.timestampInMicroseconds(FramePhase.rasterFinish) >
// (frameInterval.inMicroseconds * 2)) {
// // in different set
// break;
// }
// lastFramesSet.add(timing);
// }
// }
var frameCount = lastFramesSet.length;
var costCount = lastFramesSet.map((t) {
return (t.totalSpan.inMicroseconds ~/ frameInterval.inMicroseconds) + 1;
}).fold(0, (a, b) => a + b);
return frameCount * 60 / costCount;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment