Plate Number Input Package
A Flutter package that provides a customizable widget for collecting vehicle or motorcycle license plate numbers from users.
Examples
![]() Default usage example. |
![]() Real project implementation. |
Features
- Dynamic Spacing: Adjust spacing between widgets using the
spacingScale
parameter. - Custom Widgets: Option to add custom widgets for letters and removal actions.
- Flexible Styling: Customize text styles for numbers and letters, as well as border radius.
- Interactive Letter Selection: Callback for handling letter selection.
- Input Validation: Prevents the entry of invalid characters such as ".", "-", and " " in numeric text fields.
Installation
To use this package, add it to your pubspec.yaml
file:
dependencies:
plate_number: ^0.0.1
Then run the following command to install the package:
flutter pub get
Usage
To get started with the package, you need to create a PlateCardBloc that manages the state of the selected plate type. This bloc should be defined in your widget tree using BlocProvider. Below is an example of how to implement this in your Flutter application:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:plate_number/bicycle_plate/index.dart';
import 'package:plate_number/car_plate/index.dart';
import 'package:plate_number/widgets/show_plate.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late PlateCardBloc bloc;
late PlateType selectedType;
@override
void initState() {
bloc = PlateCardBloc(PlateType.irCar);
selectedType = bloc.plateType;
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plate Number Input Example'),
),
body: BlocProvider(
create: (BuildContext context) {
return bloc;
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocBuilder<PlateCardBloc, PlateCardState>(
builder: (BuildContext context, PlateCardState state) {
switch (state.plateType) {
case PlateType.irCar:
return const CarPlateNumber(
activeColor: Colors.pinkAccent,
inactiveColor: Colors.blueGrey,
backgroundColor: Colors.white,
spacingScale: 6,
);
case PlateType.irBicycle:
return const BicyclePlateNumber(
activeColor: Colors.blueAccent,
inactiveColor: Colors.blueGrey,
backgroundColor: Colors.white,
spacingScale: 6,
);
}
},
),
const ShowPlate(),
PlateTypeSelector(
onValueChanged: (PlateType type) {
setState(() {
selectedType = type;
});
bloc.add(TypeIsChanged(type));
},
selectedType: selectedType,
),
],
),
),
),
);
}
}
class PlateTypeSelector extends StatelessWidget {
const PlateTypeSelector({super.key, required this.onValueChanged, required this.selectedType});
final ValueChanged<PlateType> onValueChanged;
final PlateType selectedType;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CupertinoSegmentedControl<PlateType>(
padding: const EdgeInsets.symmetric(vertical: 10),
selectedColor: Colors.blueAccent,
unselectedColor: Colors.white,
children: {
for (var type in PlateType.values)
type: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: Text(
type.parseToString(),
style: const TextStyle(fontSize: 15),
),
)
},
onValueChanged: onValueChanged,
groupValue: selectedType,
),
],
);
}
}
Important Note
To use the CarPlateNumber widget, make sure to import the relevant index file:
import 'package:plate_number/car_plate/index.dart';
And for the BicyclePlateNumber widget:
import 'package:plate_number/bicycle_plate/index.dart';
Remember to create the PlateCardBloc beforehand and define the BlocProvider in the widget tree.
Contributing
Contributions are welcome! If you have suggestions or improvements, feel free to open an issue or submit a pull request.