Created
January 13, 2020 03:22
-
-
Save 410063005/3293c1faa78a01a3d0e7b4e2ce12d1af to your computer and use it in GitHub Desktop.
一个统计 Flutter Fps 的 Widget
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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