如何检测堆栈下方小部件上的滚动?

时间:2018-11-19 20:20:59

标签: dart flutter

我试图按照此tutorial实现GuillotineMenu,我设法创建了很棒的动画菜单,但是菜单下方的列表视图无法检测到手势(滚动)。如何将滚动手势发送到列表视图?当我在菜单上使用IgnorePointer时,滚动条起作用,但菜单不起作用。我可以在堆栈上的两个小部件上检测手势吗?

P.S在此代码中,我使用了手势检测器而不是listview

代码:

home.dart

import 'package:Pixelitg/GuillotineMenu.dart';
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      top: false,
      bottom: false,
      child: new Container(
        child: new Stack(
          alignment: Alignment.topLeft,
          children: <Widget>[
            new Page(),
             new GuillotineMenu(),
          ],
        ),
      ),
    );
  }
}

GuillotineMenu:

import 'package:Pixelitg/news.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class GuillotineMenu extends StatefulWidget {
  @override
  _GuillotineMenuState createState() => new _GuillotineMenuState();
}

enum _GuillotineAnimationStatus { closed, open, animating }

class _GuillotineMenuState extends State<GuillotineMenu>
    with SingleTickerProviderStateMixin {
  double pi = 22 / 7;
  String _title = "Our Work";
  AnimationController animationControllerMenu;
  Animation<double> animationMenu;
  Animation<double> animationTitleFadeInOut;
  _GuillotineAnimationStatus menuAnimationStatus =
      _GuillotineAnimationStatus.closed;
  double rotationAngle = 0.0;
  _handleMenuOpenClose() {
    if (menuAnimationStatus == _GuillotineAnimationStatus.closed) {
      animationControllerMenu.forward().orCancel;
    } else if (menuAnimationStatus == _GuillotineAnimationStatus.open) {
      animationControllerMenu.reverse().orCancel;
    }
  }

  @override
  void initState() {
    super.initState();

    ///
    /// Initialization of the animation controller
    ///
    animationControllerMenu = new AnimationController(
        duration: const Duration(milliseconds: 1000), vsync: this)
      ..addListener(() {
        setState(() {});
      })
      ..addStatusListener((AnimationStatus status) {
        if (status == AnimationStatus.completed) {
          ///
          /// When the animation is at the end, the menu is open
          ///
          menuAnimationStatus = _GuillotineAnimationStatus.open;
        } else if (status == AnimationStatus.dismissed) {
          ///
          /// When the animation is at the beginning, the menu is closed
          ///
          menuAnimationStatus = _GuillotineAnimationStatus.closed;
        } else {
          ///
          /// Otherwise the animation is running
          ///
          menuAnimationStatus = _GuillotineAnimationStatus.animating;
        }
      });
    animationTitleFadeInOut =
        new Tween(begin: 1.0, end: 0.0).animate(new CurvedAnimation(
      parent: animationControllerMenu,
      curve: new Interval(
        0.0,
        0.5,
        curve: Curves.ease,
      ),
    ));

    animationMenu =
        new Tween(begin: -pi / 2.0, end: 0.0).animate(new CurvedAnimation(
      parent: animationControllerMenu,
      curve: Curves.bounceOut,
      reverseCurve: Curves.bounceIn,
    ));

    ///
    /// Initialization of the menu appearance animation
    ///
    new Tween(begin: -pi / 2.0, end: 0.0).animate(animationControllerMenu);
  }

  @override
  void dispose() {
    animationControllerMenu.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    MediaQueryData mediaQueryData = MediaQuery.of(context);
    double screenWidth = mediaQueryData.size.width;
    double screenHeight = mediaQueryData.size.height;

    return new Material(
      color: Colors.transparent,
      child: new Transform.rotate(
        angle: animationMenu.value,
        origin: new Offset(24.0, 56.0),
        alignment: Alignment.topLeft,
        child: Container(
          width: screenWidth,
          height: screenHeight,
          color: Color(0xFF333333),
          child: new Stack(
            children: <Widget>[
              _buildMenuTitle(),
              _buildMenuIcon(),
              _buildMenuContent(),
            ],
          ),
        ),
      ),
    );
  }

  ///
  /// Menu Title
  ///
  Widget _buildMenuTitle() {
    double screenWidth = MediaQuery.of(context).size.width;
    return new Positioned(
      top: 32.0,
      left: 40.0,
      width: screenWidth,
      height: 24.0,
      child: new Transform.rotate(
          alignment: Alignment.topLeft,
          origin: Offset.zero,
          angle: pi / 2.0,
          child: new Center(
            child: new Container(
              width: double.infinity,
              height: double.infinity,
              child: new Opacity(
                opacity: animationTitleFadeInOut.value,
                child: new Text(_title,
                    textAlign: TextAlign.center,
                    style: new TextStyle(
                      color: Colors.white,
                      fontSize: 20.0,
                      fontWeight: FontWeight.bold,
                      letterSpacing: 2.0,
                    )),
              ),
            ),
          )),
    );
  }

  ///
  /// Menu Icon
  ///
  Widget _buildMenuIcon() {
    return new Positioned(
      top: 32.0,
      left: 4.0,
      child: new IconButton(
        icon: const Icon(
          Icons.menu,
          color: Colors.white,
        ),
        onPressed: _handleMenuOpenClose,
      ),
    );
  }

  ///
  /// Menu content
  ///
  Widget _buildMenuContent() {
    final List<Map> _menus = <Map>[
      {
        "icon": Icons.work,
        "title": "Our Work",
      },
      {
        "icon": FontAwesomeIcons.plusSquare,
        "title": "Services",
      },
      {
        "icon": Icons.view_agenda,
        "title": "News Feed",
      },
      {
        "icon": Icons.person,
        "title": "Our Team",
      },
      {
        "icon": FontAwesomeIcons.phoneVolume,
        "title": "Contact Us",
      },
    ];

    return new Padding(
      padding: const EdgeInsets.only(left: 64.0, top: 96.0),
      child: new Container(
        width: double.infinity,
        height: double.infinity,
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: _menus.map((menuItem) {
            return new FlatButton(
              child: ListTile(
                leading: new Icon(
                  menuItem["icon"],
                  color:
                      menuItem["title"] == _title ? Colors.cyan : Colors.white,
                ),
                title: new Text(
                  menuItem["title"],
                  style: new TextStyle(
                      color: menuItem["title"] == _title
                          ? Colors.cyan
                          : Colors.white,
                      fontSize: 24.0),
                ),
              ),
              onPressed: () {
                setState(() {
                  _title = menuItem["title"];
                  _handleMenuOpenClose();
                });
              },
            );
          }).toList(),
        ),
      ),
    );
  }
}

class Page extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        child: Container(
          padding: const EdgeInsets.only(top: 90.0),
          child: News(),
        ),
        onDoubleTap: (){print('object');},
      ),
    );
  }
}

0 个答案:

没有答案