当前位置: 首页 > 知识库问答 >
问题:

EditText缓存旧文本

仉联
2023-03-14

我有以下问题。我有EditText和TextWatcher,它们根据一些规则格式化输入文本。在TextChanged()之后的方法中,我格式化它。然后我有格式化的字符串,我想用格式化的值替换EditText的旧值。接下来我们有两个选项:

    < li >使用EditText.setText() < li >使用Editable.replace()

如果我们使用第一个选项,EditText的工作速度非常慢,并且会丢失符号。但是如果我们使用第二种方法,可编辑不会替换旧文本,而是将新文本附加到旧文本上。

也许有人有类似的问题?

更新:使用可编辑.clear() 然后可编辑.追加() 或插入() 具有类似的效果

代码

    public static class LoginWatcher implements TextWatcher {

    private EditText target;
    private LoginFilter loginFilter = new LoginFilter();

    private int lastLength;
    private boolean wasPhoneNumber = false;

    private AsYouTypeFormatter formatter;
    private boolean isFormattingStopped;

    public LoginWatcher(OnLoginEnterListener onLoginInputListener, EditText target) {
        listener = onLoginInputListener;
        this.target = target;
        lastLength = target.getText().length();
        formatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(Locale.getDefault().getCountry());
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        if (isFormattingStopped) {
            return;
        }

        if (count > 0 && hasSeparator(s, start, count)) {
            stopFormatting();
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
        target.removeTextChangedListener(this);

        boolean isSymbolsChecked = loginFilter.check(s.toString());
        boolean isEmail = StringUtils.isEmailValid(s.toString());
        boolean isPhoneNumber = isPhoneNumber(s.toString());



        if (lastLength <= s.length()) {
            if (isPhoneNumber && !isFormattingStopped) {
                String formatted = reformat(s, Selection.getSelectionEnd(s));
                if (formatted != null) {
                    target.setText(formatted);
                    target.setSelection(target.getText().length());
                }

            } else if (wasPhoneNumber) {
                String unformatted = unFormatPhoneNumber(s.toString());

                target.setText(unformatted); // or s.clear(); s.append(); 
                target.setSelection(target.getText().length());
            }
        }

        lastLength = s.length();
        wasPhoneNumber = isPhoneNumber;

        if (isFormattingStopped) {
            isFormattingStopped = s.length() != 0;
        }

        target.addTextChangedListener(this);
    }

    private String unFormatPhoneNumber(String s) {

        char[] chars = s.toCharArray();

        if (s.isEmpty()) {
            return s;
        }

        if (chars[0] == '+') {
            boolean isPhoneNumber = true;
            for (int i = 1; i < chars.length; ++i) {
                if (!Character.isDigit(chars[i])) {
                    isPhoneNumber = false;
                    break;
                }
            }
            if (isPhoneNumber) {
                return s;
            }
        }

        return s.replaceAll("[\\+\\(\\)\\s\\-]+", "");
    }

    private String reformat(CharSequence s, int cursor) {
        int curIndex = cursor - 1;
        String formatted = null;
        formatter.clear();
        char lastNonSeparator = 0;
        boolean hasCursor = false;
        int len = s.length();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (PhoneNumberUtils.isNonSeparator(c)) {
                if (lastNonSeparator != 0) {
                    formatted = getFormattedNumber(lastNonSeparator, hasCursor);
                    hasCursor = false;
                }
                lastNonSeparator = c;
            }
            if (i == curIndex) {
                hasCursor = true;
            }
        }
        if (lastNonSeparator != 0) {
            formatted = getFormattedNumber(lastNonSeparator, hasCursor);
        }
        return formatted;
    }

    private String getFormattedNumber(char lastNonSeparator, boolean hasCursor) {
        return hasCursor ? formatter.inputDigitAndRememberPosition(lastNonSeparator)
                         : formatter.inputDigit(lastNonSeparator);
    }

    private boolean isPhoneNumber(String s) {
        return !TextUtils.isEmpty(s) && Patterns.PHONE.matcher(s).matches();
    }

    private boolean hasSeparator(final CharSequence s, final int start, final int count) {
        for (int i = start; i < start + count; i++) {
            char c = s.charAt(i);
            if (!PhoneNumberUtils.isNonSeparator(c)) {
                return true;
            }
        }
        return false;
    }

    private void stopFormatting() {
        isFormattingStopped = true;
        formatter.clear();
    }

}

