flutterdartflutter-animationmousehover

How to make a widget visible/invisible on hover?


I'm trying to make a widget visible/invisible on hovering for flutter desktop app ,But it's not giving the result.

Full Code:


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

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Card(
          elevation: 11,
          margin: const EdgeInsets.all(10),
          color: MyColor.whiteColor,
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Expanded(
                    child: Text(
                        '''Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum''')),
                OnHoverView(
                  child: InkWell(
                    onTap: () {},
                    child: Container(
                      width: 154,
                      height: 32,
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(50.0),
                        border:
                            Border.all(color: MyColor.sliderArchiveBackGround),
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          Container(
                            width: 22,
                            height: 22,
                            decoration: BoxDecoration(
                                shape: BoxShape.circle,
                                border: Border.all(
                                    color: MyColor.sliderArchiveBackGround)),
                          ),
                          const TextWidget(
                            text: AppConstants.markAsDone,
                            fontWeight: FontWeight.w400,
                            textColor: MyColor.textGrey,
                            fontSize: 16,
                          )
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Hovering Widget

class OnHoverView extends StatefulWidget {
 final Widget child;
 const OnHoverView(
     {super.key, required this.child,});

 @override
 State<OnHoverView> createState() => _OnHoverViewState();
}

class _OnHoverViewState extends State<OnHoverView> {
 bool visible = true;
  
 @override
 Widget build(BuildContext context) {
   return MouseRegion(
       onEnter: (event) => onHoverChange(true),
       onExit: (event) => onHoverChange(false),
       child: Visibility(visible: visible,child: widget.child,));
 }

 onHoverChange(bool value) {
   debugPrint("ON Overing --------->$value");
   setState(() {
     visible = value;
   });
 }
}

Result:

enter image description here


Solution

  • put some more efforts & I found ,It's very easy.

    Full Code:

    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      bool onHoveringVisibility = false;
     
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: OnHoverView(
              onHoverChange: (value) {
                setState(() {
                  onHoveringVisibility = value;
                });
              },
              child: Card(
                elevation: 11,
                margin: const EdgeInsets.all(10),
                color: MyColor.whiteColor,
                child: Padding(
                  padding: const EdgeInsets.all(15.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Expanded(
                          child: Text(
                              '''Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum''')),
                      Visibility(
                        visible: onHoveringVisibility,
                        child: AppFadeInWidget(
                          child: InkWell(
                            onTap: () {},
                            child: Container(
                              width: 154,
                              height: 32,
                              alignment: Alignment.center,
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(50.0),
                                border:
                                    Border.all(color: MyColor.sliderArchiveBackGround),
                              ),
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  Container(
                                    width: 22,
                                    height: 22,
                                    decoration: BoxDecoration(
                                        shape: BoxShape.circle,
                                        border: Border.all(
                                            color: MyColor.sliderArchiveBackGround)),
                                  ),
                                  const TextWidget(
                                    text: AppConstants.markAsDone,
                                    fontWeight: FontWeight.w400,
                                    textColor: MyColor.textGrey,
                                    fontSize: 16,
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    

    Hovering Widget:

    
    
    class OnHoverView extends StatelessWidget {
      final Widget child;
      final void Function(bool) onHoverChange;
      const OnHoverView(
          {super.key, required this.child, required this.onHoverChange});
    
      @override
      Widget build(BuildContext context) {
        return MouseRegion(
            onEnter: (event) => onHoverChange(true),
            onExit: (event) => onHoverChange(false),
            child: child);
      }
    }
    
    

    Fade In Widget (For smooth visibility):

    class AppFadeInWidget extends StatefulWidget {
      final Widget child;
      const AppFadeInWidget({super.key, required this.child});
    
      @override
      State<AppFadeInWidget> createState() => _AppFadeInWidgetState();
    }
    
    class _AppFadeInWidgetState extends State<AppFadeInWidget> with TickerProviderStateMixin{
       AnimationController? _controller;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
          duration: const Duration(milliseconds: 500),
          vsync: this,
        )..forward(); // Start the fade-in on initState.
      }
      @override
      void dispose() {
       _controller?.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return _controller != null
            ? FadeTransition(
                opacity: _controller!,
                child: widget.child,
              )
            : const SizedBox.shrink();
      }
    }
    

    RESULT