Michael Michael - 3 years ago 219
Dart Question

Exact timing of the display of images and user reactions in Flutter applications

I have to create an app for psychological reaction time testing. For that purpose I have to control exactly when an image is
visible and exactly measure the delay between the onset of the visibility of the image and the onset of the reaction (e.g. tap event).
How can I achieve that in Flutter? Specifically, what is the most efficient way to show and hide several different images in the same place and how can I exactly know the onset of the tap event in relation to the onset of the real and full visibility to the user taking into consideration the frame rate of the device? Is there way to get low-level control over that process. Flutter seems to expose a high-level api, usually.

Answer Source

I have made an attempt that is possibly exactly what you are looking for, my logic is as follows:

  1. Add a listener to the image being presented.
  2. Using Stopwatch class, I notify my object to start counting time once the image is displayed.
  3. When clicking on the correct answer, I stop my Stopwatch to stop counting.
  4. Save my current score, and carry on to the next question.


  • In this example, for the sake of simplicity, I did not make an account for which answer is correct and which is not.
  • I create a new StatelessWidget to hold each question, using PageView.builder might be a good use here as well.

Simple Example:

enter image description here

import 'dart:async';

import 'package:flutter/material.dart';

int score = 0;

class TimeTest extends StatefulWidget {
  Widget nextQuestionWidget; //to navigate
  String question;
  NetworkImage questionImage;
  List<String> answers;

      {this.questionImage, this.question, this.answers, this.nextQuestionWidget });

  _TimeTestState createState() => new _TimeTestState();

class _TimeTestState extends State<TimeTest> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  bool _loading = true;
  Stopwatch timer = new Stopwatch();

  void initState() {
    widget.questionImage.resolve(new ImageConfiguration()).addListener((_, __) {
      if (mounted) {
        setState(() {
          _loading = false;

  Widget build(BuildContext context) {
    return new Scaffold(
      key: _scaffoldKey,
      appBar: new AppBar(title: new Text("Time Test"),),
      body: new Container(
        alignment: FractionalOffset.center,
        margin: const EdgeInsets.symmetric(vertical: 15.0),
        child: new Column(
          children: <Widget>[
            new Text(widget.question),
            new Divider(height: 15.0, color: Colors.blueAccent,),
            new CircleAvatar(backgroundImage: widget.questionImage,
              backgroundColor: Colors.transparent,),
            new Container(height: 15.0,),
            new Column(
              children: new List.generate(widget.answers.length, (int index) {
                return new FlatButton(
                  onPressed: () {
                    ///add conditions for correct or incorrect answers
                    ///and some manipulation on the score
                    score = score + timer.elapsedMilliseconds;
                    _scaffoldKey.currentState.showSnackBar(new SnackBar(
                        content: new Text(
                            "Your answered this question in ${timer

                    ///Hold on before moving to the next question
                    new Future.delayed(const Duration(seconds: 3), () {
                      Navigator.of(context).push(new MaterialPageRoute(
                          builder: (_) => widget.nextQuestionWidget));
                  }, child: new Text(widget.answers[index]),);


class QuestionOne extends StatelessWidget {
  Widget build(BuildContext context) {
    return new TimeTest(question: "Which animal is in this photo?",
      questionImage: new NetworkImage(
      answers: ["Lion", "Tiger", "Cheetah"],
      nextQuestionWidget: new QuestionTwo(),);

class QuestionTwo extends StatelessWidget {
  Widget build(BuildContext context) {
    return new TimeTest(question: "Which bird is in this photo?",
      questionImage: new NetworkImage(
      answers: ["Hawk", "Eagle", "Falcon"],
      nextQuestionWidget: new ResultPage(),);

class ResultPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("Result"),),
      body: new Center(
        child: new Text("CONGRATULATIONS! Your score is $score milliseconds"),),
void main() {
  runApp(new MaterialApp(home: new QuestionOne()));
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download