Création de widgets personnalisés réutilisables dans Flutter

Online Coding Courses for Kids

Tout est un widget dans Flutter… alors ne serait-il pas intéressant de savoir comment créer le vôtre? Il existe plusieurs méthodes pour créer des widgets personnalisés, mais la plus élémentaire consiste à combiner des widgets existants simples dans le widget plus complexe que vous souhaitez. C’est appelé composition.

Dans ce didacticiel, vous apprendrez à créer un widget personnalisé que vous pouvez réutiliser n’importe où. Voici les compétences spécifiques que vous apprendrez à maîtriser:

  • Concevoir l’interface utilisateur du widget
  • Créez votre design à l’aide de widgets existants
  • Planifier et mettre en œuvre la manière dont les utilisateurs interagissent avec le widget

Commencer

Téléchargez le projet en cliquant sur le Télécharger les matériaux bouton en haut ou en bas de la page.

Cet article utilise Android Studio, mais Visual Studio Code fonctionnera également correctement.

Vous allez créer une application de lecture de musique appelée Classique. Il ne lit qu’une seule chanson, mais ce n’est pas grave parce que la chanson est tellement géniale que vous ne voudrez plus jamais écouter autre chose. :]

Voici à quoi ressemblera l’application lorsque vous aurez terminé:

Look fini de l'application classique

Le contrôle du lecteur audio en bas est le widget personnalisé que vous allez créer.

Ouvrez le projet de démarrage en accédant au entrée dossier et en cliquant Obtenir les dépendances lorsque Android Studio vous y invite.

Le projet de démarrage comprend déjà du code afin que vous puissiez terminer ce projet en un seul didacticiel. Si vous êtes curieux de connaître l’architecture de l’application, consultez l’article Gestion de l’état avec le fournisseur.

Exécutez l’application maintenant et vous verrez ceci:

Vue de démarrage de l'application classique

Il est temps de commencer à composer votre widget pour que vos utilisateurs puissent écouter de la musique délicieuse.

Refactorisation des dispositions de l’interface utilisateur

Comme vous le savez probablement, la disposition de l’interface utilisateur de Flutter se compose d’une arborescence de widgets.

Arborescence des widgets

Chaque feuille de l’arbre est un widget. Chaque branche de l’arbre est un widget. L’interface utilisateur entière elle-même n’est également qu’un widget. C’est l’intérêt de la composition: des widgets constitués de widgets jusqu’aux plus petits composants.

Le code de l’arborescence des widgets peut être assez imbriqué. Pour rendre votre code de mise en page plus lisible et maintenable, vous devez prendre en compte les groupes de widgets dans leurs propres classes de widgets autonomes.

Extraction de widgets

dans le lib dossier, ouvrir main.dart. Trouvez le MyApp widget, qui ressemble à ceci:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ...
        body: SafeArea(
          ...
        ),
    );
  }
}

Même si MyApp est déjà assez simple, vous pouvez le décomposer encore plus. C’est une bonne occasion d’en apprendre davantage sur la refactorisation et l’utilisation des outils d’Android Studio pour extraire les widgets.

Placez votre curseur sur Stack et clic-droit pour afficher le menu contextuel. Alors choisi Refactoriser ▸ Extraire ▸ Extraire le widget Flutter….

C’est le corps de Scaffold, alors nommez-le BodyWidget.

class BodyWidget extends StatelessWidget {
  const BodyWidget({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        // ...
      ],
    );
  }
}

Android Studio a créé automatiquement un nouveau widget à partir de Stack et ses widgets descendants. C’est tout. Vous avez terminé. Vous savez maintenant comment créer des widgets personnalisés dans Flutter. Merci d’avoir lu. Revenez dans le prochain tutoriel pour plus de contenu de qualité sur raywenderlich.com.

Je rigole. :]Il y a plus à propos de cet article à venir. Mais sérieusement, il est vraiment aussi simple de créer de nouveaux widgets.

Vous pourriez mettre BodyWidget dans son propre fichier et utilisez-le dans une autre partie de cette application ou même dans une autre application. Bien que ce widget lui-même ne soit pas particulièrement intéressant, le widget du lecteur audio que vous allez créer l’est.

