Flutter-Web:鼠标悬停 -> 将光标更改为指针
Flutter-Web: Mouse hover -> Change cursor to pointer
更新(2021/05/11):
Flutter 现在原生实现了悬停事件 Widgets。
有一个用于 RaisedButton 等 Widget 的 MouseCursor 和 hoverColor 或 hoverElevation 等属性。
https://api.flutter.dev/flutter/rendering/MouseCursor-class.html
您还可以在已接受答案中所述的其他任何地方使用 InkWell。
原题:
如何在 Flutter 中更改光标外观?
我知道使用 Listener() 小部件我们可以监听鼠标事件,
但我还没有找到任何关于 flutter web 悬停事件的信息。
有人找到解决方案了吗?
我认为鼠标事件不会在网络上运行,Listener Widget 在 Google I/O 2019 年进行了演示并且可以使用鼠标,但它是作为 ChromeOS 应用程序而不是网络应用
At this time, desktop UI interactions are not fully complete, so a UI built with flutter_web may feel like a mobile app, even when running on a desktop browser.
从 dev 频道构建版本 1.19.0–3 开始。0.pre 内置了对指针光标的支持。使用与波纹管相同的方法,不同之处在于应用于 Flutter 应用程序容器元素 flt-glass-pane
。使用波纹管方法只会复制行为。
为了覆盖 pointer
光标,您可以使用波纹管方法,但应用于 flt-glass-pane
元素。
解决方法如下:
- 您必须在整个 body[=47= 上设置一个 id(例如 app-container ] 应用的 index.html 模板)。
这就是您的 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>
- 接下来,您必须创建一个包装飞镖 class。我称它为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
);
}
- 之后,无论您希望在何处显示手形光标,都必须将您的元素包装在此 HandCursor 包装器中。请参阅下面的 class 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 项目
希望对您有所帮助。
以前的方法已弃用。这是更新后的代码
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
您仍然希望将应用程序容器的 ID 附加到您的 html 的正文中。这是我的 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>
您想将手形光标小部件的代码放在它自己的文件中。你可以称它为hand_cursor.dart。并在您希望手显示的小部件上使用它,将其导入您正在处理的文件并将您想要的小部件包装在 HandCursor 小部件中。
Constantin Stan 改编的答案
对于那些想要具有类似于 InkWell
小部件和边框半径选项的点击效果的用户:
添加到您的 pubspec.yaml 文件
dependencies:
universal_html: ^1.1.4
然后将以下标签添加到 index.html 文件中 <body id="app-container">
如下:
<!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
);
}
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']);
},
)
我很难找到有关现在内置支持的文档。以下是对我有帮助的内容:https://github.com/flutter/flutter/issues/58260
这对我有用,没有改变 index.html 等
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
child: Icon(
Icons.add_comment,
size: 20,
),
onTap: () {},
),
),
另见官方文档:https://api.flutter.dev/flutter/rendering/MouseCursor-class.html
Widget build(BuildContext context) {
return Center(
child: MouseRegion(
cursor: SystemMouseCursors.text,
child: Container(
width: 200,
height: 100,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(color: Colors.yellow),
),
),
),
);
}
这里 https://api.flutter.dev/flutter/material/MaterialStateMouseCursor-class.html 官方文档中的另一个精彩示例“...定义了一个鼠标光标,当其小部件被禁用时解析为 SystemMouseCursors.forbidden。”
从 Flutter beta 版本 1.19.0-4.1.pre
开始,将 id 添加到 body
并设置其光标不起作用。因为 flt-glass-pane
正在替换光标。
所以解决办法就是直接设置cursor到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
);
}
您可以使用具有 onHover 事件的 InkWell
InkWell(
onTap: () {},
onHover: (value) {
setState(() {
isHovered = value;
});
},
child: Container(
width: 50,
height: 72,
color: Colors.black
)
);
确保有一些onTap,即使是一个空函数,否则它被认为是禁用的,悬停将不起作用
我所知道的最简单的方法
InkWell(
onTap: (){},
mouseCursor: MaterialStateMouseCursor.clickable,
...
更新(2021/05/11):
Flutter 现在原生实现了悬停事件 Widgets。
有一个用于 RaisedButton 等 Widget 的 MouseCursor 和 hoverColor 或 hoverElevation 等属性。
https://api.flutter.dev/flutter/rendering/MouseCursor-class.html
您还可以在已接受答案中所述的其他任何地方使用 InkWell。
原题:
如何在 Flutter 中更改光标外观? 我知道使用 Listener() 小部件我们可以监听鼠标事件, 但我还没有找到任何关于 flutter web 悬停事件的信息。 有人找到解决方案了吗?
我认为鼠标事件不会在网络上运行,Listener Widget 在 Google I/O 2019 年进行了演示并且可以使用鼠标,但它是作为 ChromeOS 应用程序而不是网络应用
At this time, desktop UI interactions are not fully complete, so a UI built with flutter_web may feel like a mobile app, even when running on a desktop browser.
从 dev 频道构建版本 1.19.0–3 开始。0.pre 内置了对指针光标的支持。使用与波纹管相同的方法,不同之处在于应用于 Flutter 应用程序容器元素 flt-glass-pane
。使用波纹管方法只会复制行为。
为了覆盖 pointer
光标,您可以使用波纹管方法,但应用于 flt-glass-pane
元素。
解决方法如下:
- 您必须在整个 body[=47= 上设置一个 id(例如 app-container ] 应用的 index.html 模板)。
这就是您的 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>
- 接下来,您必须创建一个包装飞镖 class。我称它为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
);
}
- 之后,无论您希望在何处显示手形光标,都必须将您的元素包装在此 HandCursor 包装器中。请参阅下面的 class 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 项目希望对您有所帮助。
以前的方法已弃用。这是更新后的代码
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
您仍然希望将应用程序容器的 ID 附加到您的 html 的正文中。这是我的 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>
您想将手形光标小部件的代码放在它自己的文件中。你可以称它为hand_cursor.dart。并在您希望手显示的小部件上使用它,将其导入您正在处理的文件并将您想要的小部件包装在 HandCursor 小部件中。
Constantin Stan 改编的答案
对于那些想要具有类似于 InkWell
小部件和边框半径选项的点击效果的用户:
添加到您的 pubspec.yaml 文件
dependencies:
universal_html: ^1.1.4
然后将以下标签添加到 index.html 文件中 <body id="app-container">
如下:
<!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
);
}
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']);
},
)
我很难找到有关现在内置支持的文档。以下是对我有帮助的内容:https://github.com/flutter/flutter/issues/58260
这对我有用,没有改变 index.html 等
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
child: Icon(
Icons.add_comment,
size: 20,
),
onTap: () {},
),
),
另见官方文档:https://api.flutter.dev/flutter/rendering/MouseCursor-class.html
Widget build(BuildContext context) {
return Center(
child: MouseRegion(
cursor: SystemMouseCursors.text,
child: Container(
width: 200,
height: 100,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(color: Colors.yellow),
),
),
),
);
}
这里 https://api.flutter.dev/flutter/material/MaterialStateMouseCursor-class.html 官方文档中的另一个精彩示例“...定义了一个鼠标光标,当其小部件被禁用时解析为 SystemMouseCursors.forbidden。”
从 Flutter beta 版本 1.19.0-4.1.pre
开始,将 id 添加到 body
并设置其光标不起作用。因为 flt-glass-pane
正在替换光标。
所以解决办法就是直接设置cursor到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
);
}
您可以使用具有 onHover 事件的 InkWell
InkWell(
onTap: () {},
onHover: (value) {
setState(() {
isHovered = value;
});
},
child: Container(
width: 50,
height: 72,
color: Colors.black
)
);
确保有一些onTap,即使是一个空函数,否则它被认为是禁用的,悬停将不起作用
我所知道的最简单的方法
InkWell(
onTap: (){},
mouseCursor: MaterialStateMouseCursor.clickable,
...