2022. 9. 28. 20:02
Flutter TextField에서 숫자 입력 시 천 단위 마다 구분자(콤마) 표시되도록 하는 기능 구현하기 개발/Flutter2022. 9. 28. 20:02
반응형
최근 Flutter TextField에서 숫자 입력 시 천 단위 마다 콤마를 표시되도록 해야하는 일이 생겼는데
이게 생각보다 간단하지 않았다.
일단 숫자 입력만 되도록 제한하고 천 단위 마다 콤마 표시하는 것 자체는 크게 어렵지 않았는데,
콤마를 표시하면 그것도 자리 차지를 하게 되어 중간에서 입력/삭제 후 자연스러운 커서 위치를 잡기가 어려웠지만
규칙을 찾아 수식을 작성해서 해결했다.
완성된 코드는 다음과 같다.
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ThousandCommaTextField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffffffff),
body: SafeArea(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
keyboardType: TextInputType.number,
textAlign: TextAlign.right,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
FilteringTextInputFormatter.digitsOnly,
ThousandCommaInputFormatter()
],
)
],
)
)
),
);
}
}
String thousandComma(dynamic val, {String defaultVal = ""}) {
NumberFormat numberFormat = NumberFormat('#,###', "ko_KR");
if (val != null && val != "") {
if (val is int || val is double) {
return numberFormat.format(val);
} else if (double.tryParse(val) != null) {
return numberFormat.format(double.parse(val));
} else if (int.tryParse(val) != null) {
return numberFormat.format(int.parse(val));
}
}
return defaultVal;
}
class ThousandCommaInputFormatter extends TextInputFormatter {
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
String oldNum = oldValue.text.replaceAll(",", "");
String newNum = newValue.text.replaceAll(",", "");
String newText = thousandComma(newValue.text, defaultVal: "0");
// 다음 커서 위치 잡기
int selectionIndex = ((newValue.text.length -1) / 3).floor() // 전체 ,(comma)의 수
- (((newValue.text.length - newValue.selection.end)-1) / 3).floor() //현재 커서 위치를 기준으로 오른쪽에 있는 ,(comma)의 수
+ newValue.selection.end;
if (selectionIndex > newText.length) {
selectionIndex = newText.length;
}
if (oldNum == newNum) {//,(comma) 뒤에 커서놓고 삭제 시
//1,234,567에서 4,뒤(커서 위치 6)에서 삭제하면 123,567이 되므로 1뒤의 ,와 4가 같이 없어져서 커서 위치가 2만큼 왼쪽으로 이동해야 한다. (최종 커서 위치 4가 되야함)
//98,765에서 8,뒤(커서 위치 3)에서 삭제하면 9,765가 되므로 8만 없어져서 커서 위치가 1만큼 왼쪽으로 이동해야 한다. (최종 커서 위치 2가 되야함)
selectionIndex = selectionIndex - (newText.replaceAll(",", "").length % 3 == 1 ? 2 : 1);
newText = newValue.text.substring(0, newValue.selection.end - 1) + newValue.text.substring(newValue.selection.end);
newText = thousandComma(newText, defaultVal: "0");
}
return newValue.copyWith(
text: newText,
selection: TextSelection.collapsed(
offset: selectionIndex));
}
}
참고 출처:
https://stackoverflow.com/questions/49577781/how-to-create-number-input-field-in-flutter
반응형
'개발 > Flutter' 카테고리의 다른 글
Flutter 특정 영역에서 이미지 크기/위치 조절하기 (0) | 2023.05.17 |
---|---|
javascript/flutter(dart)에서 Byte 단위 값을 알맞는 용량 형식(KB/MB...)으로 변환하기 (0) | 2022.08.23 |
Flutter에서 Flick 화면 만들기 (0) | 2022.08.03 |
Flutter에서 TextField의 "붙여넣기" 도구 설명 이름을 한국어로 변경하는 방법 (0) | 2022.01.27 |
Flutter에서 new_version으로 업데이트 체크 시 Bad state: No element 오류 해결 (Android) (0) | 2021.12.27 |