Flutter Web 鼠标区域小部件触发

3

我正在尝试使用Flutter获得此结果;

enter image description here

我遇到了这种行为;

enter image description here

代码;

    import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:html' as html;

class OverlayAnimatedGridElement extends StatefulWidget {
  OverlayAnimatedGridElement(this.imagepath, this.postDetail, this.postTitle);
  final String imagepath;
  final String postTitle;
  final String postDetail;

  @override
  _OverlayAnimatedGridElementState createState() =>
      _OverlayAnimatedGridElementState();
}

class _OverlayAnimatedGridElementState extends State<OverlayAnimatedGridElement>
    with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _opacityTween;
  bool isHovered = false;

  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    _opacityTween = Tween<double>(begin: 0, end: 1).animate(
        CurvedAnimation(parent: _controller, curve: Curves.easeInOutCirc));

    super.initState();
  }

  hoverActivation(hoverState) {
    bool hoverState;
    isHovered = hoverState;
    if (isHovered = true) {
      _controller.forward();
    } else if (isHovered = false) {
      _controller.reset();
    }
    print("activated");
  }

  @override
  Widget build(BuildContext context) {
    _opacityTween.addListener(() {
      setState(() {
        print(_opacityTween.value);
      });
    });

    return MouseRegion(
      onHover: hoverActivation(true),
      child: Container(
        constraints: BoxConstraints(maxHeight: 360, maxWidth: 640),
        child: Stack(
          alignment: Alignment.bottomCenter,
          children: [
            Image(image: AssetImage("${widget.imagepath}")),
            Opacity(
              opacity: _opacityTween.value,
              child: Container(
                color: Color.fromRGBO(128, 128, 128, 0.5),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.max,
                  children: [
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text("${widget.postDetail}"),
                        Text("${widget.postTitle}")
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

一个独立的小部件可以正常工作,但当我将它放入gridview或pageview中时,当我滚动到它时,它会自动读取鼠标进入。

我尝试使用其他小部件,如Inkwell、Listener等,但没有解决方案。有人能指导我是否有更好的解决方案吗?

我该如何解决这个问题?

编辑:

Multiple animation forwards

现在遇到这个问题。MouseRegion 导致多个 controller.forwards。
2个回答

5

我创建了一个示例 ... 请尝试一下吧。

import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Todos',
      theme: new ThemeData(primarySwatch: Colors.deepOrange),
      home: MyHome(),
    );
  }
}

class MyHome extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return GridView.count(crossAxisCount: 3,
    children: List.generate(10, (index) {
      return OverlayAnimatedGridElement("https://picsum.photos/300/200");
        }
    ));
  }

}


class OverlayAnimatedGridElement extends StatefulWidget {
  OverlayAnimatedGridElement(this.imagepath);
  final String imagepath;
//  final String postTitle;
//  final String postDetail;

  @override
  _OverlayAnimatedGridElementState createState() =>
      _OverlayAnimatedGridElementState();
}

class _OverlayAnimatedGridElementState extends State<OverlayAnimatedGridElement>
    with TickerProviderStateMixin {
  bool isHovered = false;

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

  hoverActivation(hoverState) {
    setState(() {
      isHovered = hoverState;
    });
    print("activated" + hoverState.toString());
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Colors.red,
        height: 200,
        width: 300,
        child: Stack(
          children: [
            Image.network(widget.imagepath),
            MouseRegion(
              onEnter: (event){
                hoverActivation(true);
              },
              onExit: (event){
                hoverActivation(false);
              },
              child: AnimatedContainer(
                duration: Duration(milliseconds: 200),
                color: Colors.black.withOpacity(isHovered ? 0.5 : 0),
              ),
            )
          ],
        ),
      ),
    );
  }
}

非常感谢。请让我总结一下,告诉我是否有误。通过将一个空的鼠标区域放入堆栈中,您确保它留在堆栈中,扩展到堆栈大小,并且不会被外部的任何错误或错误触发。这按预期工作,但现在我遇到了性能问题。我还有两个问题。为什么我们要将该事件传递到方法中?当我不传递它时,它会自动触发,当我这样做时,它会等待。这是MouseRegion的默认行为吗?第二个问题是我在这个上面得到了重复的动画。我猜这是每次鼠标移动“事件”都会发生的? - ZayX
1
我兄弟!抱歉我不太理解你的问题...请添加图片或更详细地解释一下...因为我们都不是以英语为母语的人! :) - Sajjad
我编辑了主要问题,这样您就可以看到当前的行为。谢谢。我的主要问题是为什么我们要将(event)传递给匿名函数? - ZayX
如果我理解正确的话,你的问题是关于onExit和onEnter回调函数的吗?我们没有使用事件,但MouseRegion只接受这样的函数。 - Sajjad

0

我通过将addListener方法移动到initState中来解决了我的第二个问题。之前它在widget本身内部,导致每次重建都会添加监听器,并为每个监听器多次重建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接