2017-11-25 2 views
1

私は、心理的反応時間テスト用のアプリケーションを作成する必要があります。この目的のために、画像がいつ表示されるかを正確に制御しなければならず、画像の可視性の開始と反応の開始(例えば、タップ事象)との間の遅延を正確に測定しなければならない。 Flutterでどのように達成できますか?具体的には、複数の異なる画像を同じ場所に表示したり非表示にする最も効率的な方法は何ですか?また、フレームを考慮した実際の視界と完全な視界の開始に関するタップイベントの開始を正確に知る方法デバイスのレート?そのプロセスを低レベルで制御する方法はありますか?フラッターは、通常、高レベルのAPIを公開するようです。Flutterアプリケーションでの画像とユーザー反応の正確なタイミング

答えて

3

私は次のように私のロジックがあり、あなたが探しているまさに可能性がある試みを行った。

  1. が提示されている画像にリスナーを追加します。
  2. Stopwatchクラスを使用して、画像が表示されたら、オブジェクトに時間をカウントするように通知します。
  3. 正解をクリックすると、Stopwatchのカウントを停止します。
  4. 現在のスコアを保存し、次の質問に進む。

注:この例では

  • 、簡略化のために、私は答えが正しいとされていない対象のアカウントを作成していませんでした。
  • 私はを使って各質問を保持するために新しいStatelessWidgetを作成します。

簡単な例:

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; 

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

    @override 
    _TimeTestState createState() => new _TimeTestState(); 
} 

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

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

    @override 
    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:() { 
        ///TODO 
        ///add conditions for correct or incorrect answers 
        ///and some manipulation on the score 
        timer.stop(); 
        score = score + timer.elapsedMilliseconds; 
        print(score); 
        _scaffoldKey.currentState.showSnackBar(new SnackBar(
         content: new Text(
          "Your answered this question in ${timer 
           .elapsedMilliseconds}ms"))); 

        ///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 { 
    @override 
    Widget build(BuildContext context) { 
    return new TimeTest(question: "Which animal is in this photo?", 
     questionImage: new NetworkImage(
      "http://cliparting.com/wp-content/uploads/2016/09/Tiger-free-to-use-clipart.png"), 
     answers: ["Lion", "Tiger", "Cheetah"], 
     nextQuestionWidget: new QuestionTwo(),); 
    } 
} 

class QuestionTwo extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new TimeTest(question: "Which bird is in this photo?", 
     questionImage: new NetworkImage(
      "http://www.clker.com/cliparts/P/q/7/9/j/q/eagle-hi.png"), 
     answers: ["Hawk", "Eagle", "Falcon"], 
     nextQuestionWidget: new ResultPage(),); 
    } 
} 

class ResultPage extends StatelessWidget { 
    @override 
    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())); 
} 
+0

Grrrrrreat !!!!! – Michael

+0

このソリューションは、新しいルートを画面上にプッシュします。それはルートの多数のメモリリークのようなものではありません。私はむしろ既存のイメージを置き換えたいと思います。どうすればそれを実現できますか? – Michael

+0

pushReplacementは、ウィジェット全体を置き換えるため、使用しません。単に画像を交換し、表示されたときに正確に通知することは可能ですか? – Michael

関連する問題