InputConnection 클래스와 관련해서 오류가 있습니다. 지금 작업하고 있는 것이 사용자가 EditText에 텍스트를 입력하고 엔터를 눌렀을 때 입력된 텍스트를 변환해 보여주는 것입니다. 이러한 과정에 한글이 입력됐을 때 오류가 발생합니다.
사용자가 한글을 입력 후 엔터를 눌렀을 때 메소드의 흐름을 보자면 한 글자를 입력할 때마다 setComposingText(text, newCursorPosition)이 호출, 엔터를 눌렀을 때 onEditorAction(v, actionid, event)이 호출되고나서 finishComposingText() 또는 commitText(text, newCursorPosition)가 호출됩니다.
이때 finishComposingText()가 호출 되었다면 정상 작동을 하는 경우이고, commitText(text, newCursorPosition) 이 호출되었다면 오류가 발생하는 경우입니다.
오류가 발생했을 때의 결과는, 예를 들어, 사용자가 ㄱㄴㄷ 을 입력하고 엔터를 눌렀을 때 ㄱㄴㄷ를 변형된 텍스트 ㅁㅂㅅ 로 교체해야 하는데, ㅁㅂㅅ로 교체하고 난 후에 commitText(text, newCursorPosition) 이 호출되며 EditText에 남아있는 텍스트는 ㅁㅂㅅㄱㄴㄷ가 됩니다. 왜 이러한 문제가 발생하는지 어떻게 해결해야할 지 궁금합니다.
다음은 메소드 호출 순서를 나타냅니다:
-
setComposingText(text, newCursorPosition); …. (입력 한 글자마다 호출) ...
-
onEditorAction(v, actionId, event);
-
clearComposingText();
-
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();
}
}
}