Remarque: Lorsque vous avez extrait le widget Flutter, vous avez peut-être remarqué un autre choix dans le menu contextuel appelé Méthode. Cela aurait rendu le Stack arborescence de widgets à partir d’une méthode dans MyApp.

Bien que ce soit bien, il y a un certain nombre d’avantages à l’extraction en tant que widget plutôt qu’une méthode ou une fonction. Le principal avantage de cet article est que vous pouvez réutiliser les widgets extraits.

Types de widgets personnalisés

Cet article se concentre sur le moyen le plus simple de créer des widgets personnalisés: la composition ou la création de widgets complexes en combinant des widgets plus simples. Cependant, il convient de mentionner quelques autres façons de créer des widgets personnalisés.

Si vous ne parvenez pas à obtenir le widget souhaité en combinant d’autres widgets, vous pouvez le dessiner sur un canevas fourni par Flutter. Vous faites cela en utilisant CustomPainter. Lisez Dessiner des formes personnalisées avec CustomPainter dans Flutter pour un excellent exemple de la façon de procéder.

Si vous voulez aller très bas, il est également possible de créer des widgets de la même manière que le framework Flutter: en utilisant RenderObjects. La meilleure façon d’en savoir plus est d’explorer le code source Flutter d’un widget similaire à celui que vous souhaitez créer. Découvrez Flutter Text Rendering pour un exemple réel de création d’un widget à partir de zéro.

Il est temps de se mettre au travail. Cet article vous expliquera étape par étape tout ce que vous devez faire pour créer vos propres widgets personnalisés. Voici les étapes à suivre:

  1. Concevez votre widget
  2. Décomposer le design
  3. Construisez le widget de base
  4. Personnalisez le look
  5. Déterminez l’interaction de l’utilisateur
  6. Définir les paramètres
  7. Mettre en œuvre les paramètres
  8. Testez le widget
  9. Partagez votre widget avec le monde

Au cours des quatre étapes suivantes, vous déterminerez à quoi ressemblera l’interface utilisateur.

Conception de votre widget

Il est utile d’avoir une représentation visuelle du widget que vous voulez dans votre esprit. Dessinez-le sur papier ou utilisez un logiciel de conception pour le dessiner.

Vous pouvez également emprunter des idées de design à d’autres. Ce n’est pas parce que vous êtes développeur que vous ne pouvez pas non plus apprendre à être un grand designer. Si vous aimez les podcasts, consultez Conseils de conception pour les ingénieurs pour développer davantage vos compétences dans ce domaine.

Pour un widget de contrôle de lecteur audio, MediaElement.js est un bon point de départ solide:

Conception de l'interface utilisateur de MediaElement.js Audio Player montrant un bouton de lecture, l'heure actuelle, un curseur de temps, la durée totale et le contrôle du volume

Le contrôle du volume n’est pas important pour ce didacticiel, alors rognez-le:

MediaElement.js sans contrôle du volume

Décomposer le design

Une fois que vous avez le design souhaité, identifiez les petits widgets que vous pouvez utiliser pour le créer. Vous devriez pouvoir obtenir quelque chose de proche avec IconButton, Slider, Container et quelques Text widgets.

Lecteur audio décomposé en widgets

Oh, oui, ils sont disposés dans une rangée, vous aurez donc besoin d’un Row widget, aussi.

Construire le widget de base

Créez un nouveau fichier en cliquant avec le bouton droit de la souris sur lib dossier et choix Nouveau ▸ fichier. Nomme le audio_widget.dart.

Entrez ensuite le code suivant:

import 'package:flutter/material.dart';

class AudioWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        children: [
          IconButton(icon: Icon(Icons.play_arrow)),
          Text('00:37'),
          Slider(value: 0),
          Text('01:15'),
        ],
      ),
    );
  }
}

Noter la Container, Row, Button, Text et Slider widgets.

De retour lib / main.dart, faites défiler vers le bas du fichier et supprimez la ligne qui dit TODO supprimer cette ligne. Puis décommentez la ligne qui dit TODO décommenter cette ligne.

Ajoutez l’importation en haut:

import 'audio_widget.dart';

Créez et exécutez l’application.

Cela vous donne ce qui suit. Si vous ignorez le fait qu’il repose sur la poitrine de Beethoven, cela ressemble déjà beaucoup à une commande de lecteur audio.

