web-dev-qa-db-fra.com

Flutter-Web: survol de la souris -> Changer le curseur en pointeur

Comment changer l'apparence du curseur dans Flutter? Je sais qu'avec le widget Listener () , nous pouvons écouter les événements de souris, mais je n'ai trouvé aucune information concernant les événements planés pour le Web flottant.

Quelqu'un a-t-il déjà trouvé une soulution?

10
Daniel Szy

Une solution pour cela est la suivante:

  1. Vous devez définir un id (par exemple app-container sur l'ensemble corps de l'application index.html modèle).

Voici à quoi ressemblera votre 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. Ensuite, vous devez créer une classe Dart wrapper. Je l'ai appelé 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. Après cela, où que vous souhaitiez afficher le curseur de la main, vous devez envelopper votre élément dans ce wrapper HandCursor. Voir la classe awesome_button.Dart ci-dessous:
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)
          ),
        )
      ],
    );
  }

}

Une brève explication peut être trouvée ici .

Une mise à jour plus polyvalente, qui fonctionne sur les nouveaux projets Web créés avec le canal master de Flutter, peut être trouvée ici .

J'espère que ça aide.

11
Constantin Stan

La méthode précédente est obsolète. Voici le code mis à jour

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,
        );
}

Et dans votre fichier pubspec.yaml, ajoutez universal_html en tant que package en tant que dépendance. La version peut changer.

dependencies:
  flutter:
    sdk: flutter
  universal_html: ^1.1.4

Vous voulez toujours avoir un identifiant de conteneur d'application attaché au corps de votre html. Voici mon fichier 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>

Vous souhaitez placer le code du widget HandCursor dans son propre fichier. Vous pouvez l'appeler hand_cursor.Dart. Et pour l'utiliser sur le widget sur lequel vous voulez que la main apparaisse, importez-la dans le fichier sur lequel vous travaillez et enveloppez le widget que vous voulez dans le widget HandCursor.

5
Khari Lane

Je crois que les événements de souris ne fonctionneront pas sur le Web, Listener Widget a été démo sur Google I/O 2019 et a fonctionné avec la souris, mais c'était comme une application ChromeOS et non une application Web.

Selon Flutter web sur GitHub :

À l'heure actuelle, les interactions avec l'interface utilisateur du bureau ne sont pas entièrement terminées, de sorte qu'une interface utilisateur créée avec flutter_web peut ressembler à une application mobile, même lorsqu'elle s'exécute sur un navigateur de bureau.

3

Réponse adaptée de Constantin Stan

Pour ceux qui veulent avoir un effet de clic similaire au widget InkWell et avec l'option de rayon de bordure:

Ajoutez à votre fichier pubspec.yaml

dependencies:
  universal_html: ^1.1.4

Ajoutez ensuite au fichier index.html la balise suivante <body id="app-container"> comme ci-dessous:

<!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>

Enfin, créez le widget suivant et utilisez encapsulé tous les widgets nécessaires:

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
  );

}
1
Edeson Bizerril
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']);
                        },
                      )
0
yumi0629