Flutter Web Mouse Region Widget Triggering

Viewed 2575

I am trying to get this result with Flutter;

enter image description here

I am having this behaviour;

enter image description here

Code;

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

A standalone widget works okay but when I put it into gridview or pageview it automatically reads it mouse entered when I scroll into it.

I tried to use other widgets like Inkwell, Listener and others. No solution. Can someone guide me if there is better solution?

How Can I solve this?

edit:

Multiple animation forwards

Now having this problem. MouseRegion causes multiple controller.forwards

2 Answers

I am Created an Example ... please Try this,

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

I solved my second problem by just moving addListener method to initState. Previously it was inside widget itself which was causing adding listeners in every rebuild and causing multiple rebuilds for each listener, I guess.

Related