106 lines
3.2 KiB
Dart
106 lines
3.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:hoshan/ui/theme/colors.dart';
|
|
import 'package:hoshan/ui/theme/text.dart';
|
|
|
|
class CardNumberInput extends StatefulWidget {
|
|
final Function(String) onChange;
|
|
final String initialValue; // New parameter
|
|
|
|
const CardNumberInput({
|
|
super.key,
|
|
required this.onChange,
|
|
this.initialValue = '', // Default to empty string
|
|
});
|
|
|
|
@override
|
|
State<CardNumberInput> createState() => _CardNumberInputState();
|
|
}
|
|
|
|
class _CardNumberInputState extends State<CardNumberInput> {
|
|
final List<TextEditingController> _controllers =
|
|
List.generate(4, (_) => TextEditingController());
|
|
final List<FocusNode> _focusNodes = List.generate(4, (_) => FocusNode());
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_setInitialValue(widget.initialValue); // Set initial value
|
|
}
|
|
|
|
void _setInitialValue(String value) {
|
|
// Split the initial value into segments of 4
|
|
final segments = List.generate(4, (index) {
|
|
return value.length > index * 4
|
|
? value.substring(index * 4, (index + 1) * 4).padRight(4, ' ')
|
|
: '';
|
|
});
|
|
|
|
for (int i = 0; i < _controllers.length; i++) {
|
|
_controllers[i].text = segments[i];
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
for (var controller in _controllers) {
|
|
controller.dispose();
|
|
}
|
|
for (var focusNode in _focusNodes) {
|
|
focusNode.dispose();
|
|
}
|
|
super.dispose();
|
|
}
|
|
|
|
void _onChanged(String value, int index) {
|
|
if (value.length == 4 && index < 3) {
|
|
FocusScope.of(context).requestFocus(_focusNodes[index + 1]);
|
|
} else if (value.isEmpty && index > 0) {
|
|
FocusScope.of(context).requestFocus(_focusNodes[index - 1]);
|
|
}
|
|
String result = '';
|
|
for (var controller in _controllers) {
|
|
result += controller.text;
|
|
}
|
|
widget.onChange(result);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Row(
|
|
children: List.generate(4, (index) {
|
|
return Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
child: SizedBox(
|
|
height: 38,
|
|
child: TextField(
|
|
controller: _controllers[index],
|
|
focusNode: _focusNodes[index],
|
|
maxLength: 4,
|
|
keyboardType: TextInputType.number,
|
|
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
|
textAlign: TextAlign.center,
|
|
style: AppTextStyles.body4
|
|
.copyWith(color: Theme.of(context).colorScheme.onSurface),
|
|
decoration: InputDecoration(
|
|
counterText: "",
|
|
fillColor: Theme.of(context).colorScheme.surface,
|
|
filled: true,
|
|
border: OutlineInputBorder(
|
|
borderSide: BorderSide(color: AppColors.gray[50]),
|
|
borderRadius: BorderRadius.circular(8)),
|
|
contentPadding: EdgeInsets.zero),
|
|
onChanged: (value) => _onChanged(value, index),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
}
|