Widget audio égaré à mi-chemin de la vue de l'application

Personnaliser l’apparence

Pour que le contrôle ressemble davantage au lecteur audio MediaElement.js, vous devez effectuer quelques ajustements.

Ouvert lib / audio_widget.dart encore.

La première chose à faire est de donner au widget une hauteur fixe afin qu’il ne occupe pas tout l’écran. Ajoutez la ligne suivante au Container widget avant son child paramètre.

height: 60,

C’est là que le rechargement à chaud brille. Appuyez sur le bouton jaune Lightning dans Android Studio pour obtenir une mise à jour instantanée.

C’est mieux. Maintenant, il est en bas où il est censé être:

Widget audio avec une hauteur fixe

Le bouton semble un peu trop sombre. C’est parce qu’il a besoin d’une fonction pour son onPressed callback pour l’activer. Ajouter onPressed: (){}, à IconButton donc ça ressemble à ceci:

IconButton(
  icon: Icon(Icons.play_arrow),
  onPressed: (){},
),

Faites une recharge à chaud.

Le bouton Lecture est maintenant plus clair:

Widget audio avec bouton blanc

Vous pouvez personnaliser un peu la Slider widget. Ajoutez les paramètres suivants:

Slider(
  value: 0.5,
  activeColor: Theme.of(context).textTheme.bodyText2.color,
  inactiveColor: Theme.of(context).disabledColor,
  onChanged: (value){},
),

Voici quelques notes sur ce code:

  • Une valeur de 0.5 place le curseur du curseur au milieu.
  • Plutôt que de coder en dur les couleurs actives et inactives, obtenir les couleurs du thème permet à ce widget de fonctionner dans les modes sombre et clair. C’est une victoire pour la réutilisabilité.
  • Donnant onChanged une valeur active le curseur. Vous ajouterez plus de code ici plus tard.

Faites une recharge à chaud.

Widget audio avec curseur et beaucoup d'espace vide sur la droite

Il y a trop d’espace vide sur la droite. Slider peut avoir n’importe quelle longueur, alors enveloppez-le avec Expanded. Avec votre curseur sur Slider, presse Option-Retour sur un Mac ou Alt-Entrée sur un PC. Choisir Envelopper avec un widget dans le menu contextuel et changer widget à Étendu.

Expanded(
  child: Slider(...),
)

Faites une recharge à chaud.

Widget audio avec curseur enveloppé étendu atteignant le bord droit de l'écran

On dirait qu’il a besoin d’un peu de rembourrage sur la droite. Ajouter SizedBox(width: 16), à la fin de la liste des Row les enfants aiment ça:

IconButton(...),
Text(...),
Slider(...),
Text(...),
SizedBox(width: 16),

Faites une recharge à chaud.

Widget audio avec rembourrage

Génial! Cela semble plutôt bien pour le moment.

Maintenant que vous avez terminé l’interface utilisateur, vous devez autoriser l’utilisateur à interagir avec le widget audio. Vous allez ajouter ces fonctionnalités UX au cours des trois prochaines étapes.

Déterminer l’interaction de l’utilisateur

Il y a quatre pièces ici:

Les quatre parties de l'UX du widget audio

  1. Bouton Lecture / Pause: Lorsqu’un utilisateur clique dessus, il doit alterner entre un Jouer et un Pause icône. Lorsque l’audio atteint la fin de la piste, il doit également revenir au Jouer icône. Cela signifie qu’il doit y avoir un moyen de définir l’icône du bouton, ou peut-être l’état de lecture.
  2. Heure actuelle: L’utilisateur de l’application n’interagit pas avec l’heure actuelle, mais le développeur doit disposer d’un moyen de la mettre à jour en fonction du plug-in audio qu’il utilise.
  3. Barre de recherche: Le développeur doit être en mesure de mettre à jour la position en fonction du temps écoulé de l’audio en cours de lecture. L’utilisateur doit également être en mesure de le faire glisser vers un nouvel emplacement et d’en informer un auditeur.
  4. Temps total: Le développeur doit pouvoir définir cela en fonction de la longueur du fichier audio.
Remarque: Ce widget ne lira en fait aucun audio lui-même. C’est plutôt un skin qu’un développeur peut utiliser avec n’importe quel plug-in de lecteur audio. Ils reconstruiront simplement le widget chaque fois que l’état audio change. L’application Classique utilise le lecteurs audio brancher.

