하지만 위의 방법을 적용해도 다음과 같은 결과가 일어난다.
위와 같이 설정 글자수 초과시 UI에 표현만 되고 글자수는 제한 되지 않는다.
이를 해결하기 위한 방법으로 두 가지가 있다(내가 발견한)
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/services.dart';
import 'dart:math';
import 'dart:convert';
class Utf8LengthLimitingTextInputFormatter extends TextInputFormatter {
Utf8LengthLimitingTextInputFormatter(this.maxLength)
: assert(maxLength == null || maxLength == -1 || maxLength > 0);
final int maxLength;
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
if (maxLength != null &&
maxLength > 0 &&
bytesLength(newValue.text) > maxLength) {
// If already at the maximum and tried to enter even more, keep the old value.
if (bytesLength(oldValue.text) == maxLength) {
return oldValue;
}
return truncate(newValue, maxLength);
}
return newValue;
}
static TextEditingValue truncate(TextEditingValue value, int maxLength) {
var newValue = '';
if (bytesLength(value.text) > maxLength) {
var length = 0;
value.text.characters.takeWhile((char) {
var nbBytes = bytesLength(char);
if (length + nbBytes <= maxLength) {
newValue += char;
length += nbBytes;
return true;
}
return false;
});
}
return TextEditingValue(
text: newValue,
selection: value.selection.copyWith(
baseOffset: min(value.selection.start, newValue.length),
extentOffset: min(value.selection.end, newValue.length),
),
composing: TextRange.empty,
);
}
static int bytesLength(String value) {
return utf8.encode(value).length;
}
}
코드 출처 - https://dev.to/stack-labs/flutter-utf8-textfield-length-limiter-and-char-counter-31o7
위의 코드 작성후 적용하고자 하는 TextField에 다음과 같이 사용하면 된다!
TextField(
controller : TextEditingController(),
inputFormatters: [Utf8LengthLimitingTextInputFormatter(5)],
)
-> 5 대신 본인이 제한하고자 하는 길이만큼 써주면 된다.
TextFormField(
focusNode: _focusNode,
textAlign: TextAlign.center,
onChanged: (nextText){
setState(() {
if(_searchController.text.trim() != ""){
isSelected = true;
}else{
isSelected = false;
}
_searchController.text = nextText.substring(0,maxLength);
_searchController.selection = TextSelection.fromPosition(TextPosition(offset: maxLength));
});
},
inputFormatters: [
LengthLimitingTextInputFormatter(maxLength)
],
),