Flutter-Web:鼠标悬停->将光标更改为指针

时间:2019-05-19 20:44:18

标签: flutter flutter-web

如何在Flutter中更改光标外观? 我知道,借助Listener()小部件,我们可以监听鼠标事件, 但是我还没有找到有关颤动网络悬停事件的任何信息。

有人找到溶液了吗?

8 个答案:

答案 0 :(得分:23)

我很难找到有关内置支持的文档。这对我有帮助:https://github.com/flutter/flutter/issues/58260

这对我有用,而无需更改index.html等。

MouseRegion(
  cursor: SystemMouseCursors.click,
    child: GestureDetector(
      child: Icon(
        Icons.add_comment,
        size: 20,
        ),
      onTap: () {},
    ),
  ),

答案 1 :(得分:8)

以下是一种解决方法:

  1. 您必须在应用程序 index.html的整个正文上设置 id (例如应用程序容器)< / strong>模板)。

这是您的 index.html 的外观:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My awesome app</title>
</head>
<body id="app-container">
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
  1. 接下来,您必须创建包装飞镖类。我称它为 hand_cursor.dart
import 'package:flutter_web/gestures.dart';
import 'package:flutter_web/widgets.dart';
import 'package:universal_html/html.dart' as html;
// see https://pub.dev/packages/universal_html

class HandCursor extends MouseRegion {

  // get a reference to the body element that we previously altered 
  static final appContainer = html.window.document.getElementById('app-container');

  HandCursor({Widget child}) : super(
    onHover: (PointerHoverEvent evt) {
      appContainer.style.cursor='pointer';
      // you can use any of these: 
      // 'help', 'wait', 'move', 'crosshair', 'text' or 'pointer'
      // more options/details here: http://www.javascripter.net/faq/stylesc.htm
    },
    onExit: (PointerExitEvent evt) {
      // set cursor's style 'default' to return it to the original state
      appContainer.style.cursor='default';
    },
    child: child
  );

}
  1. 此后,无论您想在何处显示手形光标,都必须将元素包装在此HandCursor包装器中。请参见下面的课程 awesome_button.dart
import 'package:awesome_app/widgets/containers/hand_cursor.dart';
import 'package:flutter_web/material.dart';
import 'package:flutter_web/widgets.dart';

class AwesomeButton extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        HandCursor(
          child: IconButton(
            onPressed: () {
              // do some magic
            },
            icon: Icon(Icons.star)
          ),
        )
      ],
    );
  }

}

简短说明here

可以找到here。更广泛的更新适用于使用Flutter的 master 频道创建的新Web项目。

我希望它会有所帮助。

答案 2 :(得分:5)

在Flutter测试版1.19.0-4.1.pre中,将ID添加到body并设置其光标无效。因为flt-glass-pane正在替换光标。 因此解决方案是将光标直接设置为flt-glass-pane

下面是正在运行的更新。

class HandCursor extends MouseRegion {
    static final appContainer = html.window.document.querySelectorAll('flt-glass-pane')[0];
    HandCursor({Widget child}) : super(
        onHover: (PointerHoverEvent evt) {
            appContainer.style.cursor='pointer';
        },
        onExit: (PointerExitEvent evt) {
            appContainer.style.cursor='default';
        },
        child: child
    );    
}

答案 3 :(得分:3)

final appContainer 
     = html.document.getElementsByTagName('body')[0] as html.Element;

            GestureDetector(
                        child: MouseRegion(
                          child: Text(
                            'https://github.com/yumi0629',
                            style: textStyle,
                          ),
                          onHover: (_) => appContainer.style.cursor = 'pointer',
                          onExit: (_) => appContainer.style.cursor = 'default',
                        ),
                        onTap: () {
                          print('open');
                          js.context.callMethod(
                              'open', ['https://github.com/yumi0629']);
                        },
                      )

答案 4 :(得分:2)

不建议使用先前的方法。这是更新的代码

import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:universal_html/prefer_sdk/html.dart' as html;

class HandCursor extends MouseRegion {
  static final appContainer = html.window.document.getElementById('app-container');
  HandCursor({Widget child})
      : super(
          onHover: (PointerHoverEvent evt) {
            appContainer.style.cursor = 'pointer';
          },
          onExit: (PointerExitEvent evt) {
            appContainer.style.cursor = 'default';
          },
          child: child,
        );
}

然后在pubspec.yaml文件中,将Universal_html作为软件包添加为依赖项。版本可能会更改。

dependencies:
  flutter:
    sdk: flutter
  universal_html: ^1.1.4

您仍然希望在HTML正文中附加一个app-container的ID。这是我的html文件。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Your App Title</title>
</head>
<body id="app-container">
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

您想将HandCursor小部件的代码放在其自己的文件中。您可以将其称为hand_cursor.dart。并在要显示手的小部件上使用它,将其导入到正在使用的文件中,然后将所需的小部件包装在HandCursor小部件中。

答案 5 :(得分:1)

我相信鼠标事件将无法在网络上运行,Listener Widget已在Google I / O 2019上进行了演示并可以与鼠标一起使用,但这是作为ChromeOS应用而非网络应用的。

根据Flutter web on GitHub

  

目前,桌面UI交互还没有完全完成,因此,即使在桌面浏览器上运行,使用flutter_web构建的UI也可能感觉像是一个移动应用。

答案 6 :(得分:0)

康斯坦丁·斯坦(Constantin Stan)的自适应答案

对于那些希望获得类似于InkWell小部件并具有“边框半径”选项的点击效果的人:

添加到您的pubspec.yaml文件

dependencies:
  universal_html: ^1.1.4

然后将以下标记<body id="app-container">添加到index.html文件中,如下所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Your App Title</title>
</head>
<body id="app-container">
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

最后创建以下窗口小部件并使用封装的所有必需窗口小部件:

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:universal_html/prefer_sdk/html.dart' as html;

class InkWellMouseRegion extends InkWell {
  InkWellMouseRegion({
    Key key,
    @required Widget child,
    @required GestureTapCallback onTap,
    double borderRadius = 0,
  }) : super(
          key: key,
          child: !kIsWeb ? child : HoverAware(child: child),
          onTap: onTap,
          borderRadius: BorderRadius.circular(borderRadius),
        );
}

class HoverAware extends MouseRegion {

  // get a reference to the body element that we previously altered 
  static final appContainer = html.window.document.getElementById('app-container');

  HoverAware({Widget child}) : super(
    onHover: (PointerHoverEvent evt) {
      appContainer.style.cursor='pointer';
      // you can use any of these: 
      // 'help', 'wait', 'move', 'crosshair', 'text' or 'pointer'
      // more options/details here: http://www.javascripter.net/faq/stylesc.htm
    },
    onExit: (PointerExitEvent evt) {
      // set cursor's style 'default' to return it to the original state
      appContainer.style.cursor='default';
    },
    child: child
  );

}

答案 7 :(得分:0)

您可以使用具有onHover事件的InkWell

InkWell(
    onTap: () {},
    onHover: (value) {
      setState(() {
        isHovered = value;
      });
    },
    child: Container(
      width: 50,
      height: 72,
      color: Colors.black   
    )
);

请确保在onTap上添加了一些内容,甚至是一个空函数,否则将其视为已禁用,并且悬停将无法工作