2015年3月8日日曜日

EditTextで絵文字を含む文字列の文字数制限処理

絵文字を含む文字列の文字数制限で少しハマりました。
最終的に以下のコードで対応しました。
final int MAX_TEXT_LENGTH = 10;
final EditText editText = (EditText) findViewById(R.id.edit_text);
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) {
        if (unfixInput(s)) {
            return;
        }
        final String str = s.toString();

        final String adjustedText = adjustText(str);
        if (!str.equals(adjustedText)) {
            editText.setText(adjustedText);
            editText.setSelection(editText.getText().length());
            Toast.makeText(getApplicationContext(), String.format("最大%d文字です", MAX_TEXT_LENGTH), Toast.LENGTH_SHORT).show();
            return;
        }
        // TODO 内容保存処理
    }

    /**
     * 入力確定前の文字があるときtrue
     */
    private boolean unfixInput(final Editable s) {
        Object[] spanned = s.getSpans(0, s.length(), Object.class);
        if (spanned != null) {
            for (Object obj : spanned) {
                if ((s.getSpanFlags(obj) & Spanned.SPAN_COMPOSING) == Spanned.SPAN_COMPOSING) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 文字列の調整
     */
    private String adjustText(final String str) {
        if (MAX_TEXT_LENGTH < str.codePointCount(0, str.length())) { // 文字数は、コードポイントで比較
            return adjustText(str.substring(0, (str.length() - 1)));
        }
        return str;
    }
});

ハマった原因

xmlのEditTextに
android:maxLength="10"
と設定しても、 文字数のカウントがサロゲートの文字が配慮されておらず、絵文字など、文字コードがサロゲートの場合、1文字で2文字と認識されてしまいます。
そのため、最大10文字と設定していても、絵文字を含む文字列だと5〜9文字までしか入力できないEditTextになってしまいます。

対処方法

  • EditTextのmaxLengthは使用しない
  • 文字数のカウントは、String#codePointCountメソッドを使用する

コードポイントとは

コードポイントとは、Unicodeで1文字分のコードを示す言い方。Javaではコードポイントはint型で表す。(引用元:http://www.ne.jp/asahi/hishidama/home/tech/java/string.html)

他、参考



0 件のコメント:

コメントを投稿