Flutter-Web: наведение мыши -> изменить курсор на указатель
Как изменить внешний вид курсора в Flutter? Я знаю, что с помощью виджета Listener() мы можем прослушивать Mouse-Events, но я не нашел никакой информации, касающейся событий зависания для трепетной сети.
Кто-нибудь еще нашел поднос?
9 ответов
Мне было трудно найти документацию по встроенной поддержке. Вот что мне помогло: https://github.com/flutter/flutter/issues/58260
И это помогло мне, без изменения index.html и т. Д.
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
child: Icon(
Icons.add_comment,
size: 20,
),
onTap: () {},
),
),
Начиная с версии сборки канала разработки 1.19.0–3.0.pre, имеется встроенная поддержка курсора-указателя. Используется тот же метод, что и ниже, с той разницей, что применяется к элементу контейнера приложения Flutter.flt-glass-pane
. Использование метода ниже просто дублирует поведение.
Чтобы переопределить pointer
курсор, вы можете использовать метод ниже, но применяемый к flt-glass-pane
элемент.
Обходной путь для этого:
- Вы должны установить идентификатор (например, 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>
- Затем вам нужно создать класс-оболочку дротика. Я назвал его 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. См. Класс 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)
),
)
],
);
}
}
Краткое объяснение можно найти здесь.
Более универсальное обновление, которое работает с новыми веб-проектами, созданными с помощью главного канала Flutter, можно найти здесь.
Я надеюсь, что это помогает.
Вы можете использовать InkWell, у которого есть событие onHover
InkWell(
onTap: () {},
onHover: (value) {
setState(() {
isHovered = value;
});
},
child: Container(
width: 50,
height: 72,
color: Colors.black
)
);
Убедитесь, что есть что-то onTap, даже пустая функция, иначе она считается отключенной, и наведение не будет
Предыдущий метод устарел. Вот обновленный код
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. Вот мой 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.
Самый простой способ, который я знаю
InkWell(
onTap: (){},
mouseCursor: MaterialStateMouseCursor.clickable,
...
Из бета-версии Flutter 1.19.0-4.1.pre
, добавить идентификатор в 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
);
}
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']);
},
)
Я считаю, что события мыши не будут работать в Интернете, виджет Listener был продемонстрирован на Google I/O 2019 и работал с мышью, но это было приложение ChromeOS, а не веб-приложение.
Согласно Flutter Web на GitHub:
В настоящее время взаимодействие с пользовательским интерфейсом рабочего стола не полностью завершено, поэтому пользовательский интерфейс, созданный с помощью flutter_web, может ощущаться как мобильное приложение, даже если он запущен в браузере рабочего стола.
Адаптированный ответ Константина Стэна
Для тех, кто хочет иметь эффект щелчка, аналогичный 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
);
}