共有1个答案

孙熠彤
2023-03-14

尝试使用Editable提供的方法

    @Override
    public void afterTextChanged(Editable s) {
        target.removeTextChangedListener(this);

        boolean isSymbolsChecked = loginFilter.check(s.toString());
        boolean isEmail = StringUtils.isEmailValid(s.toString());
        boolean isPhoneNumber = isPhoneNumber(s.toString());

        if (lastLength <= s.length()) {
            if (isPhoneNumber && !isFormattingStopped) {
                String formatted = reformat(s, Selection.getSelectionEnd(s));
                if (formatted != null) {
                    s.replace(0, s.length(), formatted)
                    target.setSelection(formatted.length());
                }

            } else if (wasPhoneNumber) {
                String unformatted = unFormatPhoneNumber(s.toString());

                s.replace(0, s.length(), formatted)
                target.setSelection(formatted.length());
            }
        }

        lastLength = s.length();
        wasPhoneNumber = isPhoneNumber;

        if (isFormattingStopped) {
            isFormattingStopped = s.length() != 0;
        }

        target.addTextChangedListener(this);
    }
 类似资料:
  • 当我更新Service Worker时,我关闭并重新打开页面,并获得新的Service Worker已安装并激活的控制台日志,旧的缓存已被删除。但是,列出要添加到缓存中的文件不会再次从服务器获取,它们是几小时前的旧版本。没有办法让它更新文件,除非清除Chrome开发工具中的存储。 安装新版本时,如何让我的服务人员使用新文件填充其缓存? 例如,当服务人员更新时,“stylesheet.css”仍然是

  • 我有一个旧的Android项目。高级宠物商店捆绑标识 运行此命令后 然后将项目包Id更改为com。拜塔里 然后尝试通过Android Studio运行该项目 它总是会引发这样的错误 当然,我试图搜索旧的捆绑ID:com.premium_pets_store它不存在于整个项目中, 那么从哪里Android Studio读它?为什么这个问题?我应该删除旧项目,并用新的捆绑包id替换它 我已经尝试过一些

  • 问题内容: go的核心部分存在http包问题。尽管响应正文中的Content-Length是正确的,但似乎文件内容已缓存。这里展示的是我正在编写的应用程序的简化版本。 现在假设我们有一个非常简单的html页面: 我执行go程序并在浏览器中访问以显示: 检查响应头,我可以看到以下内容: 现在,我编辑html文件,以便标记包含并重新加载页面。我得到以下内容: 再次查看响应标题 因此,http.File

  • 我用Infinispan(8.2.4 Final)设置了一个集群缓存存储,使用SoftIndexFileStore进行持久化。 文档中指出,如果条目过期,压缩程序将无法清理清除的条目,磁盘使用量将随着时间的推移而增加。从用户指南: 当条目存储过期时,SIFS无法检测到其中一些条目已过期。因此,不会压缩这样的旧文件(未实现方法AdvancedStore.purgeExpired()。这可能会导致文件

  • 按照一般app的设计,都是主应用,和用户目录下的缓存文件,把用户自定义的或使用生成的文件都放到缓存文件目录里。鉴于此,我们来找找code.app的缓存文件,或许能发现点有用的东西 可参照 https://code.visualstudio.com/docs/customization/userandworkspace 理解 缓存目录详情 目录是 /Users/sang/Library/Applic

  • Phonegap 2.1 iOS 6 jQuery 1.7.2 JQMobile 1.1.1 我有一个phonegap应用程序,如果我几天不使用该应用程序,它似乎会缓存来自ajax响应的旧数据。我必须重新安装应用程序才能清除它。我找到了应用程序本身的修复程序,但这需要重新发布。它连接到一个.NET WCF REST服务,有没有办法关闭该端的缓存?我在webconfig中根本没有outputCach