flutterrotationtransformpan

Flutter - after rotate container with Transform.rotate, it's child gesturedetector ontap method not working


enter image description here enter image description here enter image description here

When I rotate the container with angle 45 or other radians, the delete button、expand button not performed the 'onTap', 'onPanUpdate' gesture. I found rotate the container with 'RotatedBox' is good, but its param 'quarterTurns' only supports int type value. I know the differences between 'Transform.rotate' and 'RotatedBox'. 'Transform.rotate' only refreshes UI, and 'Rotatedbox' affects its children layout. I don't know how to do in my case.

please help me, thanks.

here is my sample code:

@override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(
      value: stickersViewNotifier,
      child: Consumer<KSStickersViewNotifier>(
        builder: (context, notifier, child) {
          return Positioned(
              left: stickersViewNotifier._left,
              top: stickersViewNotifier._top,
              child: GestureDetector(
                  onTap: () {
                    stickersViewNotifier.updateShouldShowControl(!stickersViewNotifier.shouldShowControl);
                  },
                  onPanDown: (DragDownDetails e) {
                    print("${e.globalPosition}");
                  },
                  onPanUpdate: (DragUpdateDetails e) {
                    stickersViewNotifier.panContainer(e.delta.dx, e.delta.dy);
                  },
                  onPanEnd: (DragEndDetails e) {
                    //打印滑动结束时在x、y轴上的速度
                    print(e.velocity);
                  },
                  child: Transform.rotate(
                    angle: 45 / 180 * math.pi,
                    child: Container(
                      width: stickersViewNotifier._width,
                      height: stickersViewNotifier._height,
                      child: Stack(
                        children: [
                          Padding(
                            padding: EdgeInsets.all(controlButtonWidth * 0.33),
                            child: DottedBorder(
                              color: stickersViewNotifier.shouldShowControl ? Colors.black : Colors.transparent,
                              strokeWidth: 1,
                              dashPattern: [5, 5, 5, 5],
                              child: Container(
                                width: double.infinity,
                                height: double.infinity,
                                child: Padding(
                                  padding: EdgeInsets.all(controlButtonWidth * 0.67),
                                  child: Center(
                                    child: containerWidget,
                                  ),
                                ),
                              ),
                            ),
                          ),
                          Offstage(
                            offstage: !stickersViewNotifier.shouldShowControl,
                            child: GestureDetector(
                              onTap: () {
                                onDelete(notifier.tag);
                              },
                              child: Container(
                                width: controlButtonWidth,
                                height: controlButtonWidth,
                                decoration: BoxDecoration(color: Colors.redAccent, borderRadius: BorderRadius.circular(controlButtonWidth / 2)),
                                child: Center(
                                  child: Icon(
                                    Icons.close_rounded,
                                    color: Colors.white,
                                    size: controlButtonWidth - 5,
                                  ),
                                ),
                              ),
                            ),
                          ),
                          Positioned(
                            right: 0,
                            child: Offstage(
                              offstage: !stickersViewNotifier.shouldShowControl,
                              child: GestureDetector(
                                child: Container(
                                  width: controlButtonWidth,
                                  height: controlButtonWidth,
                                  decoration: BoxDecoration(color: Colors.redAccent, borderRadius: BorderRadius.circular(controlButtonWidth / 2)),
                                  child: Center(
                                    child: Icon(
                                      Icons.refresh_rounded,
                                      color: Colors.white,
                                      size: controlButtonWidth - 5,
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                          Positioned(
                            right: 0,
                            bottom: 0,
                            child: Offstage(
                              offstage: !stickersViewNotifier.shouldShowControl,
                              child: GestureDetector(
                                onPanUpdate: (DragUpdateDetails details) {
                                  double dx = details.delta.dx;
                                  double dy = details.delta.dy;
                                  stickersViewNotifier.zoom(dx, dy);
                                },
                                child: Container(
                                  width: controlButtonWidth,
                                  height: controlButtonWidth,
                                  decoration: BoxDecoration(color: Colors.redAccent, borderRadius: BorderRadius.circular(controlButtonWidth / 2)),
                                  child: Center(
                                    child: Icon(
                                      Icons.zoom_out_map_rounded,
                                      color: Colors.white,
                                      size: controlButtonWidth - 8,
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  )));
        },
      ),
    );
  }


Solution

  • here is an demo: hope you will get the idea. move buttons on top level widget. and rotate the full container including buttons. also use multi-stack for this purpose.

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    class DeleteOnRotate extends StatefulWidget {
      DeleteOnRotate({Key? key}) : super(key: key);
    
      @override
      _DeleteOnRotateState createState() => _DeleteOnRotateState();
    }
    
    class _DeleteOnRotateState extends State<DeleteOnRotate> {
      double _angle = 0;
      bool _visible = true;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: LayoutBuilder(
            builder: (context, constraints) => Stack(
              children: [
                Align(
                  alignment: Alignment.bottomCenter,
                  child: TextButton(
                    child: Text("ChangeVisibility"),
                    onPressed: () {
                      setState(() {
                        _visible = !_visible;
                      });
                    },
                  ),
                ),
    
                ///stickerBox
                if (_visible)
                  Container(
                    height: constraints.maxHeight * .6,
                    width: constraints.maxWidth,
                    color: Colors.cyanAccent.withOpacity(.2),
                    child: Stack(
                      children: [
                        Align(
                          alignment: Alignment(0, 0),
                          child: Transform.rotate(
                            angle: _angle / 180 * pi,
                            child: Container(
                              height: constraints.maxHeight * .35,
                              width: constraints.maxWidth * .6,
                              decoration: BoxDecoration(
                                border: Border.all(
                                  style: BorderStyle.solid,
                                ),
                              ),
                              child: Stack(
                                children: [
                                  Positioned(
                                    top: 0,
                                    left: 0,
                                    child: IconButton(
                                      onPressed: () {
                                        setState(() {
                                          _visible = !_visible;
                                        });
                                      },
                                      icon: Icon(
                                        Icons.delete,
                                      ),
                                    ),
                                  ),
                                  Positioned(
                                    top: 0,
                                    right: 0,
                                    child: IconButton(
                                      onPressed: () {
                                        setState(() {
                                          _angle += 45;
                                        });
                                      },
                                      icon: Icon(
                                        Icons.rotate_right,
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
              ],
            ),
          ),
        );
      }
    }
    
    
    ```