한 번 사용하는 비밀번호 입력을 쉽게 하기 위해 사용자 정의 가능한 OTP 텍스트 필드 위젯을 제공하는 플러터 패키지입니다. 입력 필드 간의 원활한 탐색, 자동 포커스 관리 및 깔끔하고 현대적인 디자인을 지원합니다. 4~8자리 코드가 필요한 인증 흐름에 적합합니다. 이 패키지는 가볍고 잘 문서화되어 있으며, 안드로이드, iOS, 웹, macOS, 윈도우, 리눅스를 포함한 모든 주요 플랫폼과 호환됩니다.
사용 사례
OTP로 사용자 로그인
이중 인증
계정 확인
비밀번호 없는 로그인
보안 폼 입력
온보딩 흐름에서 코드 입력
주요 기능
필드 간 자동 포커스
사용자 정의 텍스트 필드 크기
4~8자리 코드 지원
크로스 플랫폼 호환성
간단한 API 통합
화면 키보드 처리
적합한 대상
인증 화면
모바일 앱 온보딩
보안 로그인 워크플로우
다중 플랫폼 앱
간단한 OTP 입력을 찾는 개발자
고려 사항
기본 스타일링을 넘어서는 사용자 정의가 제한적
내장된 검증 로직 없음
제출에 대한 수동 처리가 필요합니다
동적 코드 길이를 위한 설계가 아님
숫자가 아닌 입력을 지원하지 않습니다
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
OTP Text Field
A flutter package to create an OTP (One-Time Password) input widget in your application.
Stay tuned for the latest updates:
✨ Features
Underline or box style fields, fully customizable colors and borders
Smart focus handling — auto-advance on input, backspace jumps to the previous field
Paste & SMS autofill support — a pasted or autofilled code is distributed across the fields
Programmatic control via OtpFieldController (set, clear, focus)
The single import above exports everything (OTPTextField, OtpFieldController, OtpFieldStyle, FieldStyle). You can also import otp_field.dart, otp_field_style.dart, and style.dart individually if you prefer.
Attach an OtpFieldController to clear, prefill, or focus the fields from your own code — for example after a failed verification or a "resend code" tap:
finalOtpFieldController otpController = OtpFieldController();
OTPTextField(
controller: otpController,
length: 4,
onCompleted: (pin) => verifyOtp(pin),
),
// Later:
otpController.clear(); // clear all fields, focus the first one
otpController.set(['1', '2', '3', '4']); // prefill the whole pin
otpController.setValue('7', 2); // set a single field (position 2)
otpController.setFocus(0); // move focus to a field
The controller must be attached to a built OTPTextField before calling its methods, otherwise a StateError is thrown. set() expects exactly length entries.
SMS code autofill
Pass AutofillHints.oneTimeCode to enable one-tap SMS code autofill on iOS and Android. The autofilled code is automatically spread across the fields:
Total width of the widget. Usually set to the available screen width.
fieldWidth
double
30
Width of each individual field.
spaceBetween
double
0
Horizontal space between fields, in addition to textFieldAlignment spacing.
controller
OtpFieldController?
null
Controller to clear, prefill, or focus the fields programmatically.
fieldStyle
FieldStyle
FieldStyle.underline
Field shape: FieldStyle.underline or FieldStyle.box.
outlineBorderRadius
double
10
Corner radius of the border when fieldStyle is FieldStyle.box.
otpFieldStyle
OtpFieldStyle?
OtpFieldStyle()
Colors for background and borders — see OtpFieldStyle.
style
TextStyle
TextStyle()
Text style of the digits being entered.
contentPadding
EdgeInsets
EdgeInsets.symmetric(horizontal: 4, vertical: 8)
Content padding inside each field.
isDense
bool
false
Whether the fields use a denser, vertically compact layout.
textFieldAlignment
MainAxisAlignment
MainAxisAlignment.spaceBetween
How the fields are distributed across width.
keyboardType
TextInputType
TextInputType.number
Keyboard shown while typing.
textCapitalization
TextCapitalization
TextCapitalization.none
Capitalization behavior for alphanumeric codes.
inputFormatter
List<TextInputFormatter>?
null
Input formatters applied while typing and to pasted text.
obscureText
bool
false
Hide the entered characters (for sensitive PINs).
showCursor
bool
false
Show the cursor and selection visuals. By default the focused field is indicated only by its focused border.
hasError
bool
false
Render all fields with the error border color.
autofocus
bool
false
Focus the first field automatically when the widget is built.
enabled
bool
true
Whether the fields accept user input.
autofillHints
List<String>?
null
Autofill hints applied to the first field. Use [AutofillHints.oneTimeCode] for SMS autofill.
redirectFocusToFirstEmptyField
bool
true
When a later field gains focus while earlier ones are empty, redirect focus to the first empty field so the code is always entered contiguously. Set to false to let users type into any box.
onChanged
ValueChanged<String>?
null
Called with the current pin whenever it changes.
onCompleted
ValueChanged<String>?
null
Called with the full pin once every field is filled.
OtpFieldStyle
Parameter
Type
Default
Description
backgroundColor
Color
Colors.transparent
Fill color of each field.
borderColor
Color
Colors.black26
Default border color.
enabledBorderColor
Color
Colors.black26
Border color when the field is enabled but not focused.
focusBorderColor
Color
Colors.blue
Border color of the focused field.
disabledBorderColor
Color
Colors.grey
Border color when enabled is false.
errorBorderColor
Color
Colors.red
Border color when hasError is true.
OtpFieldController
Method
Description
clear()
Clears all fields, focuses the first one, and calls onChanged with an empty string.
set(List<String> pin)
Sets the whole pin. The list length must equal length; throws ArgumentError otherwise. Calls onChanged, and onCompleted if no entry is empty.
setValue(String value, int position)
Sets a single field at position (0-based). Calls onChanged.
setFocus(int position)
Moves focus to the field at position (0-based).
📝 Behavior notes
Focus flow: typing a digit moves focus to the next field; the keyboard is dismissed after the last one. Deleting a digit moves focus back. Pressing backspace on an already-empty field also jumps back.
Typing over a digit: focusing a filled field selects its content, so typing replaces the digit instead of appending to it.
Paste & autofill: a multi-character value (paste or SMS autofill) is filtered through your inputFormatters, distributed across the fields from the start, and any leftover fields are cleared.
RTL locales: the fields are always laid out left-to-right, since verification codes are read left-to-right.