| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:async'; |
| import 'dart:math'; |
| |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/scheduler.dart'; |
| import 'package:flutter_driver/driver_extension.dart'; |
| |
| /// This application shows empty screen until first frame timings are acquired. |
| void main() { |
| enableFlutterDriverExtension(); |
| |
| final Completer<List<FrameTiming>> completer = Completer<List<FrameTiming>>(); |
| SchedulerBinding.instance!.addTimingsCallback((List<FrameTiming> timings) { |
| completer.complete(timings); |
| }); |
| |
| runApp(Directionality( |
| textDirection: TextDirection.ltr, |
| child: _FirstFrameTimings(completer: completer), |
| )); |
| } |
| |
| class _FirstFrameTimings extends StatefulWidget { |
| const _FirstFrameTimings({ |
| Key? key, |
| required this.completer, |
| }) : super(key: key); |
| |
| final Completer<List<FrameTiming>> completer; |
| |
| @override |
| _FirstFrameTimingsState createState() => _FirstFrameTimingsState(); |
| } |
| |
| class _FirstFrameTimingsState extends State<_FirstFrameTimings> { |
| int? _minFrameNumber; |
| |
| @override |
| Widget build(BuildContext context) { |
| widget.completer.future.then(_setMinFrameNumber); |
| if (_minFrameNumber != null) { |
| return Text( |
| _minFrameNumber.toString(), |
| key: const Key('minFrameNumber'), |
| ); |
| } else { |
| return const Text('Waiting...'); |
| } |
| } |
| |
| void _setMinFrameNumber(List<FrameTiming> timings) { |
| final int minFrameNumber = timings |
| .map((FrameTiming timing) => timing.frameNumber) |
| .reduce(min); |
| setState(() { |
| _minFrameNumber = minFrameNumber; |
| }); |
| } |
| } |