在堆栈中颤动,使页面下方可点击

问题描述 投票:2回答:2

我只有一个包含断头台菜单和列表的堆栈。但是页面下方(列表和工厂)不可点击!第一个代码是主页面,第二个代码是书籍(下页),第三个代码是断头台菜单。 如何在页面下方点击?

enter image description here

主页

import 'package:firebase_example/Ui/Books.dart';
import 'package:firebase_example/Ui/GuillotineMenu.dart';
import 'package:flutter/material.dart';

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

class _HomeState extends State<Home> {
  final GlobalKey<ScaffoldState> _drawerKey = new GlobalKey();

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        top: false,
        bottom: false,
        child: new Container(
          child: new Stack(
            alignment: Alignment.topLeft,
            children: <Widget>[
              Books(),
              GuillotineMenu(),
            ],
          ),
        ),
      ),
    );
android dart flutter
2个回答
2
投票

你要找的是IgnorePointer。通过使用它,您应该能够从命中测试中排除您的小部件(因此允许触摸它下面的内容)。

您将不得不小心如何实现使断条菜单打开/关闭的按钮。我建议将它作为堆栈中较低项目的一部分,然后在断头台关闭时设置IgnorePointer的ignoring = true

请注意,使用PageRoutes可能有一种“更好”的方式来实现断头台菜单。这样你就可以在现有导航器上推送/弹出一条新路线,而不必维护自己的堆栈。

这是代码:

class GuillotinePageRoute<T> extends PageRoute<T> {
  GuillotinePageRoute({
    @required this.builder,
    RouteSettings settings: const RouteSettings(),
    this.maintainState: true,
    bool fullscreenDialog: false,
  })  : assert(builder != null),
        super(settings: settings, fullscreenDialog: fullscreenDialog);

  final WidgetBuilder builder;

  @override
  final bool maintainState;

  @override
  Duration get transitionDuration => const Duration(milliseconds: 500);

  @override
  Color get barrierColor => null;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    final Widget result = builder(context);
    assert(() {
      if (result == null) {
        throw new FlutterError('The builder for route "${settings.name}" returned null.\n'
            'Route builders must never be null.');
      }
      return true;
    }());
    return result;
  }

  @override
  Widget buildTransitions(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    MediaQueryData queryData = MediaQuery.of(context);

    var topInset = queryData.padding.top;

    Offset origin = Offset((kToolbarHeight / 2.0), topInset + (kToolbarHeight / 2.0));

    Curve curve = animation.status == AnimationStatus.forward ? Curves.bounceOut : Curves.bounceIn;
    var rotateTween = new Tween(begin: -pi / 2.0, end: 0.0);

    Cubic opacityCurve = Cubic(0.0, 1.0, 0.0, 1.0);

    return new AnimatedBuilder(
      animation: animation,
      child: child,
      builder: (context, child) {
        return Opacity(
          opacity: opacityCurve.transform(animation.value),
          child: Transform(
            transform: Matrix4.identity()..rotateZ(rotateTween.lerp(curve.transform(animation.value))),
            origin: origin,
            child: child,
          ),
        );
      },
    );
  }

  @override
  String get barrierLabel => null;
}

并在一个例子中使用它:

import 'dart:math';

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MenuPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(children: [
      AppBar(
        leading: new IconButton(icon: Icon(Icons.menu), onPressed: () => Navigator.pop(context)),
        elevation: 0.0,
      ),
      Expanded(
        child: Container(
          child: Center(
            child: Text(
              "Menu page!",
              style: TextStyle(color: Colors.white, decoration: TextDecoration.none),
            ),
          ),
          color: Colors.blue,
        ),
      ),
    ]);
  }
}

class MyHomePage extends StatelessWidget {
  void pushGuillotine(BuildContext context, WidgetBuilder builder) {
    Navigator.push(context, new GuillotinePageRoute(builder: builder));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("This is a title"),
        leading: new RotatedBox(
          quarterTurns: -1,
          child: IconButton(icon: Icon(Icons.menu), onPressed: () => pushGuillotine(context, (context) => MenuPage())),
        ),
      ),
      body: Container(
        color: Colors.blueGrey,
        child: Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Text(
                'This is the home page.',
              ),
              new Text(
                'Hello world!',
                style: Theme.of(context).textTheme.display1,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class GuillotinePageRoute<T> extends PageRoute<T> {
  GuillotinePageRoute({
    @required this.builder,
    RouteSettings settings: const RouteSettings(),
    this.maintainState: true,
    bool fullscreenDialog: false,
  })  : assert(builder != null),
        super(settings: settings, fullscreenDialog: fullscreenDialog);

  final WidgetBuilder builder;

  @override
  final bool maintainState;

  @override
  Duration get transitionDuration => const Duration(milliseconds: 500);

  @override
  Color get barrierColor => null;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    final Widget result = builder(context);
    assert(() {
      if (result == null) {
        throw new FlutterError('The builder for route "${settings.name}" returned null.\n'
            'Route builders must never be null.');
      }
      return true;
    }());
    return result;
  }

  @override
  Widget buildTransitions(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    MediaQueryData queryData = MediaQuery.of(context);

    var topInset = queryData.padding.top;

    Offset origin = Offset((kToolbarHeight / 2.0), topInset + (kToolbarHeight / 2.0));

    Curve curve = animation.status == AnimationStatus.forward ? Curves.bounceOut : Curves.bounceIn;
    var rotateTween = new Tween(begin: -pi / 2.0, end: 0.0);

    Cubic opacityCurve = Cubic(0.0, 1.0, 0.0, 1.0);

    return new AnimatedBuilder(
      animation: animation,
      child: child,
      builder: (context, child) {
        return Opacity(
          opacity: opacityCurve.transform(animation.value),
          child: Transform(
            transform: Matrix4.identity()..rotateZ(rotateTween.lerp(curve.transform(animation.value))),
            origin: origin,
            child: child,
          ),
        );
      },
    );
  }

  @override
  String get barrierLabel => null;
}

0
投票

如果您有一个没有交互的小部件并且想要使其可点击,请使用GestureDetector小部件作为父级,您可以在链接中看到该示例。

---编辑

这个答案可以帮助你,当你需要制作一个没有互动的小部件有一些,不完全是这个问题是什么谈论,诚实的错误,但我可以帮助别人..

© www.soinside.com 2019 - 2024. All rights reserved.