【问题标题】:Create Extended ASCII Character InputFilter创建扩展 ASCII 字符输入过滤器
【发布时间】:2012-10-09 14:49:04
【问题描述】:

我正在使用下面的 InputFilter 过滤掉无效(十进制值大于 127 的 ASCII),当输入无效字符时,EditText 会显示文本两次。我确实希望 EditText 显示有效字符,下面是发生情况的示例。

-用户在EditText组件中输入XYZ€
-toast 消息出现在屏幕上,指出“无效的非 Ascii 字符”
-EditText 组件在屏幕上显示 xyz,这是我所期望的
-用户输入一个有效字符,A,所以屏幕显示XYZA
-InputFilter 运行并返回 XYZAXYZXYZA 出现在 EditText 组件中,这是不正确的。它复制了 XYZ

关于为什么在处理无效字符后重复输入的文本有什么想法吗?

屏幕:

<EditText android:id="@+id/editText"
    android:layout_width="fill_parent" android:layout_height="120dp"
    android:layout_marginTop="10dp" android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp" android:maxLength="45"
    android:focusable="true" android:inputType="text"
    android:cursorVisible="true" android:imeOptions="actionDone"
 />

活动:

public class EditTextActivity extends Activity {        

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        EditText eText = (EditText) findViewById(R.id.editText);
        setAsciiTextFilter();
    }    

    private void setAsciiTextFilter() {

              InputFilter filter = new InputFilter() {

                    int asciiNo;

                    @Override
                    public CharSequence filter(CharSequence source, int start, int end,
                            Spanned dest, int dstart, int dend) {

                        for (int i = start; i < end; i++) {

                            asciiNo = source.charAt(i);

                            if(asciiNo > 127) {       

                                toast = mUtility.showToast("Invalid non-Ascii Character", Toast.LENGTH_SHORT);

                                //Replace the invalid ascii character with empty String
                                return source.toString().replace(source.charAt(i)+"", "");
                            }    
                        }
                        return null;
                    }
                };


           eText.setFilters(new InputFilter[]{filter}); 
    }
}

新尝试:

 InputFilter filter = new InputFilter() {
                        @Override
                        public CharSequence filter(CharSequence source, int start, int end,
                                Spanned dest, int dstart, int dend) {

                            if (source instanceof SpannableStringBuilder) {
                                SpannableStringBuilder sourceAsSpannableBuilder = (SpannableStringBuilder)source;
                                for (int i = end - 1; i >= start; i--) { 
                                    char currentChar = source.charAt(i);
                                    int ascii = currentChar;
                                     if (ascii > 127) {    
                                         sourceAsSpannableBuilder.delete(i, i+1);
                                         toast = mUtility.showToast("Invalid non-Ascii Character", Toast.LENGTH_SHORT);
                                     }     
                                }
                                return source;
                            } else {
                                StringBuilder filteredStringBuilder = new StringBuilder();
                                for (int i = 0; i < end; i++) { 
                                    char currentChar = source.charAt(i);
                                    int ascii = currentChar;
                                    if (ascii <= 127) {    
                                        filteredStringBuilder.append(currentChar);
                                    }     
                                }
                                return filteredStringBuilder.toString();
                            }
                        }
                    };

【问题讨论】:

    标签: android


    【解决方案1】:

    我发现最好使用单个 for 循环和答案。

    还请注意,将源传递给 SpannableStringBuilder 构造函数以便从源复制跨度非常重要。如果你不这样做,事情就会变得很糟糕。

        @Override
        public CharSequence filter(CharSequence source, int start,
                int end, Spanned dest, int dstart, int dend) {
            SpannableStringBuilder ret;
    
            if (source instanceof SpannableStringBuilder) {
                ret = (SpannableStringBuilder)source;
            } else {
                ret = new SpannableStringBuilder(source);
            }
    
            for (int i = end - 1; i >= start; i--) {
                char currentChar = source.charAt(i);
                char currentChar = source.charAt(i);
                int ascii = currentChar;
                if (ascii > 127) {    
                    ret.delete(i, i+1);
                    toast = mUtility.showToast("Invalid non-Ascii Character", Toast.LENGTH_SHORT);
                }     
            }
    
            return ret;
        }
    

    【讨论】:

      【解决方案2】:

      已编辑:

      我认为问题在于您要返回整个字符串,而您应该只返回该字符的替换。 filter() 在文本更改时运行,并且不一定替换 EditText 中的整个字符串。你需要注意这一点,所以你最终不会把整个字符串推到一个字符应该去的地方。

      This question 是相关的(只需将非 ascii 替换为非字母数字),并且那里的答案被广泛接受,因此您应该能够使用它来获得您想要的。

      对于令人困惑的答案/删除问题,我们深表歉意。我在离开家之前就回答了。几分钟后,我意识到我的逻辑有一个巨大的缺陷,所以我跳上手机删除了它。我讨厌尝试在手机上输入完整的答案,所以只需要稍等片刻即可。

      【讨论】:

      • 感谢您的回答。我使用了您的建议并更新了我上面的代码(在新尝试:部分)。一旦输入了无效字符,即使是有效字符,toast 也会继续显示,因为 sourceAsSpannableBuilder.delete(i, i+1);每次都不断删除无效字符。 sourceAsSpannableBuilder 似乎保留了无效字符,即使 EditText 没有显示它。仅在输入无效字符时才显示吐司的任何方法?感谢所有的帮助...
      • 忽略上面的问题,if(end == i+1){ //show toast} 有效
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      • 2022-01-14
      • 2010-11-22
      • 1970-01-01
      相关资源
      最近更新 更多