마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

한국어 키보드 입력 관련 InputConnection 클래스 오류

0 추천

InputConnection 클래스와 관련해서 오류가 있습니다. 지금 작업하고 있는 것이 사용자가 EditText에 텍스트를 입력하고 엔터를 눌렀을 때 입력된 텍스트를 변환해 보여주는 것입니다. 이러한 과정에 한글이 입력됐을 때 오류가 발생합니다.

사용자가 한글을 입력 후 엔터를 눌렀을 때 메소드의 흐름을 보자면 한 글자를 입력할 때마다 setComposingText(text, newCursorPosition)이 호출, 엔터를 눌렀을 때 onEditorAction(v, actionid, event)이 호출되고나서 finishComposingText() 또는 commitText(text, newCursorPosition)가 호출됩니다.

이때 finishComposingText()가 호출 되었다면 정상 작동을 하는 경우이고, commitText(text, newCursorPosition) 이 호출되었다면 오류가 발생하는 경우입니다.

오류가 발생했을 때의 결과는, 예를 들어, 사용자가 ㄱㄴㄷ 을 입력하고 엔터를 눌렀을 때 ㄱㄴㄷ를 변형된 텍스트 ㅁㅂㅅ 로 교체해야 하는데, ㅁㅂㅅ로 교체하고 난 후에 commitText(text, newCursorPosition) 이 호출되며 EditText에 남아있는 텍스트는 ㅁㅂㅅㄱㄴㄷ가 됩니다. 왜 이러한 문제가 발생하는지 어떻게 해결해야할 지 궁금합니다.

 

다음은 메소드 호출 순서를 나타냅니다:

  1. setComposingText(text, newCursorPosition); …. (입력 한 글자마다 호출) ...
  2. onEditorAction(v, actionId, event);
  3. clearComposingText();
  4. finishComposingText(); OR commitText(text, newCursorPosition);

 

다음의 조건을 만족해야 합니다:

  • 키보드를 내리지 말것 (onEditorAction(v, actionId, event) 의 return 값을 true 로)
  • replace 가 호출되기 전에 clearComposingText() 가 호출될 것

 

다음은 코드 전문입니다.

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    CustomEditText et = (CustomEditText) findViewById(R.id.ttv);
}

 

activity_main.xml:

<com.example.jujaeho.testmyapplication.CustomEditText
    android:id="@+id/ttv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="텍스트 입력" />

 

CustomEditText.java:

(CustomInputConnection 서브 클래스는 로그를 확인하기 위함입니다.)

public class CustomEditText extends EditText implements TextView.OnEditorActionListener {
    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOnEditorActionListener(this);
        setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    }

    public CustomEditText(Context context) {
        super(context);
        setOnEditorActionListener(this);
        setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    }

    @Override
    public void clearComposingText() {
        Log.d("ABC", "@clearComposingText");
        super.clearComposingText();
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        final InputConnection connection =
                new CustomInputConnection(super.onCreateInputConnection(outAttrs), true);
        final int imeActions = outAttrs.imeOptions & EditorInfo.IME_MASK_ACTION;
        if ((imeActions & EditorInfo.IME_ACTION_DONE) != 0) {
            // clear the existing action
            outAttrs.imeOptions ^= imeActions;
            // set the DONE action
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
        }

        if ((outAttrs.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
            outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        }
        return connection;
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        Log.d("ABC", "@onEditorAction");
        clearComposingText();
        getText().replace(0, getText().length(), "sdf");
        return true;
    }

    private class CustomInputConnection extends InputConnectionWrapper {
        public CustomInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        @Override
        public boolean performEditorAction(int editorAction) {
            Log.d("ABC", "@performEditorAction");
            return super.performEditorAction(editorAction);
        }

        @Override
        public boolean commitText(CharSequence text, int newCursorPosition) {
            Log.d("ABC", "@commitText-text=" + text);
            return super.commitText(text, newCursorPosition);
        }

        @Override
        public boolean setComposingText(CharSequence text, int newCursorPosition) {
            Log.d("ABC", "@setComposingText-text=" + text);
            return super.setComposingText(text, newCursorPosition);
        }

        @Override
        public boolean finishComposingText() {
            Log.d("ABC", "@finishComposingText");
            return super.finishComposingText();
        }
    }
}

 

강동투 (290 포인트) 님이 2015년 8월 17일 질문
강동투님이 2015년 8월 17일 수정

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...