Flutter-Web: Mouse hover -> Change cursor to pointer
I had difficulties finding documentation on the now built-in support. Here is what helped me: https://github.com/flutter/flutter/issues/58260
And this did the trick for me, without changing index.html etc.
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
child: Icon(
Icons.add_comment,
size: 20,
),
onTap: () {},
),
),
Also see the official documentation: 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),
),
),
),
);
}
And here https://api.flutter.dev/flutter/material/MaterialStateMouseCursor-class.html yet another wonderful example from the official docs that "...defines a mouse cursor that resolves to SystemMouseCursors.forbidden when its widget is disabled."
Starting with dev channel build version 1.19.0–3.0.pre there is built-in support for the pointer cursor. The same method as bellow is used with the difference that is applied to the Flutter app container element flt-glass-pane
. Using the bellow method will just duplicate the behavior.
In order to override the pointer
cursor, you can use the bellow method but applied on the flt-glass-pane
element.
A workaround for this is the following:
- You have to set an id (for example app-container on the entire body of the app's index.html template).
This is how your index.html will look like:
<!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>
- Next, you have to create a wrapper dart class. I called it 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
);
}
- After that, wherever you want to have the hand cursor shown, you have to wrap your element in this HandCursor wrapper. See the class awesome_button.dart bellow:
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)
),
)
],
);
}
}
A short explanation can be found here.
A more versatile update, that works on the new web projects created with the master channel of Flutter, can be found here.
I hope it helps.
You can use an InkWell that has an onHover event
InkWell(
onTap: () {},
onHover: (value) {
setState(() {
isHovered = value;
});
},
child: Container(
width: 50,
height: 72,
color: Colors.black
)
);
Make sure to have something onTap, even an empty function, else it is considered to be disabled, and the hover won't work
The previous method is deprecated. Here is the updated code
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,
);
}
And in your pubspec.yaml file, add universal_html as a package as a dependency. The version may change.
dependencies:
flutter:
sdk: flutter
universal_html: ^1.1.4
You still want to have an id of app-container attached to the body of your html. Here is my html file.
<!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>
You want to put the code for the HandCursor widget in its own file. You can call it hand_cursor.dart. And to use it on the widget you want the hand to show up on, import it into the file you're working on and wrap the widget you want in the HandCursor widget.