展开时,Flutter Interactive Viewer 子项不在堆栈顶部

Flutter Interactive Viewer child not on top of stack when expanded

对于一列包含一行两个容器的屏幕,每个容器显示一个图像,行下方有一个撤消 FlatButton,当我将 InteractiveViewer 用于行中的第二个时,它工作得很好,但对于第一个,当它已展开,图像顶部有撤消按钮。

希望当其中一个容器与交互式查看器一起使用时,它们位于视图的顶部。

还希望 Interactive Viewer 容器在长按时进入全屏并在松开长按时退出全屏。

final TransformationController _transformationController =
  TransformationController();
  Animation<Matrix4> _animationReset;
  AnimationController _controllerReset;

  void _onAnimateReset() {
    _transformationController.value = _animationReset.value;
    if (!_controllerReset.isAnimating) {
      _animationReset?.removeListener(_onAnimateReset);
      _animationReset = null;
      _controllerReset.reset();
    }
  }

  void _animateResetInitialize() {
    _controllerReset.reset();
    _animationReset = Matrix4Tween(
      begin: _transformationController.value,
      end: Matrix4.identity(),
    ).animate(_controllerReset);
    _animationReset.addListener(_onAnimateReset);
    _controllerReset.forward();
  }

  void _animateResetStop() {
    _controllerReset.stop();
    _animationReset?.removeListener(_onAnimateReset);
    _animationReset = null;
    _controllerReset.reset();
  }

  void _onInteractionStart(ScaleStartDetails details) {
    // If the user tries to cause a transformation while the reset animation is
    // running, cancel the reset animation.
    if (_controllerReset.status == AnimationStatus.forward) {
      _animateResetStop();
    }
  }

  void _onInteractionEnd(ScaleEndDetails details) {
    _animateResetInitialize();
  }

  final TransformationController _transformationController2 =
  TransformationController();
  Animation<Matrix4> _animationReset2;
  AnimationController _controllerReset2;

  void _onAnimateReset2() {
    _transformationController2.value = _animationReset2.value;
    if (!_controllerReset2.isAnimating) {
      _animationReset2?.removeListener(_onAnimateReset2);
      _animationReset2 = null;
      _controllerReset2.reset();
    }
  }

  void _animateResetInitialize2() {
    _controllerReset2.reset();
    _animationReset2 = Matrix4Tween(
      begin: _transformationController2.value,
      end: Matrix4.identity(),
    ).animate(_controllerReset2);
    _animationReset2.addListener(_onAnimateReset2);
    _controllerReset2.forward();
  }


  void _animateResetStop2() {
    _controllerReset2.stop();
    _animationReset2?.removeListener(_onAnimateReset2);
    _animationReset2 = null;
    _controllerReset2.reset();
  }

  void _onInteractionStart2(ScaleStartDetails details) {
    // If the user tries to cause a transformation while the reset animation is
    // running, cancel the reset animation.
    if (_controllerReset2.status == AnimationStatus.forward) {
      _animateResetStop2();
    }
  }

  void _onInteractionEnd2(ScaleEndDetails details) {
    _animateResetInitialize2();
  }


  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: BGColor,
        appBar: AppBar(
          backgroundColor: PrimaryColor,
          title: Text('App\'name',
            style: TextStyle(
                color: Colors.white
            ),
          ),
          leading: GestureDetector(
            onTap: () {
              Navigator.of(context).pop();},
            child: Padding(
              padding: EdgeInsets.only(top: 19.0, left: 12.0),
              child: Text('Quit',
              style: TextStyle(
                color: Colors.white54,
                fontSize: 18.0,
              ),
              ),
            ),
          ),
        ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Flexible(
            flex: 1,
              child: tapInstruct(),
          ),
          SizedBox(height: 5.0),
          Flexible(
            flex: 9,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: InteractiveViewer(
                    boundaryMargin: EdgeInsets.all(double.infinity),
                    transformationController: _transformationController,
                    minScale: 1.0,
                    maxScale: 5,
                    onInteractionStart: _onInteractionStart,
                    onInteractionEnd: _onInteractionEnd,
                    panEnabled: false,
                    child: Container(
                      //margin: EdgeInsets.all(10.0),
                      child: GestureDetector(
                        onTap: () => _leftCardTapped(),
                        child: Padding(
                          padding: const EdgeInsets.all(2.0),
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(15.0),
                            child: Image.file(
                              favpicz[lcn]
                              // fit: BoxFit.fitHeight,
                            ),
                          ),
                        ),
                        // ),
                      ),
                    ),
                  ),
                ),
                Divider(
                  thickness: 2.0,
                ),
                Expanded(
                  flex: 1,
                  child: InteractiveViewer(
                    boundaryMargin: EdgeInsets.all(double.infinity),
                    transformationController: _transformationController2,
                    minScale: 1.0,
                    maxScale: 5,
                    onInteractionStart: _onInteractionStart2,
                    onInteractionEnd: _onInteractionEnd2,
                    panEnabled: false,
                    child: Container(
                      //margin: EdgeInsets.all(10.0),
                      child: GestureDetector(
                        onTap: () => _rightCardTapped(),
                        //onLongPress: //TODO full screen image,
                       // onLongPressEnd: ,//TODO exit full screen
                        //child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(2.0),
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(15.0),
                            child: Image.file(
                              favpicz[rcn],
                            ),
                          ),
                        ),
                        //),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          SizedBox(height: 5.0),
          Flexible(
            flex: 1,
            child:
                GestureDetector(
                  child: FlatButton(
                    onPressed: () => undo(),
                    child: Text('Undo',
                    style: TextStyle(
                      color: BGColor
                    ),),
                    color: undoButtonColor,
                  ),
                ),

          )
        ],
      ),
    ),
    );
  }

通过在 Visibility 小部件中包装两个 Container 和 FlatButton 并创建函数以在 InteractiveViewer 动画开始时将另一个容器和平面按钮的可见性设置为 false,我能够使它看起来像我想要的那样结束时为真。

使用“可见性”小部件也可以在长按时获得所需的全屏效果。