1 关键字

TextInput; maxLength

2 问题描述

2.1 运行环境

系统版本:3.2Beta4
开发板:rk3568

2.2 问题现象:

TextInput组件设置maxLength属性(此属性规定输入字段允许的最大长度),但TextInput输入框仍然能输入超过maxLength值长度的字符。

3 问题原因

3.1 正常机制

maxLength属性规定输入字段允许的最大长度,设置了maxLength属性的TextInput无法输入超过maxLength值长度的字符。

3.2 异常机制

设置了maxLength属性的TextInput能输入超过maxLength值长度的字符。

4 解决方案

修改OnTextChangedListenerImpl::InsertText 方法(文件路径:\foundation\arkui\ace_engine\frameworks\core\components\text_field\on_text_changed_listener_impl.cpp):
在 auto value = client->GetEditingValue(); 语句下添加以下代码:

if (value.GetWideText().length() >= client->GetMaxLength()) {
  LOGW("maxLenth exceeded,don't insert text");
  return;
}

5 定位过程

用户触发输入后的一些关键逻辑调用链按顺序如下【方法(文件路径)】:

  1. JsTextInputClientEngine::InsertText(base\inputmethod\imf\interfaces\kits\js\napi\inputmethodability\js_text_input_client_engine.cpp)

  2. InputMethodAbility::InsertText(const std::string text)(base\inputmethod\imf\frameworks\inputmethod_ability\src\input_method_ability.cpp)

  3. InputDataChannelStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,...)

  4. InputDataChannelStub::InsertText(const std::u16string& text)

  5. textListener->InsertText(text) (InputMethodController::WorkThread()) (base\inputmethod\imf\frameworks\inputmethod_controller\src\input_method_controller.cpp)

复现问题的环境为3.2Beta4,ArkUI未使用ng框架 ,textListener->InsertText(text)对应于的Arkui逻辑(TextInput输入框用户操作与UI的交互逻辑(输入/删除))代码位于文件\foundation\arkui\ace_engine\frameworks\core\components\text_field\on_text_changed_listener_impl.cpp内,在输入框接受到用户输入时,执行方法:OnTextChangedListenerImpl::InsertText

void OnTextChangedListenerImpl::InsertText(const std::u16string& text)
{
    ...
    //输入文字为空时
    if (text.length() <= 0) {
        LOGE("the text is null");
        return;
    }

    auto task = [textField = field_, text] {
        //获取输入框实例
        auto client = textField.Upgrade();
        if (!client) {
            LOGE("text field is null");
            return;
        }
        ContainerScope scope(client->instanceId_);
        //取得当前输入框内已存在的值
        auto value = client->GetEditingValue();
        auto textEditingValue = std::make_shared<TextEditingValue>();
        //计算输入框在输入后即将显示的新值
        textEditingValue->text =
            value.GetBeforeSelection() + StringUtils::Str16ToStr8(text) + value.GetAfterSelection();
        textEditingValue->UpdateSelection(std::max(value.selection.GetStart(), 0) + text.length());

        //更新输入框的值
        client->UpdateInsertText(StringUtils::Str16ToStr8(text));
        client->UpdateEditingValue(textEditingValue, true);
    };
    //执行更新UI任务
    PostTaskToUI(task);
}

通过以上执行逻辑,可以看出textInput在接受到用户输入时,在更新输入框的值之前,并没有判断输入框的maxLength值与已经存在的值的长度做比较,实际上,在maxLength值大于或等于已经存在的值的长度时,不应再更新输入框的值。

6 知识分享

maxLength属性可以指定或确定可在文本框中输入的最大字符数,该属性的默认值是无限数量。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