当用户开始输入 EditText 时,它可以在末尾附加一个文件扩展名吗?

As a user starts to type in an EditText can it append a file extension to the end?

问题: 我一直在尝试在 real-time 中追加用户键入光标后的文件扩展名,但没有成功。

我的尝试: 我一直在尝试使用我认为正确的 .addTextChangedListener(),但在尝试实现这个想法时遇到了问题.调试显示不断循环,因此呈现出冻结的外观。我在论坛上查看了几个 post,但是当我输入这个 post 标题时建议的那些涉及前缀而不是后缀。

EditText 字段,其中突出显示的区域代表光标右侧的文本:

我为让它发挥作用的一次糟糕尝试:

private void setupAddDBEditText(){

    mDBToAdd.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

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

        @Override
        public void afterTextChanged(Editable s) {
            if(s.toString().contains(".db"))
                mDBToAdd.setText(s.toString().substring(0,s.toString().length()-3));
            mDBToAdd.setText(s + ".db");
        }
}

您需要在更改文本时删除侦听器(这就是您获得无限循环的原因)。

您可以创建一个自定义 TextWatcher 来处理这种事情(如下),它会将自己作为观察者删除,更改文本并将光标放在正确的位置,然后再将自己添加回来。

public class FileExtensionTextWatcher implements TextWatcher {
    private final String extension;
    private final EditText text;

    FileExtensionTextWatcher(EditText t, String ext) {
        extension = ext;
        text = t;
    }

    // you may want to change around the logic in here to allow for
    // odd entries or other changes - but the overall approach should
    // be similar
    private String removeAutoExtension(String s) {
        String ext = "." + extension;
        if( s.contains(ext) ) {
            int ei = s.lastIndexOf(ext);
            if( ei == 0 ) return "";
            String trailingChar = "";
            if( ei < s.length() - ext.length() ) {
                trailingChar = s.substring(ei+ext.length());
            }
            return s.substring(0,ei) + trailingChar;
        }
        else {
            return s;
        }
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

    @Override
    public void afterTextChanged(Editable txt) {
        if( txt == null ) return;

        String currentText = txt.toString();
        String filename = removeAutoExtension(currentText);
        int initCursor = filename.length();
        String displayedText;
        if( filename.isEmpty() ) {
            displayedText = filename;
        }
        else {
            displayedText = filename + "." + extension;
        }

        text.removeTextChangedListener(this);
        txt.clear();
        txt.insert(0, displayedText);
        text.setSelection(initCursor);
        text.addTextChangedListener(this);
    }
}

然后你会像这样使用它

EditText e = findViewById(R.id.edit_text);
e.addTextChangedListener(new FileExtensionTextWatcher(e, "db"));

这是演示 GIF 的外观。

您可能需要进行一些更改来处理诸如是否允许用户输入他们自己的扩展名之类的事情(此表单不允许 - 但您可以在自定义观察器中使用一些额外的逻辑来更改它) .