Flutter MouseRegion 链接高亮显示样式 只有你想不到 没有你做不到的

630 阅读2分钟

MouseRegion 是 Flutter 开发中,在桌面应用与Web应用中,用来监听一定区域内鼠标的进入与退出,以及移动轨迹。

在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。

如果你有兴趣 你可以关注一下公众号 biglead 来获取最新的学习资料。


先来看看本文章实现的效果

在这里插入图片描述

直接来看代码吧

首先是启动函数

main() {
  runApp(MaterialApp(
    //不显示 debug标签
    debugShowCheckedModeBanner: false,
    //显示的首页面
    home: DemoMouseRegionPage(),
  ));
}

然后是定义我这个首页面了 DemoMouseRegionPage

///代码清单
class DemoMouseRegionPage extends StatefulWidget {
  @override
  _DemoMouseRegionPageState createState() => _DemoMouseRegionPageState();
}

class _DemoMouseRegionPageState extends State<DemoMouseRegionPage> {
  //为true时鼠标进入了监听区域中
  bool _isEnter = false;
  //绑定文本框,用来获取文本Text的位置与大小信息
  GlobalKey _globalKey = GlobalKey();
  //文本颜色
  Color _textColor = Colors.black;

  @override
  Widget build(BuildContext context) {
    //
    return Scaffold(
      appBar: AppBar(
        title: Text("MouseRegion"),
      ),
      body: Container(
        width: double.infinity,
        padding: EdgeInsets.all(10),
        child: Column(
          children: [
            //鼠标事件监听
            buildMouseRegion(),
          ],
        ),
      ),
    );
  }

我将 MouseRegion 组件通过 函数封装的形式来构建 ,代码如下:

  MouseRegion buildMouseRegion() {
    return MouseRegion(
      //进入
      onEnter: (PointerEnterEvent event) {
        print("进入 ---");
        setState(() {
          _isEnter = true;
        });
      },
      //退出
      onExit: (PointerExitEvent event) {
        print("退出 ---");
        setState(() {
          _isEnter = false;
        });
      },
      onHover: (PointerHoverEvent event) {
        //x 当前鼠标位置
        buildHoverEvent(event);
      },
      child: Container(
        width: double.infinity,
        alignment: Alignment.center,
        height: 300,
        child: Text(
          "这是什么 ???",
          key: _globalKey,
          style: TextStyle(color: _textColor),
        ),
        color: _isEnter ? Colors.blueAccent : Colors.blue[200],
      ),
    );
  }

在这里是通过 _isEnter 来记录鼠标是否进入到了 MouseRegion 监听的范围内,同样的是根据 _isEnter 的变化 来动态修改 Container 的背景颜色的。

然后在 鼠标移动监听的回调 onHover 中,通过 PointerHoverEvent 参数来实时获取了 鼠标的位置 ,通过 Text 绑定的 GlobalKey 来获取 Text 组件的位置与大小 ,从而来计算 鼠标是否在 Text 的区域内。


  void buildHoverEvent(PointerHoverEvent event) {
    //x 当前鼠标位置
    double x = event.position.dx;
    double y = event.position.dy;

    //获取文本组件的属性信息
    RenderBox renderBox = _globalKey.currentContext.findRenderObject();
    //文本组件的左上角点坐标
    Offset offset = renderBox.localToGlobal(Offset.zero);

    double topX = offset.dx;
    double topY = offset.dy;

    //文本组件的大小
    Size size = renderBox.paintBounds.size;

    //文本组件的右下角点坐标
    double bottomX = topX + size.width;
    double bottomY = topY + size.height;

    if (x > topX && x < bottomX && y > topY && y < bottomY) {
      //在文本组件 Text 的区域内 文字颜色为红色
      _textColor = Colors.red;
    } else {
      _textColor = Colors.black;
    }
    setState(() {});
    print("onHover --- $x  $y  $offset");
  }

完毕