Flutter悬浮交互插件hoverables的使用

Flutter悬浮交互插件hoverables的使用

Easiest and cleanest way to build hover effects in Flutter. This package provides a simple way to build hover effects in Flutter without dealing with managing hover state explicitly.

Demo: Playground

开始使用

1. 在项目中添加依赖

在项目的 pubspec.yaml 文件中添加以下内容:

dependencies:
  hoverables: <latest_version>

2. 导入库

在你的代码文件中导入库:

import 'package:hoverables/hoverables.dart';

使用方法

使用 HoverBuilder

HoverBuilder 允许你轻松地构建悬停效果。它提供了一个 builder 函数,该函数会给出当前的悬停状态。

HoverBuilder(
  builder: (context, hovering, child) {
    return AnimatedScale(
      duration: const Duration(milliseconds: 200),
      scale: hovering ? 1.35 : 1,
      child: child,
    );
  },
  child: GestureDetector(
    onTap: onTap,
    child: Container(
      width: 200,
      height: 200,
      alignment: Alignment.center,
      decoration: BoxDecoration(
        color: Theme.of(context).colorScheme.primaryContainer,
        borderRadius: BorderRadius.circular(20),
      ),
      child: const Text('Hover Scale'),
    ),
  ),
);

完整示例代码

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GridView(
          padding: const EdgeInsets.all(56),
          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 300,
            mainAxisSpacing: 56,
            crossAxisSpacing: 56,
          ),
          children: [
            // Hover Builder
            HoverBuilder(
              builder: (context, hovering, child) {
                return Center(
                  child: GestureDetector(
                    onTap: onTap,
                    child: AnimatedContainer(
                      duration: const Duration(milliseconds: 200),
                      width: hovering ? 300 : 200,
                      height: hovering ? 300 : 200,
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        color: hovering
                            ? Theme.of(context).colorScheme.primaryContainer
                            : Colors.grey.shade200,
                        borderRadius: BorderRadius.circular(20),
                      ),
                      child: AnimatedDefaultTextStyle(
                        duration: const Duration(milliseconds: 200),
                        style: DefaultTextStyle.of(context).style.copyWith(
                              fontSize: hovering ? 30 : 20,
                              fontWeight: hovering
                                  ? FontWeight.bold
                                  : FontWeight.normal,
                              fontStyle: hovering
                                  ? FontStyle.italic
                                  : FontStyle.normal,
                            ),
                        child: child!,
                      ),
                    ),
                  ),
                );
              },
              child: const Text('Hover Me'),
            ),
            // Hover Scale
            HoverBuilder(
              builder: (context, hovering, child) {
                return AnimatedScale(
                  duration: const Duration(milliseconds: 200),
                  scale: hovering ? 1.35 : 1,
                  child: child,
                );
              },
              child: GestureDetector(
                onTap: onTap,
                child: Container(
                  width: 200,
                  height: 200,
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.primaryContainer,
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: const Text('Hover Scale'),
                ),
              ),
            ),
            // Hover Rotation
            HoverBuilder(
              builder: (context, hovering, child) {
                return AnimatedRotation(
                  duration: const Duration(milliseconds: 200),
                  turns: hovering ? 10 / 360 : 0,
                  child: child,
                );
              },
              child: GestureDetector(
                onTap: onTap,
                child: Container(
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.tertiaryContainer,
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: const Text('Hover Turn'),
                ),
              ),
            ),
            // Hover Translate
            HoverBuilder(
              builder: (context, hovering, child) {
                return AnimatedSlide(
                  duration: const Duration(milliseconds: 200),
                  offset: hovering
                      ? const Offset(-0.05, -0.05)
                      : const Offset(0, 0),
                  child: child,
                );
              },
              child: GestureDetector(
                onTap: onTap,
                child: Container(
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.surfaceContainer,
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: const Text('Hover Turn'),
                ),
              ),
            ),
            // Hover Fade
            HoverBuilder(
              builder: (context, hovering, child) {
                return AnimatedOpacity(
                  duration: const Duration(milliseconds: 200),
                  opacity: hovering ? 0.6 : 1,
                  child: child,
                );
              },
              child: GestureDetector(
                onTap: onTap,
                child: Container(
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.outlineVariant,
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: const Text('Hover Turn'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void onTap() {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Hoverables are awesome!'),
      ),
    );
  }
}

更多关于Flutter悬浮交互插件hoverables的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter悬浮交互插件hoverables的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,hoverables 并不是一个官方提供的内置插件或组件,但你可以通过监听鼠标悬停事件来实现悬浮交互效果。这通常涉及到使用 PointerHoverEventListener 组件。下面是一个简单的示例,展示如何在 Flutter 中实现悬浮交互效果。

首先,确保你的 Flutter 环境已经设置好,然后创建一个新的 Flutter 项目或在现有项目中添加以下代码。

示例代码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Hoverables Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HoverableDemo(),
    );
  }
}

class HoverableDemo extends StatefulWidget {
  @override
  _HoverableDemoState createState() => _HoverableDemoState();
}

class _HoverableDemoState extends State<HoverableDemo> {
  bool isHovered = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hoverables Demo'),
      ),
      body: Center(
        child: Listener(
          onPointerHover: (PointerHoverEvent event) {
            setState(() {
              isHovered = event.isIn;
            });
          },
          child: Container(
            width: 200,
            height: 200,
            decoration: BoxDecoration(
              color: isHovered ? Colors.blue : Colors.grey,
              borderRadius: BorderRadius.circular(10),
            ),
            child: Center(
              child: Text(
                isHovered ? 'Hovered' : 'Not Hovered',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

解释

  1. Listener 组件:用于监听指针事件,包括悬停事件。
  2. onPointerHover 回调:当指针悬停在组件上时,PointerHoverEvent 会被触发。event.isIn 是一个布尔值,表示指针是否在当前组件内。
  3. setState 方法:用于更新组件的状态。当悬停状态改变时,调用 setState 来重新构建组件。
  4. Container 组件:作为被悬停的组件,其颜色和文本会根据悬停状态变化。

运行效果

运行上述代码后,你将看到一个灰色的方块。当你将鼠标悬停在方块上时,它会变成蓝色,并且文本会变为 “Hovered”。当你将鼠标移开时,它会恢复为灰色,文本变为 “Not Hovered”。

这个示例展示了如何在 Flutter 中通过监听悬停事件来实现简单的悬浮交互效果。你可以根据需求进一步扩展和定制这个示例。

回到顶部