AndroidのEdittext表情記号の入力禁止(雷驚風)


先日のプロジェクトの中にEditTextの規定があって、入力法の表情を入力することを禁止して、すぐに書きました.今になってやっと問題が検出されました.中にはいくつかのバージョンが入っています.テストは何回も変わりました.会社のQAがどのような状況なのかがわかります.ああ、ここで言ってください.どうせ彼らは見えません.見ても誰が言ったのか分かりません.さて本題に戻りますが、まず間違ったコードを見てみましょう.皆さんは検討してみてください.今はもう変更しました.gitの歴史をめくって、間違ったコードをcopyしてください.
 mAppraiseEdit.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                cursorPos = mAppraiseEdit.getSelectionEnd();
                inputAfterText = s.toString();
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!resetText) {
                    if (count >= 2) {
                        CharSequence input = s.subSequence(cursorPos, cursorPos + count);
                        if (TextUtil.containsEmoji(input.toString())) {
                            resetText = true;
                            UIUtils.showShortCustomToast(AppraiseActivity.this, "           ");
                            mAppraiseEdit.setText(inputAfterText);
                            CharSequence text = mAppraiseEdit.getText();
                            if (text instanceof Spannable) {
                                Spannable spanText = (Spannable) text;
                                Selection.setSelection(spanText, text.length());
                            }
                            return;
                        }
                    }
                } else {
                    resetText = false;
                }


            }

            @Override
            public void afterTextChanged(Editable s) {


            }
        });

         
このような場合、このバグは1つのバージョンを隠して、1つのQAを倒して、興味のある人はまず試して、何か問題があるかを探して、後で私はどのような状況で問題が発生するかを説明して、ああ、そうだ、IndexOutOfBoundsExceptionの問題が発生しました.
最後にafterTextChanged(Editable)メソッドで解決したのですが、有表情記号を検出してそのまま既存の文字列で1文字切り取れば良いと思い、最後に切り取るたびにedittextに1文字多くの「�」が入っていることに気づき、少し間違えました.私はEditableが異なる情況の下で混合して英語、漢字、記号と表情の彼のs.lengthとsの内容の関係を入力することを印刷して、毎回表情sの内容を入力するのはすべて“�”で、彼らの関係は:まず表情を入力する時、s=“�”、s.length=2;英語のアルファベットを入力して表情を入力すると、s=“e�”、s.length=3になります.1つの漢字を入力して表情を入力する時、s=“私�”、s.length=3;一つの表情、androidは二つの「�」に取って代わられたようで、私はs.equals(「�」)で判断しようとしたが、全然だめだった.1時間ほど退勤して、ちょうど明日は週末で、2日間休んでいた.月曜日の出勤時、パソコンを開けてこのバグを見て、それぞれの表情が2つのlengthの長さを占めている以上、入力ボックスに表情が含まれていることを検出したら、そのまま現在のStringで末尾length 2の長さを削除すれば良い(表情を入力してafterTextChange()を実行すると、Stringに表情の「�」が加わっているので)、自分の考え次第ですぐに所望の結果が得られます.今、先週の金曜日を思い出して、自分がその時すでに深く潜っていたかもしれませんが、思想の上から出てこなかったので、愚かになって、自分で直接自分を軽蔑しました:拭いて、どうしたのか、その時頭が水に入って、やはりロバを蹴って、これは簡単ではありませんか、どうして1時間も振り回して、いいですよ.では、冗談を言って、下に直接コードをつけます.
edittext.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) {
                int index = mAppraiseEdit.getSelectionStart() - 1;
                if (index > 0) {
                    if (TextUtil.isEmojiCharacter(s.charAt(index))) {
                        Editable edit = mAppraiseEdit.getText();
                        edit.delete(s.length() - 2, s.length());
                        UIUtils.showShortCustomToast(AppraiseActivity.this, "         ");
                    }
                }

            }
        });

         
ああ、そう簡単ですね.ところで、上のような書き方のバグは、いくつかの三方入力法と関係があります.いくつかの入力法は、中国語を入力すると、アルファベットがedittextに事前に表示されます.例えば、「ニュース」という言葉を入力したいのですが、「xw」を入力するとedittextの中には空で、入力法の中国語部分に「ニュース」「勉強」「今」などが表示され、edittextの中では空ですが、edttextの中には先に「xw」の下に線が表示されます.「ニュース」を選択すると「xw」は「ニュース」に置き換えられます.今このバグが後に出てくるのはCharSequence input=ssubSequenceです.(cursorPos,cursorPos+ count);この行のコードは、IndexOutOfBoundsExceptionのバグを報告します.興味のある人は解決して、今日のblogsは先にここに着いて、紙幅は小さくて、自分のためにツッコミを入れるだけで、ついでに記録します.
表情コードが存在するかどうかを検出します.
public static boolean isEmojiCharacter(char codePoint) {
        return !((codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD) || ((codePoint >= 0x20) && codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }