Flutter MouseRegion 滚动时悬停暂时暂停,导致项目按钮停止跟踪鼠标移动

问题描述 投票:0回答:1

我在 Flutter 应用程序中遇到一个问题,当滚动开始时,MouseRegion 内的悬停效果会中断。此中断会导致“项目”按钮停止跟踪鼠标移动。

这是说明问题的 GIF: Flutter MouseRegion Hover Interruption During Scrolling

我尝试调整 Flutter 中的 MouseRegion 属性以减轻滚动期间的悬停中断。然而,尽管进行了这些调整,问题仍然存在,导致“项目”按钮功能意外暂停。

这是代码片段:

class MainButtonStarting extends StatefulWidget {
  const MainButtonStarting({super.key});

  @override
  State<MainButtonStarting> createState() => _MainButtonStartingState();
}

class _MainButtonStartingState extends State<MainButtonStarting>
    with SingleTickerProviderStateMixin {
  var containerPosition = const Offset(
    10000,
    680,
  );

  double containerSize = 100;
  double containerOpacity = .5;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      containerPosition = Offset(
        MediaQuery.of(context).size.width - 410,
        670,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onExit: (event) {
        containerOpacity = .5;

        containerPosition = Offset(
          MediaQuery.of(context).size.width - 410,
          670,
        );
        containerSize = 100;
      },
      onHover: (event) {
        setState(() {
          containerOpacity = 1;

          containerSize = 156;
          double containerWidth =
              100; // Adjust according to your container size
          double containerHeight =
              100; // Adjust according to your container size
          double mouseX = event.localPosition.dx;
          double mouseY = event.localPosition.dy;
          double screenWidth = MediaQuery.of(context).size.width;
          double screenHeight = MediaQuery.of(context).size.height;

          // Calculate new position for the container
          double newLeft = mouseX - containerSize / 2;
          double newTop = mouseY - containerSize / 2;

          // Ensure the container stays within the bounds of the screen
          if (newLeft < 0) {
            newLeft = 0;
          } else if (newLeft + containerWidth > screenWidth) {
            newLeft = screenWidth - containerWidth;
          }

          if (newTop < 0) {
            newTop = 0;
          } else if (newTop + containerHeight > screenHeight) {
            newTop = screenHeight - containerHeight;
          }

          // Update container position
          containerPosition = Offset(newLeft, newTop);
        });
      },
      child: Stack(
        children: [
          Container(
            height: 782,
            width: double.infinity,
            decoration: basicContainer,
            child: Stack(
              children: [
                ClipRRect(
                  borderRadius: BorderRadius.circular(12),
                  child: Image.asset(
                    'assets/images/newImages/bg_container.png',
                    fit: BoxFit.cover,
                    height: 782,
                  ),
                ),
                Positioned(
                  left: 50,
                  bottom: 40,
                  child: Container(
                    width: 875,
                    decoration: basicContainer,
                    child: Padding(
                      padding: const EdgeInsets.all(46.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          SizedBox(
                            width: 875,
                            child: Text(
                              'Embracing the interplay of artistic freedom and strategic order.',
                              textAlign: TextAlign.right,
                              style: GoogleFonts.gfsDidot(
                                color: Colors.white,
                                fontSize: 40,
                                fontWeight: FontWeight.w400,
                              ),
                            ),
                          ),
                          const Gap(74),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: [
                              SizedBox(
                                width: 537,
                                child: Text(
                                  'We welcome the invigorating fusion of boundless creativity and steadfast structure. It’s within this captivating balance that we discover our inspiration and drive to deliver exceptional results.\n\nOur design philosophy is rooted in our commitment to creativity, collaboration, and attention to detail. \n\nWe are committed to delivering the best possible design solutions that works for you.',
                                  style: GoogleFonts.inter(
                                    color: Colors.white,
                                    fontSize: 16,
                                    fontWeight: FontWeight.w300,
                                  ),
                                ),
                              ),
                              Container(
                                width: 163,
                                height: 55,
                                clipBehavior: Clip.antiAlias,
                                decoration: ShapeDecoration(
                                  shape: RoundedRectangleBorder(
                                    side: const BorderSide(
                                        width: 1, color: Color(0xFF6C6C6C)),
                                    borderRadius: BorderRadius.circular(6),
                                  ),
                                ),
                                child: const Center(
                                  child: Text(
                                    'About us',
                                    style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 16,
                                      fontFamily: 'Inter',
                                      fontWeight: FontWeight.w300,
                                    ),
                                  ),
                                ),
                              )
                            ],
                          )
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          AnimatedPositioned(
            curve: Curves.fastEaseInToSlowEaseOut,
            duration: const Duration(milliseconds: 250),
            left: containerPosition.dx,
            top: containerPosition.dy,
            child: AnimatedOpacity(
              duration: const Duration(milliseconds: 250),
              opacity: containerOpacity,
              child: AnimatedContainer(
                duration: const Duration(milliseconds: 250),
                width: containerSize,
                height: containerSize,
                decoration: const ShapeDecoration(
                  color: Color(0x7F6C6C6C),
                  shape: OvalBorder(
                    side: BorderSide(width: 1, color: Colors.white),
                  ),
                ),
                child: Center(
                  child: Text(
                    'Projects',
                    style: GoogleFonts.inter(
                      color: Colors.white,
                      fontSize: 15,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

任何有关如何解决此问题的见解或建议将不胜感激。谢谢!

flutter animation hover
1个回答
0
投票

这是一个有趣的问题,我想到的是将鼠标区域包装在一个侦听器中,该侦听器检测滚动并纠正位置。我不确定这是否是最好的解决方案,但我想不出更好的解决方案。看,一个例子如下,但当然,要适当地进行计算,考虑到所有可能影响的因素。

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerSignal: (pointerSignal) {
        if (pointerSignal is PointerScrollEvent) {
          final scrollMoved = pointerSignal.scrollDelta.dy;
          setState(() {
            containerPosition = Offset(
                //move position on Y
                containerPosition.dx, containerPosition.dy + scrollMoved);
          });
        }
      },
      child: MouseRegion(
        onExit: (event) {
          containerOpacity = .5;
...
© www.soinside.com 2019 - 2024. All rights reserved.