首页 > 解决方案 > Flutter Web 鼠标区域小部件触发

问题描述

我试图用 Flutter 得到这个结果;

在此处输入图像描述

我有这种行为;

在此处输入图像描述

代码;

    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 等。没有解决方案。如果有更好的解决方案,有人可以指导我吗?

我该如何解决这个问题?

编辑:

多个动画转发

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

标签: flutterflutter-layoutflutter-webflutter-animation

解决方案


我创造了一个例子......请试试这个,

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),
              ),
            )
          ],
        ),
      ),
    );
  }
}

推荐阅读