A TextField Widget to Help Display Different Style Pin

PinInputTextField is a TextField widget to help display different style pin. It supports all the platforms flutter supports.

Feature 🌟

  • allow you customized the shape, any!
  • built-in 4 commonly used pin styles of shape
  • obscure support
  • solid support
  • enterColor support
  • cursor support
  • support all the textField properties theoretically
  • Flutter all platform support

Example 🦀

Thanks to the Flutter Web, you can enjoy the preview by website without any installation.

Decoration

UnderlineDecoration

BoxLooseDecoration

BoxTightDecoration

CircleDecoration

Installing 🔧

Install the latest version from pub.

Usage ✍️

Attributes

Customizable attributes for PinInputTextField

Attribute NameExample ValueDescription
pinLength6The max length of pin, the default is 6
onSubmit(String pin){}The callback will execute when user click done, sometimes is not working in Android.
decorationBoxLooseDecorationDecorate the pin, there are 3 inside styles, the default is BoxLooseDecoration
inputFormattersWhitelistingTextInputFormatter.digitsOnlyJust like TextField's inputFormatter, the default is WhitelistingTextInputFormatter.digitsOnly
keyboardTypeTextInputType.phoneJust like TextField's keyboardType, the default is TextInputType.phone
pinEditingControllerPinEditingControllerControls the pin being edited. If null, this widget will create its own PinEditingController
autoFocusfalseSame as TextField's autoFocus, the default is false
focusNodeFocusNodeSame as TextField's focusNode
textInputActionTextInputAction.doneSame as TextField's textInputAction, not working in digit mode
enabledtrueSame as TextField's enabled, the default is true
onChanged(String pin){}Same as TextField's onChanged
textCapitalizationTextCapitalization.wordsSame as TextField's textCapitalization
cursorCursor.disabled()The cursor of the pin, default is not enabled

FormField

Instead of using PinInputTextField, using PinInputTextFormField to control validate.

ObscureStyle

/// Determine whether replace [obscureText] with number.
final bool isTextObscure;
/// The display text when [isTextObscure] is true, emoji supported
final String obscureText;

Notice ⚠️

Version 3.2.0

Cursor property would override HintText due to the conflict display in same paint position.

If you have any idea, please make a Pull Request.

Known Issue 🥶

The PinEditingController listener will execute more than once when programmatically set text, you can filter some duplicate values in your code.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add pin_input_text_field

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  pin_input_text_field: ^4.1.1

Alternatively, your editor might support or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:pin_input_text_field/pin_input_text_field.dart'; 

example/lib/main.dart

import 'dart:ui';

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

void main() => runApp(MyApp());

const _kInputHeight = 64.0;
const _kDefaultHint = 'abcd';

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pin Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ListPage(),
    );
  }
}

enum TextFieldType {
  NORMAL,
  FORM,
}

class ListPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('demo'),
      ),
      body: ListView.builder(
        itemCount: TextFieldType.values.length,
        itemBuilder: (ctx, index) {
          return ListTile(
            title: Text(TextFieldType.values[index].toString()),
            onTap: () {
              Navigator.push(
                  ctx,
                  MaterialPageRoute(
                      builder: (context) =>
                          MyHomePage(TextFieldType.values[index])));
            },
          );
        },
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage(this.textFieldType, {Key key}) : super(key: key);

  final TextFieldType textFieldType;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// Default max pin length.
  static final int _pinLength = 4;

  /// PinInputTextFormField form-key
  final GlobalKey<FormFieldState<String>> _formKey =
      GlobalKey<FormFieldState<String>>(debugLabel: '_formkey');

  /// Control the input text field.
  TextEditingController _pinEditingController =
      TextEditingController(text: '123');

  GlobalKey<ScaffoldState> _globalKey =
      GlobalKey<ScaffoldState>(debugLabel: 'home page global key');

  /// Decorate the outside of the Pin.
  PinDecoration _pinDecoration;

  /// Control whether show the obscureCode.
  bool _obscureEnable = false;

  PinEntryType _pinEntryType = PinEntryType.underline;
  ColorBuilder _solidColor =
      PinListenColorBuilder(Colors.grey, Colors.grey[400]);
  bool _solidEnable = false;

  /// Control whether textField is enable.
  bool _enable = true;

  /// Indicate whether the PinInputTextFormField has error or not
  /// after being validated.
  bool _hasError = false;

  bool _cursorEnable = true;

  /// Set a pin to the textField.
  void _setPinValue() {
    _pinEditingController
      ..text = "0000"
      ..selection = TextSelection.collapsed(offset: 4);
  }

  @override
  void initState() {
    _pinEditingController.addListener(() {
      debugPrint('controller execute. pin:${_pinEditingController.text}');
    });
    super.initState();
    _selectedMenu(PinEntryType.underline);
  }

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

  void _selectedMenu(PinEntryType type) {
    _pinEntryType = type;
    switch (type) {
      case PinEntryType.underline:
        setState(() {
          _pinDecoration = UnderlineDecoration(
            colorBuilder: PinListenColorBuilder(Colors.cyan, Colors.green),
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '😂',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.boxTight:
        setState(() {
          _pinDecoration = BoxTightDecoration(
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '👿',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.boxLoose:
        setState(() {
          _pinDecoration = BoxLooseDecoration(
            strokeColorBuilder:
                PinListenColorBuilder(Colors.cyan, Colors.green),
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '☺️',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.circle:
        setState(() {
          _pinDecoration = CirclePinDecoration(
            bgColorBuilder: _solidEnable ? _solidColor : null,
            strokeColorBuilder:
                PinListenColorBuilder(Colors.cyan, Colors.green),
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '🤪',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.customized:
        setState(() {
          _pinDecoration = ExampleDecoration();
        });
        break;
    }
  }

  _buildExampleBody() {
    switch (widget.textFieldType) {
      case TextFieldType.NORMAL:
        return _buildPinInputTextFieldExample();
      case TextFieldType.FORM:
        return _buildPinInputTextFormFieldExample();
    }
  }

  _buildConfigWidget() {
    return [
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'obscureEnabled',
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          SizedBox(
            width: 12,
          ),
          Checkbox(
              value: _obscureEnable,
              onChanged: (enable) {
                setState(() {
                  _obscureEnable = enable;
                  _selectedMenu(_pinEntryType);
                });
              }),
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'solidEnabled',
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          SizedBox(
            width: 12,
          ),
          Checkbox(
              value: _solidEnable,
              onChanged: (enable) {
                setState(() {
                  _solidEnable = enable;
                  _selectedMenu(_pinEntryType);
                });
              }),
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'enabled',
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(width: 12),
          Checkbox(
            value: _enable,
            onChanged: (enable) {
              setState(() {
                _enable = enable;
              });
            },
          )
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'cursor enabled',
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(width: 12),
          Checkbox(
            value: _cursorEnable,
            onChanged: (enable) {
              setState(() {
                _cursorEnable = enable;
              });
            },
          )
        ],
      ),
    ];
  }

  Widget _buildPinInputTextFieldExample() {
    return Center(
      // Center is a layout widget. It takes a single child and positions it
      // in the middle of the parent.
      child: ListView(
        children: <Widget>[
          ..._buildConfigWidget(),
          SizedBox(
            height: _kInputHeight,
            child: PinInputTextField(
              pinLength: _pinLength,
              decoration: _pinDecoration,
              controller: _pinEditingController,
              textInputAction: TextInputAction.go,
              enabled: _enable,
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.characters,
              onSubmit: (pin) {
                debugPrint('submit pin:$pin');
              },
              onChanged: (pin) {
                debugPrint('onChanged execute. pin:$pin');
              },
              enableInteractiveSelection: false,
              cursor: Cursor(
                width: 2,
                color: Colors.lightBlue,
                radius: Radius.circular(1),
                enabled: _cursorEnable,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildPinInputTextFormFieldExample() {
    return Center(
      // Center is a layout widget. It takes a single child and positions it
      // in the middle of the parent.
      child: ListView(
        children: <Widget>[
          ..._buildConfigWidget(),
          SizedBox(
            height: _kInputHeight,
            child: PinInputTextFormField(
              key: _formKey,
              pinLength: _pinLength,
              decoration: _pinDecoration,
              controller: _pinEditingController,
              textInputAction: TextInputAction.go,
              enabled: _enable,
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.characters,
              onSubmit: (pin) {
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();
                }
              },
              onChanged: (pin) {
                debugPrint('onChanged execute. pin:$pin');
              },
              onSaved: (pin) {
                debugPrint('onSaved pin:$pin');
              },
              validator: (pin) {
                if (pin.isEmpty) {
                  setState(() {
                    _hasError = true;
                  });
                  return 'Pin cannot empty.';
                }
                if (pin.length < _pinLength) {
                  setState(() {
                    _hasError = true;
                  });
                  return 'Pin is not completed.';
                }
                setState(() {
                  _hasError = false;
                });
                return null;
              },
              cursor: Cursor(
                width: 2,
                color: Colors.lightBlue,
                radius: Radius.circular(1),
                enabled: _cursorEnable,
              ),
            ),
          ),
          SizedBox(
            height: 16,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                  }
                },
                child: Text(
                  'Submit',
                  style: TextStyle(
                    color: Colors.white,
                  ),
                ),
                style: ElevatedButton.styleFrom(
                  elevation: 2,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5),
                  ),
                  primary: _hasError ? Colors.red : Colors.green,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _globalKey,
      appBar: AppBar(
        title: Text(widget.textFieldType.toString()),
        actions: <Widget>[
          PopupMenuButton<PinEntryType>(
            icon: Icon(Icons.more_vert),
            onSelected: _selectedMenu,
            itemBuilder: (context) {
              return [
                PopupMenuItem(
                  child: Text('underline decoration'),
                  value: PinEntryType.underline,
                ),
                PopupMenuItem(
                  child: Text('box loose decoration'),
                  value: PinEntryType.boxLoose,
                ),
                PopupMenuItem(
                  child: Text('box tight decoration'),
                  value: PinEntryType.boxTight,
                ),
                PopupMenuItem(
                  child: Text('circle decoration'),
                  value: PinEntryType.circle,
                ),
                PopupMenuItem(
                  child: Text('Customize decorarion'),
                  value: PinEntryType.customized,
                )
              ];
            },
          ),
        ],
      ),
      body: _buildExampleBody(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.refresh),
        tooltip: 'set new value',
        onPressed: () {
          _setPinValue();
        },
      ),
    );
  }
}

class ExampleDecoration extends PinDecoration {
  ExampleDecoration({
    TextStyle textStyle,
    ObscureStyle obscureStyle,
    String errorText,
    TextStyle errorTextStyle,
    String hintText,
    TextStyle hintTextStyle,
    ColorBuilder bgColorBuilder,
  }) : super(
          textStyle: textStyle,
          obscureStyle: obscureStyle,
          errorText: errorText,
          errorTextStyle: errorTextStyle,
          hintText: hintText,
          hintTextStyle: hintTextStyle,
        );

  @override
  PinDecoration copyWith({
    TextStyle textStyle,
    ObscureStyle obscureStyle,
    String errorText,
    TextStyle errorTextStyle,
    String hintText,
    TextStyle hintTextStyle,
    ColorBuilder bgColorBuilder,
  }) {
    return ExampleDecoration(
        textStyle: textStyle ?? this.textStyle,
        obscureStyle: obscureStyle ?? this.obscureStyle,
        errorText: errorText ?? this.errorText,
        errorTextStyle: errorTextStyle ?? this.errorTextStyle,
        hintText: hintText ?? this.hintText,
        hintTextStyle: hintTextStyle ?? this.hintTextStyle,
        bgColorBuilder: bgColorBuilder);
  }

  @override
  void notifyChange(String pin) {}

  @override
  void drawPin(
    Canvas canvas,
    Size size,
    String text,
    int pinLength,
    Cursor cursor,
  ) {
    /// You can draw anything you want here.
    canvas.drawLine(
      Offset.zero,
      Offset(size.width, size.height),
      Paint()
        ..color = Colors.red
        ..strokeWidth = 10
        ..style = PaintingStyle.stroke
        ..isAntiAlias = true,
    );
  }

  @override
  PinEntryType get pinEntryType => PinEntryType.customized;
} 

Download Details:

Author: TinoGuo

Source Code: https://github.com/TinoGuo/pin_input_text_field

#text #flutter  

What is GEEK

Buddha Community

A TextField Widget to Help Display Different Style Pin

A TextField Widget to Help Display Different Style Pin

Flutter pin input

PinInputTextField is a TextField widget to help display different style pin. It supports all the platforms flutter supports.

Feature 🌟

  • allow you customized the shape, any!
  • built-in 4 commonly used pin styles of shape
  • obscure support
  • solid support
  • enterColor support
  • cursor support
  • support all the textField properties theoretically
  • Flutter all platform support

Example 🦀

Thanks to the Flutter Web, you can enjoy the preview by website without any installation.

Installing 🔧

Install the latest version from pub.

Usage ✍️

Attributes

Customizable attributes for PinInputTextField

Attribute NameExample ValueDescription
pinLength6The max length of pin, the default is 6
onSubmit(String pin){}The callback will execute when user click done, sometimes is not working in Android.
decorationBoxLooseDecorationDecorate the pin, there are 3 inside styles, the default is BoxLooseDecoration
inputFormattersWhitelistingTextInputFormatter.digitsOnlyJust like TextField's inputFormatter, the default is WhitelistingTextInputFormatter.digitsOnly
keyboardTypeTextInputType.phoneJust like TextField's keyboardType, the default is TextInputType.phone
pinEditingControllerPinEditingControllerControls the pin being edited. If null, this widget will create its own PinEditingController
autoFocusfalseSame as TextField's autoFocus, the default is false
focusNodeFocusNodeSame as TextField's focusNode
textInputActionTextInputAction.doneSame as TextField's textInputAction, not working in digit mode
enabledtrueSame as TextField's enabled, the default is true
onChanged(String pin){}Same as TextField's onChanged
textCapitalizationTextCapitalization.wordsSame as TextField's textCapitalization
cursorCursor.disabled()The cursor of the pin, default is not enabled

FormField

Instead of using PinInputTextField, using PinInputTextFormField to control validate.

ObscureStyle

/// Determine whether replace [obscureText] with number.
final bool isTextObscure;
/// The display text when [isTextObscure] is true, emoji supported
final String obscureText;

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_pin_input

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  flutter_pin_input: ^1.1.0

Alternatively, your editor might support or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_pin_input/flutter_pin_input.dart'; 

example/lib/main.dart

import 'dart:ui';

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

void main() => runApp(MyApp());

const _kInputHeight = 64.0;
const _kDefaultHint = 'abcd';

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pin Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ListPage(),
    );
  }
}

enum TextFieldType {
  NORMAL,
  FORM,
}

class ListPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('demo'),
      ),
      body: ListView.builder(
        itemCount: TextFieldType.values.length,
        itemBuilder: (ctx, index) {
          return ListTile(
            title: Text(TextFieldType.values[index].toString()),
            onTap: () {
              Navigator.push(
                  ctx,
                  MaterialPageRoute(
                      builder: (context) =>
                          MyHomePage(TextFieldType.values[index])));
            },
          );
        },
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage(this.textFieldType, {Key key}) : super(key: key);

  final TextFieldType textFieldType;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// Default max pin length.
  static final int _pinLength = 4;

  /// PinInputTextFormField form-key
  final GlobalKey<FormFieldState<String>> _formKey =
      GlobalKey<FormFieldState<String>>(debugLabel: '_formkey');

  /// Control the input text field.
  TextEditingController _pinEditingController =
      TextEditingController(text: '123');

  GlobalKey<ScaffoldState> _globalKey =
      GlobalKey<ScaffoldState>(debugLabel: 'home page global key');

  /// Decorate the outside of the Pin.
  PinDecoration _pinDecoration;

  /// Control whether show the obscureCode.
  bool _obscureEnable = false;

  PinEntryType _pinEntryType = PinEntryType.underline;
  ColorBuilder _solidColor =
      PinListenColorBuilder(Colors.grey, Colors.grey[400]);
  bool _solidEnable = false;

  /// Control whether textField is enable.
  bool _enable = true;

  /// Indicate whether the PinInputTextFormField has error or not
  /// after being validated.
  bool _hasError = false;

  bool _cursorEnable = true;

  /// Set a pin to the textField.
  void _setPinValue() {
    _pinEditingController
      ..text = "0000"
      ..selection = TextSelection.collapsed(offset: 4);
  }

  @override
  void initState() {
    _pinEditingController.addListener(() {
      debugPrint('controller execute. pin:${_pinEditingController.text}');
    });
    super.initState();
    _selectedMenu(PinEntryType.underline);
  }

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

  void _selectedMenu(PinEntryType type) {
    _pinEntryType = type;
    switch (type) {
      case PinEntryType.underline:
        setState(() {
          _pinDecoration = UnderlineDecoration(
            colorBuilder: PinListenColorBuilder(Colors.cyan, Colors.green),
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '😂',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.boxTight:
        setState(() {
          _pinDecoration = BoxTightDecoration(
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '👿',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.boxLoose:
        setState(() {
          _pinDecoration = BoxLooseDecoration(
            strokeColorBuilder:
                PinListenColorBuilder(Colors.cyan, Colors.green),
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '☺️',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.circle:
        setState(() {
          _pinDecoration = CirclePinDecoration(
            bgColorBuilder: _solidEnable ? _solidColor : null,
            strokeColorBuilder:
                PinListenColorBuilder(Colors.cyan, Colors.green),
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '🤪',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.customized:
        setState(() {
          _pinDecoration = ExampleDecoration();
        });
        break;
    }
  }

  _buildExampleBody() {
    switch (widget.textFieldType) {
      case TextFieldType.NORMAL:
        return _buildPinInputTextFieldExample();
      case TextFieldType.FORM:
        return _buildPinInputTextFormFieldExample();
    }
  }

  _buildConfigWidget() {
    return [
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'obscureEnabled',
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          SizedBox(
            width: 12,
          ),
          Checkbox(
              value: _obscureEnable,
              onChanged: (enable) {
                setState(() {
                  _obscureEnable = enable;
                  _selectedMenu(_pinEntryType);
                });
              }),
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'solidEnabled',
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          SizedBox(
            width: 12,
          ),
          Checkbox(
              value: _solidEnable,
              onChanged: (enable) {
                setState(() {
                  _solidEnable = enable;
                  _selectedMenu(_pinEntryType);
                });
              }),
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'enabled',
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(width: 12),
          Checkbox(
            value: _enable,
            onChanged: (enable) {
              setState(() {
                _enable = enable;
              });
            },
          )
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'cursor enabled',
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(width: 12),
          Checkbox(
            value: _cursorEnable,
            onChanged: (enable) {
              setState(() {
                _cursorEnable = enable;
              });
            },
          )
        ],
      ),
    ];
  }

  Widget _buildPinInputTextFieldExample() {
    return Center(
      // Center is a layout widget. It takes a single child and positions it
      // in the middle of the parent.
      child: ListView(
        children: <Widget>[
          ..._buildConfigWidget(),
          SizedBox(
            height: _kInputHeight,
            child: PinInputTextField(
              pinLength: _pinLength,
              decoration: _pinDecoration,
              controller: _pinEditingController,
              textInputAction: TextInputAction.go,
              enabled: _enable,
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.characters,
              onSubmit: (pin) {
                debugPrint('submit pin:$pin');
              },
              onChanged: (pin) {
                debugPrint('onChanged execute. pin:$pin');
              },
              enableInteractiveSelection: false,
              cursor: Cursor(
                width: 2,
                color: Colors.lightBlue,
                radius: Radius.circular(1),
                enabled: _cursorEnable,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildPinInputTextFormFieldExample() {
    return Center(
      // Center is a layout widget. It takes a single child and positions it
      // in the middle of the parent.
      child: ListView(
        children: <Widget>[
          ..._buildConfigWidget(),
          SizedBox(
            height: _kInputHeight,
            child: PinInputTextFormField(
              key: _formKey,
              pinLength: _pinLength,
              decoration: _pinDecoration,
              controller: _pinEditingController,
              textInputAction: TextInputAction.go,
              enabled: _enable,
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.characters,
              onSubmit: (pin) {
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();
                }
              },
              onChanged: (pin) {
                debugPrint('onChanged execute. pin:$pin');
              },
              onSaved: (pin) {
                debugPrint('onSaved pin:$pin');
              },
              validator: (pin) {
                if (pin.isEmpty) {
                  setState(() {
                    _hasError = true;
                  });
                  return 'Pin cannot empty.';
                }
                if (pin.length < _pinLength) {
                  setState(() {
                    _hasError = true;
                  });
                  return 'Pin is not completed.';
                }
                setState(() {
                  _hasError = false;
                });
                return null;
              },
              cursor: Cursor(
                width: 2,
                color: Colors.lightBlue,
                radius: Radius.circular(1),
                enabled: _cursorEnable,
              ),
            ),
          ),
          SizedBox(
            height: 16,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                  }
                },
                child: Text(
                  'Submit',
                  style: TextStyle(
                    color: Colors.white,
                  ),
                ),
                style: ElevatedButton.styleFrom(
                  elevation: 2,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5),
                  ),
                  primary: _hasError ? Colors.red : Colors.green,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _globalKey,
      appBar: AppBar(
        title: Text(widget.textFieldType.toString()),
        actions: <Widget>[
          PopupMenuButton<PinEntryType>(
            icon: Icon(Icons.more_vert),
            onSelected: _selectedMenu,
            itemBuilder: (context) {
              return [
                PopupMenuItem(
                  child: Text('underline decoration'),
                  value: PinEntryType.underline,
                ),
                PopupMenuItem(
                  child: Text('box loose decoration'),
                  value: PinEntryType.boxLoose,
                ),
                PopupMenuItem(
                  child: Text('box tight decoration'),
                  value: PinEntryType.boxTight,
                ),
                PopupMenuItem(
                  child: Text('circle decoration'),
                  value: PinEntryType.circle,
                ),
                PopupMenuItem(
                  child: Text('Customize decorarion'),
                  value: PinEntryType.customized,
                )
              ];
            },
          ),
        ],
      ),
      body: _buildExampleBody(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.refresh),
        tooltip: 'set new value',
        onPressed: () {
          _setPinValue();
        },
      ),
    );
  }
}

class ExampleDecoration extends PinDecoration {
  ExampleDecoration({
    TextStyle textStyle,
    ObscureStyle obscureStyle,
    String errorText,
    TextStyle errorTextStyle,
    String hintText,
    TextStyle hintTextStyle,
    ColorBuilder bgColorBuilder,
  }) : super(
          textStyle: textStyle,
          obscureStyle: obscureStyle,
          errorText: errorText,
          errorTextStyle: errorTextStyle,
          hintText: hintText,
          hintTextStyle: hintTextStyle,
        );

  @override
  PinDecoration copyWith({
    TextStyle textStyle,
    ObscureStyle obscureStyle,
    String errorText,
    TextStyle errorTextStyle,
    String hintText,
    TextStyle hintTextStyle,
    ColorBuilder bgColorBuilder,
  }) {
    return ExampleDecoration(
        textStyle: textStyle ?? this.textStyle,
        obscureStyle: obscureStyle ?? this.obscureStyle,
        errorText: errorText ?? this.errorText,
        errorTextStyle: errorTextStyle ?? this.errorTextStyle,
        hintText: hintText ?? this.hintText,
        hintTextStyle: hintTextStyle ?? this.hintTextStyle,
        bgColorBuilder: bgColorBuilder);
  }

  @override
  void notifyChange(String pin) {}

  @override
  void drawPin(
    Canvas canvas,
    Size size,
    String text,
    int pinLength,
    Cursor cursor,
  ) {
    /// You can draw anything you want here.
    canvas.drawLine(
      Offset.zero,
      Offset(size.width, size.height),
      Paint()
        ..color = Colors.red
        ..strokeWidth = 10
        ..style = PaintingStyle.stroke
        ..isAntiAlias = true,
    );
  }

  @override
  PinEntryType get pinEntryType => PinEntryType.customized;
}

Download Details:

Author: devasx666

Source Code: https://github.com/devasx666/flutter-pin-input

#flutter #textfield 

Max Willor

Max Willor

1596170547

Is My Assignment Help Legit?

Yes, the assignment help is quite legitimate. If you are struggling to complete the assignment then you can take the support of My Assignment Help Sydney. We are discussing certain features that will help to get good grades in the assignment.

• Timely delivery- My assignment help will help to submit the assignment on time. The writers will ensure that orders are completed before deadline. They also proofread the content and look for errors before the final submission.

• 24 by 7 help- The experts work 24 by 7 according to the convenience. Also, the experts are available round the clock. You can contact assignment writing services or assignment help Sydney through email, phone and live chat.

• Experienced professionals- Creativity, knowledge and experience are three attributes that must be considered while hiring the writer. All the professionals from my assignment help Sydney are master and PHD from reputed universities.

• Original content- You will get the original and genuine content from the experts. You will get plag free work and experts will do proofreading and editing of content. They use trustworthy plagiarism detection software. The experts follow strict policies against duplicate content. The experts provide personalized assignments of all types.

• Services of subjects- The experts provide the assignment writing services of all subjects.

• Original content report on demand- The assignment is checked through the reliable software. Also, the experts can share the report if requested.

• High-quality work- The experts do the high-quality work. They look for errors and take the reference from reliable content.

• Unlimited revisions- The experts will do unlimited revisions. We understand that eve after the final submission the professor can ask for adding or deleting some content. So, you can take the support of my assignment help.

• Best guarantee of price- you will get the personalized services at the best price. Assignment help Sydney assure you to provide best quote in market.

So, my assignment help is a reliable and legitimate service. You can take the support of Assignment Help Sydney. They have a team of experts that will help to write the original content. The proofreaders proofread the content and look for errors. They look for spelling, vocabulary and sentence formation errors.

Hence, you can take the support of assignment help. You have to subscribe at the website. The experts will get in touch with you. So, you can take the help of assignment help services.

Are you seeking online assignment help? Are you not able to select the best professionals?
myassignmenthelpau is one of the renowned online assignment help service providers in the world. Your assignments will be written by those experts who have thorough knowledge of the subject. Our company serve the needs of all the students who need assignment help. The term assignment means everything from simple essays to complicated dissertations. One of the reasons why this is the best assignment writing service you could have at your side is because we cover everything you require.

• A+ quality assignments
• 50+ subjects assignment
• On-time delivery
• 100% confidential
• 3000+ experts

#assignment help #my assignment help #buy assignment online #online assignment help #online assignment help #assignment help melbourne

A TextField Widget to Help Display Different Style Pin

PinInputTextField is a TextField widget to help display different style pin. It supports all the platforms flutter supports.

Feature 🌟

  • allow you customized the shape, any!
  • built-in 4 commonly used pin styles of shape
  • obscure support
  • solid support
  • enterColor support
  • cursor support
  • support all the textField properties theoretically
  • Flutter all platform support

Example 🦀

Thanks to the Flutter Web, you can enjoy the preview by website without any installation.

Decoration

UnderlineDecoration

BoxLooseDecoration

BoxTightDecoration

CircleDecoration

Installing 🔧

Install the latest version from pub.

Usage ✍️

Attributes

Customizable attributes for PinInputTextField

Attribute NameExample ValueDescription
pinLength6The max length of pin, the default is 6
onSubmit(String pin){}The callback will execute when user click done, sometimes is not working in Android.
decorationBoxLooseDecorationDecorate the pin, there are 3 inside styles, the default is BoxLooseDecoration
inputFormattersWhitelistingTextInputFormatter.digitsOnlyJust like TextField's inputFormatter, the default is WhitelistingTextInputFormatter.digitsOnly
keyboardTypeTextInputType.phoneJust like TextField's keyboardType, the default is TextInputType.phone
pinEditingControllerPinEditingControllerControls the pin being edited. If null, this widget will create its own PinEditingController
autoFocusfalseSame as TextField's autoFocus, the default is false
focusNodeFocusNodeSame as TextField's focusNode
textInputActionTextInputAction.doneSame as TextField's textInputAction, not working in digit mode
enabledtrueSame as TextField's enabled, the default is true
onChanged(String pin){}Same as TextField's onChanged
textCapitalizationTextCapitalization.wordsSame as TextField's textCapitalization
cursorCursor.disabled()The cursor of the pin, default is not enabled

FormField

Instead of using PinInputTextField, using PinInputTextFormField to control validate.

ObscureStyle

/// Determine whether replace [obscureText] with number.
final bool isTextObscure;
/// The display text when [isTextObscure] is true, emoji supported
final String obscureText;

Notice ⚠️

Version 3.2.0

Cursor property would override HintText due to the conflict display in same paint position.

If you have any idea, please make a Pull Request.

Known Issue 🥶

The PinEditingController listener will execute more than once when programmatically set text, you can filter some duplicate values in your code.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add pin_input_text_field

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  pin_input_text_field: ^4.1.1

Alternatively, your editor might support or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:pin_input_text_field/pin_input_text_field.dart'; 

example/lib/main.dart

import 'dart:ui';

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

void main() => runApp(MyApp());

const _kInputHeight = 64.0;
const _kDefaultHint = 'abcd';

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pin Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ListPage(),
    );
  }
}

enum TextFieldType {
  NORMAL,
  FORM,
}

class ListPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('demo'),
      ),
      body: ListView.builder(
        itemCount: TextFieldType.values.length,
        itemBuilder: (ctx, index) {
          return ListTile(
            title: Text(TextFieldType.values[index].toString()),
            onTap: () {
              Navigator.push(
                  ctx,
                  MaterialPageRoute(
                      builder: (context) =>
                          MyHomePage(TextFieldType.values[index])));
            },
          );
        },
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage(this.textFieldType, {Key key}) : super(key: key);

  final TextFieldType textFieldType;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// Default max pin length.
  static final int _pinLength = 4;

  /// PinInputTextFormField form-key
  final GlobalKey<FormFieldState<String>> _formKey =
      GlobalKey<FormFieldState<String>>(debugLabel: '_formkey');

  /// Control the input text field.
  TextEditingController _pinEditingController =
      TextEditingController(text: '123');

  GlobalKey<ScaffoldState> _globalKey =
      GlobalKey<ScaffoldState>(debugLabel: 'home page global key');

  /// Decorate the outside of the Pin.
  PinDecoration _pinDecoration;

  /// Control whether show the obscureCode.
  bool _obscureEnable = false;

  PinEntryType _pinEntryType = PinEntryType.underline;
  ColorBuilder _solidColor =
      PinListenColorBuilder(Colors.grey, Colors.grey[400]);
  bool _solidEnable = false;

  /// Control whether textField is enable.
  bool _enable = true;

  /// Indicate whether the PinInputTextFormField has error or not
  /// after being validated.
  bool _hasError = false;

  bool _cursorEnable = true;

  /// Set a pin to the textField.
  void _setPinValue() {
    _pinEditingController
      ..text = "0000"
      ..selection = TextSelection.collapsed(offset: 4);
  }

  @override
  void initState() {
    _pinEditingController.addListener(() {
      debugPrint('controller execute. pin:${_pinEditingController.text}');
    });
    super.initState();
    _selectedMenu(PinEntryType.underline);
  }

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

  void _selectedMenu(PinEntryType type) {
    _pinEntryType = type;
    switch (type) {
      case PinEntryType.underline:
        setState(() {
          _pinDecoration = UnderlineDecoration(
            colorBuilder: PinListenColorBuilder(Colors.cyan, Colors.green),
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '😂',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.boxTight:
        setState(() {
          _pinDecoration = BoxTightDecoration(
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '👿',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.boxLoose:
        setState(() {
          _pinDecoration = BoxLooseDecoration(
            strokeColorBuilder:
                PinListenColorBuilder(Colors.cyan, Colors.green),
            bgColorBuilder: _solidEnable ? _solidColor : null,
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '☺️',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.circle:
        setState(() {
          _pinDecoration = CirclePinDecoration(
            bgColorBuilder: _solidEnable ? _solidColor : null,
            strokeColorBuilder:
                PinListenColorBuilder(Colors.cyan, Colors.green),
            obscureStyle: ObscureStyle(
              isTextObscure: _obscureEnable,
              obscureText: '🤪',
            ),
            hintText: _kDefaultHint,
          );
        });
        break;
      case PinEntryType.customized:
        setState(() {
          _pinDecoration = ExampleDecoration();
        });
        break;
    }
  }

  _buildExampleBody() {
    switch (widget.textFieldType) {
      case TextFieldType.NORMAL:
        return _buildPinInputTextFieldExample();
      case TextFieldType.FORM:
        return _buildPinInputTextFormFieldExample();
    }
  }

  _buildConfigWidget() {
    return [
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'obscureEnabled',
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          SizedBox(
            width: 12,
          ),
          Checkbox(
              value: _obscureEnable,
              onChanged: (enable) {
                setState(() {
                  _obscureEnable = enable;
                  _selectedMenu(_pinEntryType);
                });
              }),
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'solidEnabled',
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          SizedBox(
            width: 12,
          ),
          Checkbox(
              value: _solidEnable,
              onChanged: (enable) {
                setState(() {
                  _solidEnable = enable;
                  _selectedMenu(_pinEntryType);
                });
              }),
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'enabled',
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(width: 12),
          Checkbox(
            value: _enable,
            onChanged: (enable) {
              setState(() {
                _enable = enable;
              });
            },
          )
        ],
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'cursor enabled',
            style: TextStyle(fontSize: 18),
          ),
          SizedBox(width: 12),
          Checkbox(
            value: _cursorEnable,
            onChanged: (enable) {
              setState(() {
                _cursorEnable = enable;
              });
            },
          )
        ],
      ),
    ];
  }

  Widget _buildPinInputTextFieldExample() {
    return Center(
      // Center is a layout widget. It takes a single child and positions it
      // in the middle of the parent.
      child: ListView(
        children: <Widget>[
          ..._buildConfigWidget(),
          SizedBox(
            height: _kInputHeight,
            child: PinInputTextField(
              pinLength: _pinLength,
              decoration: _pinDecoration,
              controller: _pinEditingController,
              textInputAction: TextInputAction.go,
              enabled: _enable,
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.characters,
              onSubmit: (pin) {
                debugPrint('submit pin:$pin');
              },
              onChanged: (pin) {
                debugPrint('onChanged execute. pin:$pin');
              },
              enableInteractiveSelection: false,
              cursor: Cursor(
                width: 2,
                color: Colors.lightBlue,
                radius: Radius.circular(1),
                enabled: _cursorEnable,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildPinInputTextFormFieldExample() {
    return Center(
      // Center is a layout widget. It takes a single child and positions it
      // in the middle of the parent.
      child: ListView(
        children: <Widget>[
          ..._buildConfigWidget(),
          SizedBox(
            height: _kInputHeight,
            child: PinInputTextFormField(
              key: _formKey,
              pinLength: _pinLength,
              decoration: _pinDecoration,
              controller: _pinEditingController,
              textInputAction: TextInputAction.go,
              enabled: _enable,
              keyboardType: TextInputType.text,
              textCapitalization: TextCapitalization.characters,
              onSubmit: (pin) {
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();
                }
              },
              onChanged: (pin) {
                debugPrint('onChanged execute. pin:$pin');
              },
              onSaved: (pin) {
                debugPrint('onSaved pin:$pin');
              },
              validator: (pin) {
                if (pin.isEmpty) {
                  setState(() {
                    _hasError = true;
                  });
                  return 'Pin cannot empty.';
                }
                if (pin.length < _pinLength) {
                  setState(() {
                    _hasError = true;
                  });
                  return 'Pin is not completed.';
                }
                setState(() {
                  _hasError = false;
                });
                return null;
              },
              cursor: Cursor(
                width: 2,
                color: Colors.lightBlue,
                radius: Radius.circular(1),
                enabled: _cursorEnable,
              ),
            ),
          ),
          SizedBox(
            height: 16,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                  }
                },
                child: Text(
                  'Submit',
                  style: TextStyle(
                    color: Colors.white,
                  ),
                ),
                style: ElevatedButton.styleFrom(
                  elevation: 2,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5),
                  ),
                  primary: _hasError ? Colors.red : Colors.green,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _globalKey,
      appBar: AppBar(
        title: Text(widget.textFieldType.toString()),
        actions: <Widget>[
          PopupMenuButton<PinEntryType>(
            icon: Icon(Icons.more_vert),
            onSelected: _selectedMenu,
            itemBuilder: (context) {
              return [
                PopupMenuItem(
                  child: Text('underline decoration'),
                  value: PinEntryType.underline,
                ),
                PopupMenuItem(
                  child: Text('box loose decoration'),
                  value: PinEntryType.boxLoose,
                ),
                PopupMenuItem(
                  child: Text('box tight decoration'),
                  value: PinEntryType.boxTight,
                ),
                PopupMenuItem(
                  child: Text('circle decoration'),
                  value: PinEntryType.circle,
                ),
                PopupMenuItem(
                  child: Text('Customize decorarion'),
                  value: PinEntryType.customized,
                )
              ];
            },
          ),
        ],
      ),
      body: _buildExampleBody(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.refresh),
        tooltip: 'set new value',
        onPressed: () {
          _setPinValue();
        },
      ),
    );
  }
}

class ExampleDecoration extends PinDecoration {
  ExampleDecoration({
    TextStyle textStyle,
    ObscureStyle obscureStyle,
    String errorText,
    TextStyle errorTextStyle,
    String hintText,
    TextStyle hintTextStyle,
    ColorBuilder bgColorBuilder,
  }) : super(
          textStyle: textStyle,
          obscureStyle: obscureStyle,
          errorText: errorText,
          errorTextStyle: errorTextStyle,
          hintText: hintText,
          hintTextStyle: hintTextStyle,
        );

  @override
  PinDecoration copyWith({
    TextStyle textStyle,
    ObscureStyle obscureStyle,
    String errorText,
    TextStyle errorTextStyle,
    String hintText,
    TextStyle hintTextStyle,
    ColorBuilder bgColorBuilder,
  }) {
    return ExampleDecoration(
        textStyle: textStyle ?? this.textStyle,
        obscureStyle: obscureStyle ?? this.obscureStyle,
        errorText: errorText ?? this.errorText,
        errorTextStyle: errorTextStyle ?? this.errorTextStyle,
        hintText: hintText ?? this.hintText,
        hintTextStyle: hintTextStyle ?? this.hintTextStyle,
        bgColorBuilder: bgColorBuilder);
  }

  @override
  void notifyChange(String pin) {}

  @override
  void drawPin(
    Canvas canvas,
    Size size,
    String text,
    int pinLength,
    Cursor cursor,
  ) {
    /// You can draw anything you want here.
    canvas.drawLine(
      Offset.zero,
      Offset(size.width, size.height),
      Paint()
        ..color = Colors.red
        ..strokeWidth = 10
        ..style = PaintingStyle.stroke
        ..isAntiAlias = true,
    );
  }

  @override
  PinEntryType get pinEntryType => PinEntryType.customized;
} 

Download Details:

Author: TinoGuo

Source Code: https://github.com/TinoGuo/pin_input_text_field

#text #flutter  

Ellis Herbert

Ellis Herbert

1588908840

A textField Widget to help Display Different Style Pin

pin_input_text_field

PinInputTextField is a TextField widget to help display different style pin. It supports all the platforms flutter supports.

Feature

  • allow you customized the shape, any!
  • built-in 4 commonly used pin styles of shape
  • obscure support
  • solid support
  • enterColor support
  • support all the textField properties support
  • Flutter web support

Example

Thanks to the Flutter Web, you can enjoy the preview by website without any installation.

Decoration

UnderlineDecoration

BoxLooseDecoration

BoxTightDecoration

CircleDecoration

Installing

Install the latest version from pub.

Usage

FormField

Instead of using PinInputTextField, using PinInputTextFormField to control validate.

ObscureStyle

/// Determine whether replace [obscureText] with number.
final bool isTextObscure;
/// The display text when [isTextObscure] is true, emoji supported
final String obscureText;

Contributors

This project exists thanks to all the people who contribute.

rajajain08

alyyasser

daniel-v

Notice after Version 2.0.0

Please set the selection when you set the text programmatically, just like this.

Don’t set the selection in lib code since if it will cause dead loop in iOS.

If you have any idea, please make a Pull Request.

Known Issue

The PinEditingController listener will execute more than once when programmatically set text, you can filter some duplicate values in your code.

Download Details:

Author: TinoGuo

GitHub: https://github.com/TinoGuo/pin_input_text_field

#flutter #dart #programming

Max Willor

Max Willor

1595933099

How To Identify The Right Finance Assignment Help Service – Know The 5 Tips!

Are you looking for the Finance Assignment Help service? If yes, then don’t worry because we are here to help you out in that. When you will look out in search of finance writing help service, you will find plethora of options available over online and offline platform. If you want to identify the right assignment help service, stay tuned with the mentioned details right below. Here the top 5 tips are mentioned for the identification.

Know what finance assignment help is:

Finance assignments are like the nightmares for the students. Making a finance assignment requires lots of research, analysis, observation, playing with numbers, and much more. The most important thing to know about finance assignment is that, it should be present in perfect manner. Hiring the finance assignment help service is perfect to make an appropriate assignment.

Calculate the experience of finance assignment help service

When you are going to hire the assignment help service, you must calculate the experience of the assignment writing service. Experience means perfection. If the company is well experienced, that means the company had dealt with different types of finance assignment also. So the more company is experienced, the better they will make the assignment.

What about recommendations?

If you want to hire the finance assignment help service, make sure to know what the rrcommendations are. Ask from your friends, classmates and even from the seniors to take recommendations for the right service. Obviously, you are not the one, who is thinking to hire the assignment help service. Your fellows will tell you about different writing companies, from where you can take help for your assignment.

What about cost of the assignment?

One should also consider the cost of the assignment help service. Different companies asks for different costs for making the assignments, so better is to select the one, who is better at making the assignment, plus ask for affordable price also. If you will research in a proper manner, then you will definitely find the one, who will charge affordable amount from you for making the finance assignment.
What is the delivery status?

One should ask for the delivery time of the assignment by the expert writers. Check out the status of delivery of the assignment helps service, so that you can find the reliable one.

Hope that now you will find the suitable finance and marketing Assignment Help service to get the best assignment done with perfection.

If you need online assignment Help, then we are the right place for you. When you look for assignment help services online, you will find a good reputation of us in the market. Have a look at the testimonials and reviews given our users, you’ll find that they are using our services repeatedly. We deliver excellent quality on any subject and that also before deadlines. Some of the benefits we offer are listed below:

• Affordable prices
• Attractive discounts
• Timely submissions
• Quick response

#finance assignment help #finance assignment help online #business finance assignment help #mba finance assignment help #assignment help