Définition des paramètres

Imaginez que vous soyez un développeur utilisant ce widget. Comment voudriez-vous définir les valeurs?

Ce serait une façon raisonnable de le faire:

AudioWidget(
  isPlaying: false,
  onPlayStateChanged: (bool isPlaying) {},
  currentTime: Duration(),
  onSeekBarMoved: (Duration newCurrentTime) {},
  totalTime: Duration(minutes: 1, seconds: 15),
),

Voici ce que fait ce code:

  • est en train de jouer: Cela vous permet de basculer Jouer pause icône du bouton.
  • onPlayStateChanged: Le widget vous avertit lorsque l’utilisateur appuie sur le Jouer pause bouton.
  • heure actuelle: En utilisant Duration ici, plutôt que String ou Text, vous n’avez pas à vous soucier de définir le texte de l’heure actuelle et le Slider position du pouce séparément. Le widget gérera les deux.
  • onSeekBarMoved: Cela vous met à jour lorsque l’utilisateur choisit un nouvel emplacement.
  • temps total: Comme currentTime, cela peut aussi être un Duration.

C’est la tactique que vous utiliserez dans ce didacticiel.

Implémentation des paramètres

Il y a une poignée de sous-étapes nécessaires pour mettre en œuvre votre plan ci-dessus.

Conversion en StatefulWidget

Vous avez initialement créé un widget sans état, mais vous devez le convertir en StatefulWidget car vous devez maintenant garder une trace de Slider état en interne.

Dans lib / audio_widget.dart, placez votre curseur sur le AudioWidget nom du cours. presse Option-Retour sur un Mac ou Alt-Entrée sur un PC pour afficher le menu contextuel. Choisir Convertir en StatefulWidget. Vous verrez quelque chose de similaire à ce qui suit:

class AudioWidget extends StatefulWidget {
  @override
  _AudioWidgetState createState() => _AudioWidgetState();
}

class _AudioWidgetState extends State {
  @override
  Widget build(BuildContext context) {
    return Container(...);
  }
}

Ajout d’un constructeur StatefulWidget

Maintenant en AudioWidget (ne pas _AudioWidgetState), ajoutez un constructeur avec les paramètres que vous avez définis ci-dessus:

const AudioWidget({
  Key key,
  this.isPlaying = false,
  this.onPlayStateChanged,
  this.currentTime,
  this.onSeekBarMoved,
  @required this.totalTime,
}) : super(key: key);

final bool isPlaying;
final ValueChanged onPlayStateChanged;
final Duration currentTime;
final ValueChanged onSeekBarMoved;
final Duration totalTime;

Voici quelques points à noter:

  • Le code source des widgets Flutter standard est très utile pour voir comment d’autres widgets sont construits. le Code source du widget Slider est particulièrement utile ici.
  • Tous les widgets ont des clés. Regarder Quand utiliser les clés pour en savoir plus sur eux.
  • ValueChanged est juste un autre nom pour Function(T value). C’est ainsi que vous créez un paramètre avec une fermeture.
  • Il n’aurait pas de sens d’avoir un lecteur audio sans une durée totale. le @required l’annotation est utile pour appliquer cela.

Puisque totalTime est requis maintenant, allez à main.dart et ajoutez un arbitraire Duration à la AudioWidget constructeur.

return AudioWidget(
  totalTime: Duration(minutes: 1, seconds: 15),
);

Vous allez accrocher AudioWidget jusqu’au modèle de vue plus tard pour obtenir une durée audio réelle.

Implémentation du bouton Play

Vous gérerez la logique de la Jouer pause bouton suivant.

Widget audio avec le bouton Lecture surligné en rouge

Vous n’allez pas ajouter d’état interne pour ce bouton. Le développeur peut suivre l’état de la lecture en fonction du plug-in audio qui lit réellement la musique. Lorsque cet état change, le développeur peut simplement reconstruire ce widget avec une nouvelle valeur pour isPlaying.

Pour garder le code de disposition de l’interface utilisateur propre, créez le bouton Lecture dans sa propre méthode. Revenir à lib / audio_widget.dart. Dans _AudioWidgetState, place ton curseur sur IcôneButton, faites un clic droit et choisissez Refactor ▸ Extract ▸ Méthode dans le menu contextuel. Cette fois, vous procédez à l’extraction en tant que méthode plutôt qu’en tant que widget afin de pouvoir tout conserver dans la classe d’état.

