flutter_secret_keyboard 1.5.0
flutter_secret_keyboard: ^1.5.0 copied to clipboard
Une bibliothèque Flutter pour implémenter un clavier de saisie de code secret sécurisé avec disposition aléatoire des touches.
Flutter Secret Keyboard #
Une bibliothèque Flutter pour implémenter un clavier de saisie de code secret sécurisé avec disposition aléatoire des touches.
Caractéristiques #
- Clavier numérique avec disposition aléatoire des touches pour une sécurité accrue
- Effets tactiles interactifs (ripple, échelle, couleur, élévation, bordure, flou)
- Brouillage visuel des touches après pression pour une sécurité renforcée
- Système de thèmes prédéfinis (Material, Neumorphique, iOS, Sombre, Bancaire, Flou)
- Configuration flexible avec support pour 3 ou 4 colonnes
- Option pour activer ou désactiver le mélange aléatoire des touches
- Liaison avec un TextField pour afficher le code saisi
- Support pour les inputFormatters permettant de formater le texte saisi
- Support pour l'authentification par empreinte digitale
- Indicateurs visuels de saisie du code
- Hautement personnalisable (couleurs, styles, icônes)
- Aucune dépendance externe
- Support des fonctions de rappel pour différentes actions (code complété, empreinte digitale, etc.)
Installation #
Ajoutez flutter_secret_keyboard
à votre fichier pubspec.yaml :
dependencies:
flutter_secret_keyboard: ^1.5.0
Configuration requise #
- Dart SDK: >=2.17.0 <4.0.0
- Flutter: >=2.10.0
Utilisation #
Voici un exemple simple d'utilisation de la bibliothèque :
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_secret_keyboard/flutter_secret_keyboard.dart';
class SecretKeyboardDemo extends StatefulWidget {
const SecretKeyboardDemo({Key? key}) : super(key: key);
@override
State<SecretKeyboardDemo> createState() => _SecretKeyboardDemoState();
}
class _SecretKeyboardDemoState extends State<SecretKeyboardDemo> {
late SecretKeyboardController _controller;
final TextEditingController _textController = TextEditingController();
String _enteredCode = '';
@override
void initState() {
super.initState();
_controller = SecretKeyboardController(
fingerprintEnabled: true, // Activer le bouton d'empreinte digitale
maxLength: 4, // Définir la longueur du code à 4 chiffres
randomizeKeys: true, // Activer le mélange aléatoire des touches
gridColumns: 3, // Configurer le clavier avec 3 colonnes
);
}
@override
void dispose() {
_controller.dispose();
_textController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// TextField lié au clavier
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextField(
controller: _textController,
readOnly: true,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Code PIN',
),
style: const TextStyle(fontSize: 24, letterSpacing: 8),
),
),
const SizedBox(height: 20),
// Clavier secret avec liaison au TextField
SecretKeyboard(
controller: _controller,
codeLength: 4,
gridColumns: 3, // Configuration avec 3 colonnes
textController: _textController, // Liaison avec le TextField
obscureText: true, // Masquer le texte
inputFormatters: [ // Ajout de formatters
LengthLimitingTextInputFormatter(4), // Limite à 4 caractères
FilteringTextInputFormatter.digitsOnly, // Uniquement des chiffres
],
onClick: (code) {
setState(() {
_enteredCode = code;
});
},
onCodeCompleted: (code) {
// Code complet, faire quelque chose
print('Code complet: $code');
},
onFingerprintClick: (_) {
// Lancer l'authentification par empreinte digitale
print('Authentification par empreinte digitale demandée');
},
// Personnalisation des icônes
deleteButtonWidget: const Icon(
Icons.backspace_outlined,
color: Colors.red,
size: 30,
),
fingerprintButtonWidget: const Icon(
Icons.fingerprint,
color: Colors.blue,
size: 30,
),
),
],
),
);
}
}
Nouveautés de la version 1.4.0 #
Brouillage visuel #
Cette fonctionnalité de sécurité applique un effet de flou temporaire sur chaque touche immédiatement après qu'elle soit pressée, rendant plus difficile pour un observateur potentiel de voir quelle touche a été utilisée.
// Utilisation de l'effet de flou
SecretKeyboard(
controller: _controller,
touchEffect: KeyTouchEffect.blur, // Activer l'effet de flou
blurIntensity: 5.0, // Intensité du flou (1.0 à 10.0)
blurDuration: Duration(milliseconds: 300), // Durée de l'effet
blurEnabled: true, // Activer/désactiver la fonctionnalité
// ...
)
L'effet de flou peut être combiné avec d'autres mesures de sécurité comme la disposition aléatoire des touches pour une protection maximale.
Effets tactiles #
Le clavier secret propose désormais six types d'effets tactiles pour améliorer l'expérience utilisateur :
// Utilisation d'un effet tactile
SecretKeyboard(
controller: _controller,
touchEffect: KeyTouchEffect.scale, // Effet d'échelle
touchEffectColor: Colors.blue, // Couleur de l'effet (si applicable)
touchEffectDuration: const Duration(milliseconds: 120), // Durée de l'animation
touchEffectScaleValue: 0.92, // Valeur d'échelle pour l'effet scale
// ...
)
Types d'effets disponibles :
KeyTouchEffect.none
- Aucun effetKeyTouchEffect.ripple
- Effet d'ondulation Material DesignKeyTouchEffect.scale
- Animation de réduction d'échelleKeyTouchEffect.color
- Changement de couleurKeyTouchEffect.elevation
- Effet d'élévation/ombreKeyTouchEffect.border
- Animation de bordureKeyTouchEffect.blur
- Effet de flou temporaire
Système de thèmes prédéfinis #
// Utilisation d'un thème prédéfini
SecretKeyboard(
controller: _controller,
theme: SecretKeyboardTheme.banking, // Thème bancaire prédéfini
// Les autres propriétés de style seront ignorées
// car elles sont définies par le thème
)
Thèmes disponibles :
SecretKeyboardTheme.material
- Style Material Design moderneSecretKeyboardTheme.materialWithBorders
- Material Design avec borduresSecretKeyboardTheme.neumorphic
- Effet d'élévation subtilSecretKeyboardTheme.iOS
- Style minimaliste inspiré d'iOSSecretKeyboardTheme.iOSWithBorders
- Style iOS avec borduresSecretKeyboardTheme.dark
- Thème sombre pour interfaces dark modeSecretKeyboardTheme.darkWithBorders
- Thème sombre avec borduresSecretKeyboardTheme.banking
- Style professionnel et sécuriséSecretKeyboardTheme.gridLines
- Avec bordures internes seulementSecretKeyboardTheme.fullGrid
- Avec bordures internes et externesSecretKeyboardTheme.blurredModern
- Style moderne avec effet de flouSecretKeyboardTheme.blurredDark
- Style sombre avec effet de flou
Création d'un thème personnalisé #
// Création d'un thème personnalisé
final monTheme = SecretKeyboardTheme(
touchEffect: KeyTouchEffect.elevation,
primaryColor: Colors.purple,
secondaryColor: Colors.purple[200],
backgroundColor: Colors.grey[100]!,
textColor: Colors.black87,
textStyle: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
animationDuration: const Duration(milliseconds: 150),
showBorders: false,
showOuterBorder: false,
borderColor: Colors.grey.withOpacity(0.5),
// Paramètres pour l'effet de flou
blurIntensity: 4.0,
blurDuration: const Duration(milliseconds: 350),
blurEnabled: true,
);
// Utilisation du thème personnalisé
SecretKeyboard(
controller: _controller,
theme: monTheme,
// ...
)
Exemple complet avec thème et effets #
import 'package:flutter/material.dart';
import 'package:flutter_secret_keyboard/flutter_secret_keyboard.dart';
class SecretKeyboardDemo extends StatefulWidget {
const SecretKeyboardDemo({Key? key}) : super(key: key);
@override
State<SecretKeyboardDemo> createState() => _SecretKeyboardDemoState();
}
class _SecretKeyboardDemoState extends State<SecretKeyboardDemo> {
late SecretKeyboardController _controller;
final TextEditingController _textController = TextEditingController();
SecretKeyboardTheme _selectedTheme = SecretKeyboardTheme.material;
@override
void initState() {
super.initState();
_controller = SecretKeyboardController(
fingerprintEnabled: true,
maxLength: 4,
randomizeKeys: true,
gridColumns: 4,
);
}
@override
void dispose() {
_controller.dispose();
_textController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Clavier Sécurisé')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Sélecteur de thème
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: DropdownButton<SecretKeyboardTheme>(
value: _selectedTheme,
isExpanded: true,
onChanged: (theme) {
if (theme != null) {
setState(() {
_selectedTheme = theme;
});
}
},
items: const [
DropdownMenuItem(
value: SecretKeyboardTheme.material,
child: Text('Thème Material'),
),
DropdownMenuItem(
value: SecretKeyboardTheme.neumorphic,
child: Text('Thème Neumorphique'),
),
DropdownMenuItem(
value: SecretKeyboardTheme.iOS,
child: Text('Thème iOS'),
),
DropdownMenuItem(
value: SecretKeyboardTheme.dark,
child: Text('Thème Sombre'),
),
DropdownMenuItem(
value: SecretKeyboardTheme.banking,
child: Text('Thème Bancaire'),
),
DropdownMenuItem(
value: SecretKeyboardTheme.blurredModern,
child: Text('Thème Flou Moderne'),
),
DropdownMenuItem(
value: SecretKeyboardTheme.blurredDark,
child: Text('Thème Flou Sombre'),
),
],
),
),
const SizedBox(height: 20),
// TextField lié au clavier
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: TextField(
controller: _textController,
readOnly: true,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Code PIN',
),
style: const TextStyle(fontSize: 24, letterSpacing: 8),
),
),
const SizedBox(height: 20),
// Clavier secret avec thème
SecretKeyboard(
controller: _controller,
textController: _textController,
theme: _selectedTheme, // Utilisation du thème sélectionné
onClick: (code) {
// Traitement du code
},
onCodeCompleted: (code) {
// Code complet, faire quelque chose
print('Code complet: $code');
},
onFingerprintClick: (_) {
// Lancer l'authentification par empreinte digitale
print('Authentification par empreinte digitale demandée');
},
),
],
),
);
}
}
Personnalisation #
Le clavier est hautement personnalisable. Voici quelques exemples :
Configuration du nombre de colonnes #
// Dans le contrôleur
SecretKeyboardController(
gridColumns: 3, // 3 colonnes pour une disposition téléphone
// ...
)
// Dans le widget
SecretKeyboard(
gridColumns: 3, // 3 colonnes (doit correspondre au controller)
// ...
)
Mode 3 colonnes vs 4 colonnes #
- 3 colonnes : Disposition similaire au clavier téléphonique standard (1-9, puis 0)
- 4 colonnes : Disposition élargie pour plus d'espace entre les touches
Activation/désactivation du mélange des touches #
// Dans le contrôleur
SecretKeyboardController(
randomizeKeys: true, // true pour mélanger, false pour l'ordre standard
// ...
)
Liaison avec un TextField #
// Créer un contrôleur de texte
final TextEditingController textController = TextEditingController();
// L'utiliser avec le clavier
SecretKeyboard(
controller: keyboardController,
textController: textController, // Liaison avec le TextField
obscureText: true, // Masquer le texte avec des points
obscuringCharacter: '•', // Caractère de masquage personnalisé
// ...
)
// Important : ne pas définir obscureText sur le TextField lui-même
// car c'est géré par le SecretKeyboard
TextField(
controller: textController,
readOnly: true, // Recommandé pour empêcher l'édition directe
// Ne pas définir obscureText ici
// ...
)
Formatage du texte avec inputFormatters #
// Utilisation des formatters standard de Flutter
SecretKeyboard(
controller: keyboardController,
textController: textController,
inputFormatters: [
LengthLimitingTextInputFormatter(4), // Limite la longueur à 4 caractères
FilteringTextInputFormatter.digitsOnly, // Accepte uniquement les chiffres
],
// ...
)
// Formatter personnalisé pour empêcher le zero initial
SecretKeyboard(
controller: keyboardController,
textController: textController,
inputFormatters: [
PreventLeadingZeroFormatter(), // Formatter inclus dans la bibliothèque
],
// ...
)
// Formatter personnalisé pour un format spécifique (XX-XXXX)
class ReferenceCodeFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue
) {
// Supprime tous les caractères non numériques
String newText = newValue.text.replaceAll(RegExp(r'[^0-9]'), '');
// Limite à 6 chiffres maximum
if (newText.length > 6) {
newText = newText.substring(0, 6);
}
// Formate selon le modèle XX-XXXX
if (newText.length > 2) {
newText = '${newText.substring(0, 2)}-${newText.substring(2)}';
}
return TextEditingValue(
text: newText,
selection: TextSelection.collapsed(offset: newText.length),
);
}
}
// Utilisation des formatters personnalisés
SecretKeyboard(
controller: keyboardController,
textController: textController,
inputFormatters: [
PreventLeadingZeroFormatter(), // Empêcher le zero initial
ReferenceCodeFormatter(), // Formatter personnalisé pour le format XX-XXXX
],
// ...
)
Couleurs des indicateurs et affichage de la grille #
SecretKeyboard(
controller: _controller,
indicatorActiveColor: Colors.blue, // Couleur des indicateurs actifs
indicatorInactiveColor: Colors.grey, // Couleur des indicateurs inactifs
indicatorBackgroundColor: Colors.white, // Couleur de fond des indicateurs
showGrid: true, // Afficher la grille
showOuterBorder: true, // Afficher la bordure externe
// ...
)
Style des touches #
SecretKeyboard(
controller: _controller,
backgroundColor: Colors.grey[200], // Couleur de fond des touches
cellStyle: const TextStyle( // Style du texte des touches
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
// ...
)
Icônes personnalisées #
SecretKeyboard(
controller: _controller,
deleteButtonWidget: Image.asset('assets/icons/delete.png'), // Image personnalisée
fingerprintButtonWidget: Image.asset('assets/icons/fingerprint.png'), // Image personnalisée
// ...
)
API principale #
SecretKeyboardController #
Le contrôleur qui gère l'état du clavier.
SecretKeyboardController({
AuthenticationFunction authenticationFunction = AuthenticationFunction.transactionValidation,
bool fingerprintEnabled = false,
int maxLength = 4,
bool randomizeKeys = true, // Option pour le mélange des touches
int gridColumns = 4, // Nombre de colonnes (3 ou 4)
})
SecretKeyboard #
Le widget principal du clavier.
SecretKeyboard({
required SecretKeyboardController controller,
required Function(String) onClick,
bool showSecretCode = true,
bool showGrid = true,
bool showOuterBorder = false,
double cellAspectRatio = 1,
Function(String)? onCodeCompleted,
Function(String)? onFingerprintClick,
Function(bool)? onCanCleanMessage,
double? height,
double? width,
Color? backgroundColor,
TextStyle? cellStyle,
int codeLength = 4,
Widget? deleteButtonWidget,
Widget? fingerprintButtonWidget,
Color indicatorActiveColor = Colors.orange,
Color indicatorInactiveColor = Colors.black,
Color indicatorBackgroundColor = Colors.white,
// Paramètres pour la liaison avec TextField
TextEditingController? textController,
bool obscureText = true,
String obscuringCharacter = '•',
// Paramètre pour le formatage du texte
List<TextInputFormatter>? inputFormatters,
// Paramètre pour la configuration des colonnes
int gridColumns = 4,
// Paramètres pour les effets tactiles
KeyTouchEffect touchEffect = KeyTouchEffect.none,
Color? touchEffectColor,
Duration touchEffectDuration = const Duration(milliseconds: 150),
double touchEffectScaleValue = 0.95,
// Paramètres pour l'effet de flou
double blurIntensity = 3.0,
Duration blurDuration = const Duration(milliseconds: 300),
bool blurEnabled = true,
// Paramètre pour le thème
SecretKeyboardTheme? theme,
})
SecretKeyboardTheme #
Classe représentant un thème pour le clavier secret.
SecretKeyboardTheme({
required KeyTouchEffect touchEffect,
required Color primaryColor,
Color? secondaryColor,
required Color backgroundColor,
required Color textColor,
TextStyle? textStyle,
Duration animationDuration = const Duration(milliseconds: 150),
bool showBorders = false,
bool showOuterBorder = false,
Color? borderColor,
// Paramètres pour l'effet de flou
double blurIntensity = 3.0,
Duration blurDuration = const Duration(milliseconds: 300),
bool blurEnabled = true,
})
SecretKeyboardTextFieldBinding #
Classe utilitaire pour lier un clavier secret à un TextField.
SecretKeyboardTextFieldBinding({
required SecretKeyboardController keyboardController,
required TextEditingController textEditingController,
bool obscureText = true,
String obscuringCharacter = '•',
// Paramètre pour le formatage du texte
List<TextInputFormatter>? inputFormatters,
})
Licence #
MIT