Flutter密码输入插件pin_code_text_field的使用
Flutter密码输入插件pin_code_text_field的使用
pin_code_text_field
是一个美观且高度可定制的Flutter小部件,用于输入PIN码。它适用于登录和一次性密码(OTP)等场景。
使用方法
作为库使用该包
-
依赖于它
在
pubspec.yaml
文件中添加:dependencies: pin_code_text_field: <VERSION>
-
安装它
您可以通过命令行安装软件包:
$ flutter packages get
或者,您的编辑器可能支持
flutter packages get
。请查阅编辑器文档以了解更多。 -
导入它
现在可以在Dart代码中使用:
import 'package:pin_code_text_field/pin_code_text_field.dart';
API
以下是 PinCodeTextField
的一些主要参数:
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
isCupertino | bool | false | 应用程序是否包装在 CupertinoApp 而不是 MaterialApp 中 |
maxLength | int | 4 | PIN码的总长度和PIN框的数量 |
hideCharacter | bool | false | 显示或隐藏PIN码 |
highlight | bool | false | 高亮聚焦的PIN框 |
highlightAnimation | bool | false | 动画高亮聚焦的PIN框 |
highlightAnimationBeginColor | Color | Colors.black | 动画高亮的起始颜色 |
highlightAnimationEndColor | Color | Colors.white | 动画高亮的结束颜色 |
highlightAnimationDuration | Duration | 500ms | 高亮动画的持续时间 |
highlightColor | Color | Colors.black | 设置聚焦PIN框的颜色 |
pinBoxDecoration | BoxDecoration | ProvidedPinBoxDecoration.defaultPinBoxDecoration | 自定义单个PIN框。检查 ProvidedPinBoxDecoration 获取可用选项 |
pinTextStyle | TextStyle | PIN字符的文本样式 | |
maskCharacter | String | “\u25CF” | 遮罩PIN码的特殊字符。仅当 hideCharacter 设置为 true 时有效 |
pinBoxHeight | double | 70.0 | PIN框的高度 |
pinBoxWidth | double | 70.0 | PIN框的宽度 |
onDone | void Function(String) | 当达到PIN码的最大长度时的回调 | |
hasTextBorderColor | Color | Colors.black | 设置包含文本的PIN框的颜色 |
pinTextAnimatedSwitcherTransition | Function(Widget child, Animation<…>) | 文本出现/消失的动画。可以编写自己的动画或使用预设:PinCodeTextField.awesomeTransition 、PinCodeTextField.defaultScalingTransition 、PinCodeTextField.defaultRotateTransition |
|
pinTextAnimatedSwitcherDuration | Duration | const Duration() | pinTextAnimatedSwitcherTransition 的持续时间。检查 ProvidedPinBoxTextAnimation 获取可用选项 |
errorBorderColor | Color | Colors.red | 如果 hasError 设置为 true ,则将所有文本框高亮为此颜色 |
onTextChange | Function(String) | 输入文本变化时的回调 | |
hasError | bool | false | 将所有边框颜色设置为 errorBorderColor |
autofocus | bool | false | 视图进入时自动获取焦点 |
wrapAlignment | WrapAlignment | WrapAlignment.start | 包裹PIN框的对齐方式 |
textDirection | TextDirection | TextDirection.ltr | PIN码的方向 |
keyboardType | TextInputType | TextInputType.number | 输入键盘类型 |
pinBoxColor | Color | null | PIN框的颜色(会被自定义的 PinBoxDecoration 覆盖) |
pinBoxBorderWidth | double | 2 | PIN框的边框宽度 |
pinBoxRadius | double | 0 | PIN框的圆角半径 |
hideDefaultKeyboard | boolean | false | 是否隐藏默认键盘 |
highlightPinBoxColor | Color | false | PIN框的背景颜色 |
hasUnderline | bool | false | 为单个PIN框添加下划线 |
示例
下面是一个完整的示例demo,展示了如何使用 PinCodeTextField
:
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pin_code_text_field/pin_code_text_field.dart';
void main() => runApp(new SampleApp());
class SampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainApp(),
);
}
}
class MainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Pin Code TextField Example")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
MaterialButton(
child: Text("Open Pin Code Input"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyApp(isMaterial: true)),
);
},
),
],
),
),
);
}
}
class MyApp extends StatefulWidget {
final bool isMaterial;
const MyApp({Key? key, required this.isMaterial}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController controller = TextEditingController(text: "");
String thisText = "";
int pinLength = 4;
bool hasError = false;
String errorMessage = "";
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.isMaterial
? materialPin()
: cupertinoPin();
}
Scaffold materialPin() {
return Scaffold(
appBar: AppBar(
title: Text("Material Pin Code Text Field Example"),
),
body: Container(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 60.0),
child: Text(thisText, style: Theme.of(context).textTheme.titleMedium),
),
Container(
height: 100.0,
child: GestureDetector(
onLongPress: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text("Paste clipboard stuff into the pinbox?"),
actions: [
TextButton(
onPressed: () async {
var copiedText = await Clipboard.getData("text/plain");
if (copiedText?.text.isNotEmpty == true) {
controller.text = copiedText.text;
}
Navigator.of(context).pop();
},
child: Text("YES"),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("No"),
)
],
);
},
);
},
child: PinCodeTextField(
autofocus: true,
controller: controller,
hideCharacter: true,
highlight: true,
highlightColor: Colors.blue,
defaultBorderColor: Colors.black,
hasTextBorderColor: Colors.green,
highlightPinBoxColor: Colors.orange,
maxLength: pinLength,
hasError: hasError,
maskCharacter: "😎",
onTextChanged: (text) {
setState(() {
hasError = false;
});
},
onDone: (text) {
print("DONE $text");
print("DONE CONTROLLER ${controller.text}");
},
pinBoxWidth: 50,
pinBoxHeight: 64,
hasUnderline: true,
wrapAlignment: WrapAlignment.spaceAround,
pinBoxDecoration: ProvidedPinBoxDecoration.defaultPinBoxDecoration,
pinTextStyle: TextStyle(fontSize: 22.0),
pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition,
pinTextAnimatedSwitcherDuration: Duration(milliseconds: 300),
highlightAnimationBeginColor: Colors.black,
highlightAnimationEndColor: Colors.white12,
keyboardType: TextInputType.number,
),
),
),
Visibility(
child: Text(
"Wrong PIN!",
),
visible: hasError,
),
Padding(
padding: const EdgeInsets.only(top: 32.0),
child: Wrap(
alignment: WrapAlignment.spaceEvenly,
children: [
MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: Text("+"),
onPressed: () {
setState(() {
this.pinLength++;
});
},
),
MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: Text("-"),
onPressed: () {
setState(() {
this.pinLength--;
});
},
),
MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: Text("SUBMIT"),
onPressed: () {
setState(() {
this.thisText = controller.text;
});
},
),
MaterialButton(
color: Colors.red,
textColor: Colors.white,
child: Text("SUBMIT Error"),
onPressed: () {
setState(() {
this.hasError = true;
});
},
),
MaterialButton(
color: Colors.pink,
textColor: Colors.white,
child: Text("CLEAR PIN"),
onPressed: () {
controller.clear();
},
),
MaterialButton(
color: Colors.lime,
textColor: Colors.black,
child: Text("SET TO 456"),
onPressed: () {
controller.text = "456";
},
),
],
),
)
],
),
),
),
);
}
CupertinoPageScaffold cupertinoPin() {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text("Cupertino Pin Code Text Field Example"),
),
child: SafeArea(
child: Container(
child: SingleChildScrollView(
child: Container(
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 60.0),
child: Text(thisText),
),
PinCodeTextField(
autofocus: false,
controller: controller,
hideCharacter: true,
highlight: true,
highlightColor: CupertinoColors.activeBlue,
defaultBorderColor: CupertinoColors.black,
hasTextBorderColor: CupertinoColors.activeGreen,
maxLength: pinLength,
hasError: hasError,
maskCharacter: "🐶",
onTextChanged: (text) {
setState(() {
hasError = false;
thisText = text;
});
},
isCupertino: true,
onDone: (text) {
print("DONE $text");
},
wrapAlignment: WrapAlignment.end,
pinBoxDecoration: ProvidedPinBoxDecoration.roundedPinBoxDecoration,
pinTextStyle: TextStyle(fontSize: 30.0),
pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition,
pinTextAnimatedSwitcherDuration: Duration(milliseconds: 300),
highlightAnimation: true,
highlightAnimationBeginColor: Colors.black,
highlightAnimationEndColor: Colors.white12,
),
Visibility(
child: Text(
"Wrong PIN!",
style: TextStyle(color: CupertinoColors.destructiveRed),
),
visible: hasError,
),
Padding(
padding: const EdgeInsets.only(top: 32.0),
child: Wrap(
alignment: WrapAlignment.spaceEvenly,
children: [
CupertinoButton(
child: Text("+"),
onPressed: () {
setState(() {
this.pinLength++;
});
},
),
CupertinoButton(
child: Text("-"),
onPressed: () {
setState(() {
this.pinLength--;
});
},
),
CupertinoButton(
child: Text("SUBMIT"),
onPressed: () {
setState(() {
this.thisText = controller.text;
});
},
),
CupertinoButton(
child: Text("SUBMIT Error"),
onPressed: () {
setState(() {
this.hasError = true;
});
},
)
],
),
)
],
),
),
),
),
),
);
}
}
这个示例展示了如何创建一个带有PIN码输入框的应用程序,并提供了Material和Cupertino两种风格的界面选择。您可以根据需要调整和扩展此示例。
更多关于Flutter密码输入插件pin_code_text_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter密码输入插件pin_code_text_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用pin_code_text_field
插件的示例代码。这个插件通常用于输入PIN码或密码,提供了一些便利的功能,比如自动聚焦下一个输入框、隐藏和显示密码等。
首先,确保在你的pubspec.yaml
文件中添加pin_code_text_field
依赖:
dependencies:
flutter:
sdk: flutter
pin_code_text_field: ^2.0.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
接下来,是一个简单的示例代码,展示如何使用PinCodeTextField
:
import 'package:flutter/material.dart';
import 'package:pin_code_text_field/pin_code_text_field.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Pin Code TextField Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PinCodeScreen(),
);
}
}
class PinCodeScreen extends StatefulWidget {
@override
_PinCodeScreenState createState() => _PinCodeScreenState();
}
class _PinCodeScreenState extends State<PinCodeScreen> {
final _controller = TextEditingController();
final _focusNode = FocusNode();
@override
void dispose() {
_controller.dispose();
_focusNode.dispose();
super.dispose();
}
void _onSubmit(String pin) {
// 在这里处理提交的PIN码
print('Submitted PIN: $pin');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Pin Code Input Demo'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: PinCodeTextField(
controller: _controller,
length: 6, // PIN码长度
obscureText: false, // 是否隐藏文本
animationType: AnimationType.fade,
width: 50.0,
height: 60.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
borderActiveColor: Colors.blue,
onCompleted: _onSubmit,
onChanged: (value) {
// 实时处理PIN码输入变化
print('Current PIN: $value');
},
pinTheme: PinTheme(
shape: PinCodeFieldShape.box,
borderRadius: BorderRadius.circular(8),
fieldSize: 50.0,
activeColor: Colors.blue,
inactiveColor: Colors.grey[300]!,
inactiveFillColor: Colors.white,
selectedColor: Colors.blueAccent,
disabledColor: Colors.grey[400]!,
animationDuration: Duration(milliseconds: 300),
),
keyboardType: TextInputType.number,
textStyle: TextStyle(
fontSize: 20.0,
),
animationDuration: Duration(milliseconds: 300),
),
),
),
);
}
}
在这个示例中,我们创建了一个包含PinCodeTextField
的简单Flutter应用。以下是关键点的总结:
PinCodeTextField
: 用于输入PIN码的主要组件。controller
:TextEditingController
用于控制文本字段。length
: 定义PIN码的长度。obscureText
: 是否隐藏输入的文本。onCompleted
: 当用户完成输入时触发的回调。onChanged
: 当用户输入变化时触发的回调。pinTheme
: 用于自定义PIN码输入框的外观。
你可以根据需要调整这些参数来满足你的具体需求。