输入框inputFilter对初始值不生效问题分析报告
1 关键字 TextInput; inputFilter; 初始值 2 问题描述 2.1 运行环境 系统版本:3.2Release开发板:rk3568 2.2 问题现象: TextInput组件设置inputFilter(通过正则表达式设置输入过滤器。匹配表达式的输入将允许显示,不匹配的输入将被过滤。)但是对于TextInput组件的初始值,这个规则未生效。 ... TextInput({text
1 关键字
TextInput; inputFilter; 初始值
2 问题描述
2.1 运行环境
系统版本:3.2Release
开发板:rk3568
2.2 问题现象:
TextInput组件设置inputFilter(通过正则表达式设置输入过滤器。匹配表达式的输入将允许显示,不匹配的输入将被过滤。)但是对于TextInput组件的初始值,这个规则未生效。
...
TextInput({text:"12789"}) //预期显示12,实际显示12789
.inputFilter('[1-5]')
...
3 问题原因
3.1 正常机制
TextInput组件设定初始值,以及其后接受字符输入时,检验值是否符合inputFilter所限定的规则
3.2 异常机制
TextInput组件设定初始值时,未检验值是否符合inputFilter所限定的规则
4 解决方案
修改文件 foundation\arkui\ace_engine\frameworks\core\components_ng\pattern\text_field\text_field_pattern.cpp 的 TextFieldModelNG::SetInputFilter 方法:
void TextFieldModelNG::SetInputFilter(const std::string& value, const std::function<void(const std::string&)>& onError)
{
ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, InputFilter, value);
auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub<TextFieldEventHub>();
CHECK_NULL_VOID(eventHub);
eventHub->SetOnInputFilterError(onError);
+auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
+auto pattern = frameNode->GetPattern<TextFieldPattern>();
+pattern->InitEditingValueTextWithFilter();
}
TextFieldPattern.InitEditingValueTextWithFilter定义:
void TextFieldPattern::InitEditingValueTextWithFilter()
{
auto content = textEditingValue_.text;
ClearEditingValue();
InsertValue(content);
auto layoutProperty = GetLayoutProperty<TextFieldLayoutProperty>();
layoutProperty->UpdateNeedFireOnChangeWhenCreate(true);
}
5 定位过程
在输入框接受到用户输入时,执行方法TextFieldPattern::InsertValue(foundation\arkui\ace_engine\frameworks\core\components_ng\pattern\text_field\text_field_pattern.cpp)
这个方法内处理一些校验例如检测maxLength,inputFilter的逻辑,最后设置输入框显示在UI界面上值。
检测maxLength:
auto originLength = static_cast<uint32_t>(textEditingValue_.GetWideText().length());
if (originLength >= GetMaxLength()) {
LOGW("Max length reached");
return;
}
检测宽字符maxLength
auto wideInsertValue = StringUtils::ToWstring(insertValue);
if (originLength + wideInsertValue.length() >= GetMaxLength()) {
valueToUpdate = StringUtils::ToString(wideInsertValue.substr(0, GetMaxLength() - originLength));
} else {
valueToUpdate = insertValue;
}
检测将被输入的字符是否符合inputFilter规则
EditingValueFilter(valueToUpdate, result);
...
void TextFieldPattern::EditingValueFilter(std::string& valueToUpdate, std::string& result)
{
//获取用户设置的inputFilter属性
auto inputFilter = textFieldLayoutProperty->GetInputFilterValue("");
bool textChanged = false;
//进行正则匹配
if (!inputFilter.empty()) {
textChanged |= FilterWithRegex(inputFilter, valueToUpdate, result);
}
...
}
应用ets代码:
TextInput({text:"12789"}) //预期显示12,实际显示12789,
.inputFilter('[1-5]')
最终会编译为以下:
TextInput.create({text:"12789"})
TextInput.inputFilter('[1-5]')
inputFilter在napi层方法入口逻辑在JSTextField::SetInputFilter,因此,在用户设置inputFilter属性时,在对应方法(TextFieldModelNG::SetInputFilter)里针对初始值也做此检测处理。
6 知识分享
inputFilter通过正则表达式设置输入过滤器。匹配表达式的输入允许显示,不匹配的输入将被过滤。仅支持单个字符匹配,不支持字符串匹配。参数支持Object类型,可设置属性值:
- value:设置正则表达式。
- error(可选):正则匹配失败时,返回被过滤的内容。
更多推荐
所有评论(0)