otp_autofill_field 1.2.0 copy "otp_autofill_field: ^1.2.0" to clipboard
otp_autofill_field: ^1.2.0 copied to clipboard

Self-contained Flutter OTP field: PIN UI with automatic Android SMS Retriever and iOS one-time-code keyboard autofill, plus a resend timer. No external OTP/PIN dependency.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:otp_autofill_field/otp_autofill_field.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'otp_autofill_field demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      home: const OtpPage(),
    );
  }
}

class OtpPage extends StatefulWidget {
  const OtpPage({super.key});

  @override
  State<OtpPage> createState() => _OtpPageState();
}

class _OtpPageState extends State<OtpPage> {
  // 1) Controller — lets us read/clear the code and flag errors from
  //    outside the widget. We created it, so we dispose it.
  final _otp = AutoOtpController();

  // The "correct" code in this demo. A real app verifies on the server.
  static const _expected = '123456';
  String _status = 'Waiting for the 6-digit code…';

  @override
  void dispose() {
    _otp.dispose();
    super.dispose();
  }

  // 2) Fired once when 6 digits are present (typed OR auto-filled).
  void _verify(String code) {
    if (code == _expected) {
      setState(() => _status = '✅ Verified: $code');
    } else {
      // Wrong → shake + clear. Because reArmOnClear is true (default), the
      // SMS retriever re-arms automatically, so a *resent* OTP autofills.
      _otp.triggerError();
      _otp.clearCode();
      setState(() => _status = '❌ Wrong code — try again');
    }
  }

  Future<void> _resend() async {
    // Call your backend to send a new OTP here.
    setState(() => _status = '🔄 New code requested');
  }

  Future<void> _showSignature() async {
    final sig = await AutoOtp.getAppSignature(); // null off Android
    if (!mounted) return;
    setState(() => _status = 'App signature: ${sig ?? "n/a (not Android)"}');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('otp_autofill_field')),
      body: Center(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Text('Enter the 6-digit code',
                  style: TextStyle(fontSize: 18)),
              const SizedBox(height: 24),

              // 3) The field. Auto-fills from Android SMS / iOS keyboard.
              AutoOtpField(
                length: 6,
                controller: _otp,
                haptic: OtpHaptic.selection, // tap feedback per digit
                theme: const AutoOtpTheme(
                  shape: AutoOtpShape.box,
                  borderRadius: 12,
                  focusedBorderColor: Colors.indigo,
                  cellAnimation: OtpCellAnimation.scale,
                ),
                // Group as 3 — 3 with a wider gap in the middle.
                separatorBuilder: (_, i) => SizedBox(width: i == 3 ? 18 : 6),
                onChanged: (code) => debugPrint('onChanged: $code'),
                onAutoFill: (code) => debugPrint('onAutoFill: $code'),
                onCompleted: _verify,
                onTimeout: () =>
                    setState(() => _status = '⌛ SMS wait timed out'),
              ),

              const SizedBox(height: 16),

              // 4) Resend cooldown — 1 minute by default, then a button.
              OtpResendTimer(
                duration: const Duration(minutes: 1),
                onResend: _resend, // timer auto-restarts afterwards
              ),

              const SizedBox(height: 20),
              Text(_status, textAlign: TextAlign.center),
              const SizedBox(height: 24),

              Wrap(
                spacing: 12,
                alignment: WrapAlignment.center,
                children: [
                  OutlinedButton(
                    onPressed: () => _otp.clearCode(),
                    child: const Text('Clear'),
                  ),
                  OutlinedButton(
                    onPressed: () => _otp.triggerError(),
                    child: const Text('Show error'),
                  ),
                  FilledButton(
                    onPressed: _showSignature,
                    child: const Text('App signature'),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}
0
likes
160
points
293
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Self-contained Flutter OTP field: PIN UI with automatic Android SMS Retriever and iOS one-time-code keyboard autofill, plus a resend timer. No external OTP/PIN dependency.

Repository (GitHub)
View/report issues

Topics

#otp #sms #autofill #pin #authentication

License

MIT (license)

Dependencies

flutter, flutter_web_plugins

More

Packages that depend on otp_autofill_field

Packages that implement otp_autofill_field