Nommez la méthode _buildPlayPauseButton et donnez-lui ce code:

IconButton _buildPlayPauseButton() {
  return IconButton(
    icon:
    (widget.isPlaying)
        ? Icon(Icons.pause)
        : Icon(Icons.play_arrow),
    color: Colors.white,
    onPressed: () {
      if (widget.onPlayStateChanged != null) {
        widget.onPlayStateChanged(!widget.isPlaying);
      }
    },
  );
}

Voici quelques notes sur le code ci-dessus:

  • IconButton choisit maintenant une icône basée sur isPlayingLa valeur de. Appuyez sur le bouton pour avertir quiconque écoute onPlayStateChanged à propos de l’événement.
  • Les variables dans StatefulWidget sont disponibles pour la classe d’état en les préfixant avec widget.. Par exemple, dans _AudioWidgetState vous pouvez référencer le isPlaying variable de AudioWidget en utilisant widget.isPlaying.

Faites un redémarrage à chaud. Un inconvénient de l’extraction vers une méthode plutôt que vers un widget est que le rechargement à chaud ne fonctionne pas.

Appuyez maintenant sur le bouton Lecture, mais il n’y a pas de réponse. C’est parce que vous n’avez pas intégré de logique pour modifier le isPlaying valeur encore. Vous le ferez une fois que vous aurez mis en œuvre tous les autres widgets.

Implémentation de la barre de recherche

Faites ensuite la barre de recherche car l’étiquette d’heure actuelle en dépend.

Widget audio avec la barre de recherche encadrée en rouge

Ajoutez deux variables d’état en haut de _AudioWidgetState:

double _sliderValue;
bool _userIsMovingSlider;

La valeur du curseur peut être un double de 0.0 à 1.0. Ajoutez une méthode au bas de la _AudioWidgetState classe pour le calculer:

double _getSliderValue() {
  if (widget.currentTime == null) {
    return 0;
  }
  return widget.currentTime.inMilliseconds / widget.totalTime.inMilliseconds;
}

Utilisez des millisecondes plutôt que des secondes pour que la barre de recherche se déplace en douceur, plutôt que de sauter d’une seconde à l’autre.

Lorsque l’utilisateur déplace le curseur manuellement, vous aurez besoin d’une méthode pour calculer l’heure actuelle en fonction de la valeur du curseur. Ajoutez la méthode suivante au bas de la _AudioWidgetState classe:

Duration _getDuration(double sliderValue) {
  final seconds = widget.totalTime.inSeconds * sliderValue;
  return Duration(seconds: seconds.toInt());
}

Vous pouvez maintenant initialiser les variables d’état. Ajoutez la méthode suivante ci-dessus build dans _AudioWidgetState:

@override
void initState() {
  super.initState();
  _sliderValue = _getSliderValue();
  _userIsMovingSlider = false;
}

Cette méthode n’est appelée que la première fois que le widget est construit.

Lorsque l’utilisateur déplace la barre de recherche en même temps que la lecture audio, vous ne voulez pas _sliderValue se battre contre widget.currentTime. le _userIsMovingSlider flag vous aide à vérifier cela. Appliquez le drapeau en ajoutant les lignes suivantes à l’intérieur build avant le return déclaration.

if (!_userIsMovingSlider) {
  _sliderValue = _getSliderValue();
}

Maintenant, extrayez Slider dans une méthode comme vous l’avez fait pour IconButton plus tôt. Placez votre curseur sur Étendu – le parent de Slider – faites un clic droit et choisissez Refactor ▸ Extract ▸ Méthode dans le menu contextuel.

Nommez la méthode _buildSeekBar et donnez-lui le code suivant:

Expanded _buildSeekBar(BuildContext context) {
  return Expanded(
    child: Slider(
      value: _sliderValue,
      activeColor: Theme.of(context).textTheme.bodyText2.color,
      inactiveColor: Theme.of(context).disabledColor,
      // 1
      onChangeStart: (value) {
        _userIsMovingSlider = true;
      },
      // 2
      onChanged: (value) {
        setState(() {
          _sliderValue = value;
        });
      },
      // 3
      onChangeEnd: (value) {
        _userIsMovingSlider = false;
        if (widget.onSeekBarMoved != null) {
          final currentTime = _getDuration(value);
          widget.onSeekBarMoved(currentTime);
        }
      },
    ),
  );
}

