LoginSignup
8
1

More than 5 years have passed since last update.

[Flutter]画面全体のどこをタップしてもイベント(主にアニメーション)を実行させる方法

Posted at

この記事は全部俺 Advent Calendar 2018の9日目の記事です。
毎回毎回調べ直している気がするので書きました。

やりたいこと

animation_button.gif animation_screen.gif

左のようなボタンを押して起きるイベントを、右のように画面のどこをタップしてもできるようにします。

ソースコード

ボタンでイベント発火するソースコード

fade_in_with_button.dart
import 'package:flutter/material.dart';

class FadeInPage extends StatefulWidget {
  @override
  _FadeInPageState createState() => _FadeInPageState();
}

// The State class is responsible for two things: holding some data we can
// update and building the UI using that data.
class _FadeInPageState extends State<FadeInPage> {
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:Text("Fade in / Fade out by toggle button"),
      ),
      body: Center(
        child: AnimatedOpacity(
          // If the Widget should be visible, animate to 1.0 (fully visible). If
          // the Widget should be hidden, animate to 0.0 (invisible).
          opacity: _visible ? 1.0 : 0.0,
          duration: Duration(milliseconds: 500),
          // The green box needs to be the child of the AnimatedOpacity
          child: Container(
            width: 200.0,
            height: 200.0,
            color: Colors.green,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Make sure we call setState! This will tell Flutter to rebuild the
          // UI with our changes!
          setState(() {
            _visible = !_visible;
          });
        },
        tooltip: 'Toggle Opacity',
        child: Icon(Icons.flip),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

floatingActionButton内にonPressedイベントを定義することでイベントを実行することを可能にしています。
ここでは_visibleのトグルを行っています。

画面全体のどこを押してもイベント発火するサンプルコード

fade_in_whole_screen.dart
import 'package:flutter/material.dart';

class FadeInPage extends StatefulWidget {
  @override
  _FadeInPageState createState() => _FadeInPageState();
}

// The State class is responsible for two things: holding some data we can
// update and building the UI using that data.
class _FadeInPageState extends State<FadeInPage> {
  // Whether the green box should be visible or invisible
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Fade in / Fade out by whole screen"),
        ),
        body: GestureDetector(
            behavior: HitTestBehavior.opaque,
            child: Center(
              child: AnimatedOpacity(
                // If the Widget should be visible, animate to 1.0 (fully visible). If
                // the Widget should be hidden, animate to 0.0 (invisible).
                opacity: _visible ? 1.0 : 0.0,
                duration: Duration(milliseconds: 500),
                // The green box needs to be the child of the AnimatedOpacity
                child: Container(
                  width: 200.0,
                  height: 200.0,
                  color: Colors.green,
                ),
              ),
            ),
            onTap: () {
              setState(() {
                _visible = !_visible;
              });
            }));
  }
}

body部分全体をGestureDetectorで囲い、先程のソースコード内のonPressedに定義されていた内容をonTapに記載します。
肝になるのが、behavior: HitTestBehavior.opaqueという部分です。
ここを記載しない場合、GestureDetectorのデフォルトのbehaviorが使用されますが、デフォルトではbehavior: HitTestBehavior.deferToChildという挙動になります。
このデフォルト挙動は、子要素がタップされたときにイベントを発火させるというものなので、デフォルトでは画面全体をタップしてもイベント発火はしません。(画面上の緑色四角部分をタップするとイベント発火します。)

ソースコード全体はここにおいてあります。

参考文献

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1