Voici quelques points à noter:

  1. L’utilisateur commence à déplacer manuellement le Slider pouce.
  2. Chaque fois que le Slider le pouce bouge, _sliderValue doit être mis à jour. Cela affectera l’interface utilisateur en mettant à jour la position visuelle du pouce sur le curseur.
  3. Lorsque l’utilisateur a fini de déplacer le pouce, désactivez le drapeau pour recommencer à le déplacer en fonction de la position de lecture. Puis informez tous les auditeurs de la nouvelle position de recherche.

Faites un redémarrage à chaud.

Widget audio avec un utilisateur déplaçant la barre de recherche

Le curseur se déplace maintenant, mais l’étiquette n’est toujours pas mise à jour. Vous aborderez cette question ensuite.

Implémentation de l’étiquette d’heure actuelle

Vous pouvez modifier l’heure actuelle en modifiant la valeur du constructeur ou en déplaçant le curseur.

Widget audio avec l'étiquette d'heure actuelle surlignée en rouge

Puisque Slider doit toujours rester synchronisé avec l’étiquette d’heure actuelle, utilisez _sliderValue pour générer la chaîne d’étiquette.

Ajoutez la méthode suivante au bas de la _AudioWidgetState classe:

String _getTimeString(double sliderValue) {
  final time = _getDuration(sliderValue);

  String twoDigits(int n) {
    if (n >= 10) return "$n";
    return "0$n";
  }

  final minutes = twoDigits(time.inMinutes.remainder(Duration.minutesPerHour));
  final seconds = twoDigits(time.inSeconds.remainder(Duration.secondsPerMinute));

  final hours = widget.totalTime.inHours > 0 ? '${time.inHours}:' : '';
  return "$hours$minutes:$seconds";
}

Cette méthode est une modification du Dart Duration.toString() méthode.

Ensuite, extrayez l’heure actuelle Text widget à une méthode. Dans build, placez votre curseur sur le premier Texte widget, faites un clic droit et choisissez Refactor ▸ Extract ▸ Méthode dans le menu contextuel.

Nommez la méthode _buildCurrentTimeLabel et donnez-lui le code suivant:

Text _buildCurrentTimeLabel() {
  return Text(
    _getTimeString(_sliderValue),
    style: TextStyle(
      fontFeatures: [FontFeature.tabularFigures()],
    ),
  );
}

FontFeature nécessite le dart:ui bibliothèque, ajoutez donc l’importation suivante en haut du fichier:

import 'dart:ui';

En utilisant FontFeature.tabularFigures() garantit que les chiffres utiliseront une largeur à espacement fixe. Cela garde le Text largeur de sauter. En savoir plus Fonctionnalités de police dans Flutter pour apprendre plus.

Faites un redémarrage à chaud.

Widget audio avec mise à jour de l'heure actuelle à mesure que la barre de recherche se déplace

Désormais, l’étiquette d’heure actuelle est mise à jour lorsque vous déplacez le curseur de la barre de recherche.

Implémentation de l’étiquette de temps total

Le dernier de tous est l’étiquette de temps total à l’extrême droite.

Widget audio avec l'étiquette de temps total encadrée en rouge

Extraire le temps total Text widget à sa propre méthode. Comme avant, dans build, placez votre curseur sur le dernier Texte widget, faites un clic droit et choisissez Refactor ▸ Extract ▸ Méthode dans le menu contextuel.

Nommez la méthode _buildTotalTimeLabel et donnez-lui le code suivant:

Text _buildTotalTimeLabel() {
  return Text(
    _getTimeString(1.0),
  );
}

Le temps total correspond au moment où le curseur est complètement à droite, ce qui correspond à une valeur de curseur de 1.0. Ainsi, vous pouvez utiliser _getTimeString() à nouveau pour générer la chaîne d’étiquette.

Faites un redémarrage à chaud.

Il a le même aspect qu’avant car le totalTime l’argument est Duration(minutes: 1, seconds: 15), que vous avez défini précédemment dans main.dart.

Widget audio avec l'heure actuelle

Génial! Vous avez maintenant votre propre widget personnalisé composé entièrement de widgets Flutter existants.

Au cours des deux dernières étapes, vous finaliserez votre widget pour la production.

Tester le widget

Les tests de widgets sont une partie importante de la création de widgets personnalisés. Pour garder cet article à une taille gérable, il ne couvrira pas les tests de widgets, mais vous devriez lire Une introduction aux tests de widgets dans la documentation Flutter et Widget Testing With Flutter: Premiers pas ici sur raywenderlich.com.

Pour l’instant, vous allez simplement tester cela AudioWidget fonctionne en le connectant à un plugin audio. Le modèle de vue dans le projet de démarrage est prêt à communiquer avec votre nouveau widget.

Dans lib / main.dart, supprimez le tout AudioPlayer class, situé au bas du fichier, puis ajoutez le code suivant:

class AudioPlayer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ViewModelBuilder.reactive(
      viewModelBuilder: () => AudioViewModel(),
      onModelReady: (model) => model.loadData(),
      builder: (context, model, child) => AudioWidget(
        isPlaying: model.isPlaying,
        onPlayStateChanged: (bool isPlaying) {
          model.onPlayStateChanged(isPlaying);
        },
        currentTime: model.currentTime,
        onSeekBarMoved: (Duration newCurrentTime) {
          model.seek(newCurrentTime);
        },
        totalTime: model.totalTime,
      ),
    );
  }
}

AudioWidget est la partie la plus importante ici. Il obtient son état de model et reconstruit chaque fois que les valeurs changent. Il met également à jour model lorsque l’utilisateur appuie sur le Jouer pause ou déplace la barre de recherche.

Faites une recharge à chaud, appuyez sur le Jouer bouton et profitez du concert.

Application classique terminée

Voici à quoi cela ressemble en action:

Widget audio avec musique

Partager votre widget avec le monde

Maintenant que vous avez une version fonctionnelle de AudioWidget, vous ou n’importe qui d’autre pouvez l’utiliser simplement en copiant audio_widget.dart dans un projet. Vous pouvez faciliter l’utilisation par d’autres personnes en le partageant sur Pub, le référentiel central des packages Flutter et Dart.

Voici quelques instructions générales pour ajouter un package Pub:

  • Démarrez un nouveau projet Flutter dans Android Studio et choisissez Forfait Flutter pour le type de projet.
  • Placez votre widget personnalisé dans le lib dossier.
  • Ajouter un dossier nommé exemple à la racine du projet. À l’intérieur, ajoutez une application Flutter qui montre comment utiliser votre widget. L’exemple de projet pubspect.yaml importe le widget en utilisant path: ../. Trouvez des exemples d’autres développeurs sur GitHub pour voir comment ils l’ont fait. La plupart des packages Pub ont des liens vers leurs dépôts GitHub.
  • Créez un référentiel GitHub pour votre propre projet. Assurez-vous que toutes vos méthodes et paramètres publics ont une documentation de commentaires.
  • Lis Développement de packages et de plugins et Publication de packages.
  • Une fois que vous avez tout configuré, exécutez pub publish depuis la racine du projet, vous publiez votre package. Cependant, vous devez d’abord le tester avec pub publish --dry-run.

Où aller en partant d’ici?

Téléchargez le projet final à l’aide du Télécharger les matériaux bouton en haut ou en bas de ce didacticiel.

Si vous souhaitez améliorer le widget, voici quelques idées:

  • Ajoutez plus de paramètres de constructeur pour permettre aux développeurs de personnaliser davantage l’apparence et le comportement du widget.
  • Prend en charge la lecture audio à partir de sources distantes en permettant au bouton Lecture d’afficher un indicateur de progression circulaire pendant le téléchargement ou la mise en mémoire tampon du fichier audio.
  • Remplacer Slider avec un CustomPainter où vous dessinez la progression de la lecture et le contenu mis en mémoire tampon séparément. Faire référence à RangeSlider pour des idées.

Voici quelques bonnes vidéos pour en savoir plus sur la création de widgets personnalisés:

Si vous avez des commentaires ou des questions, veuillez les laisser dans le forum de discussion ci-dessous.

Close Menu