Android InputMethodManager 이용한 Text 입력
* Android에서 텍스트를 입력하는 방법에 대해 테스트를 해본다.* 2가지 방법을 이용하여 sample project를 만들어 본다.
1. EditText (TextWatcher) 이용
2. InputConnection (KeyListener) 이용
< EditText 이용>
1. 화면에 TextView와 EditText를 하나 구성한다. /*
* Step 1
* - Backgroud로 보여줄 이미지를 설정한다.
* - Text가 보여질 TextView를 추가한다.
* - TextView에 입력하기 위해 EditText를 하나 생성한다.
*
* - EditText를 터치하면, IME가 자동으로 올라온다(show).
* - IME를 내릴경우(hide) 취소 키를 눌러야 하고, EditText에는 커서가 그대로 남아있다.
*/
// main layout
ViewGroup.LayoutParams layoutParamsMain =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
// sub layout
ViewGroup.LayoutParams layoutParamsSub =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
FrameLayout mainLayout = new FrameLayout(this);
LinearLayout subLayout = new LinearLayout(this);
subLayout.setOrientation(LinearLayout.VERTICAL);
// Background 용 ImageView
mImageView = new ImageView(this);
mImageView.setBackgroundResource(R.drawable.iu3);
// Text 입력을 위한 EditText와 Text를 보여줄 TextView
mTextView = new TextView(this);
mEditText = new EditText(this);
// Initial Text 설정.
mTextView.setText(mInitText1);
mEditText.setText(mInitText2);
// Add Views ( ImageView, TextView )
mainLayout.addView(mImageView, layoutParamsMain);
subLayout.addView(mTextView, layoutParamsSub);
subLayout.addView(mEditText, layoutParamsSub);
mainLayout.addView(subLayout, layoutParamsSub);
2. EditText에 TextWatcher의 Listener를 붙인다.- 3개의 method를 이용한다(onTextChanged, beforeTextChanged, afterTextChanged).
/*
* Step 2
* - EditText 에 Text가 입력될 때마다 변경되는 Text를 TextView에 보여주기 위해
* - TextWathcer를 implements 한다.
* - 또는 아래 주석처럼 사용할 수도 있겠다.
*
* - Step 2까지 하게되면, EditText 에 Text를 입력하면 TextView에도 그 Text가 반영된다.
* - 이 상태 역시 EditText를 터치하면, IME가 자동으로 올라오게 된다(show).
* - IME를 내릴경우(hide) 취소 키를 눌러야 하고, EditText에는 커서가 그대로 남아있다.
*/
mEditText.addTextChangedListener(this);
// mTextWatcher = new TextWatcher() {
//
// @Override
// public void onTextChanged(CharSequence s, int start, int before, int count) {
// // TODO Auto-generated method stub
// Log.i(TAG , "onTextChanged() is called");
// Log.e(TAG, "String = " + s);
//
// mTextView.setText(s);
// }
//
// @Override
// public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// // TODO Auto-generated method stub
// Log.i(TAG , "beforeTextChanged() is called");
// Log.e(TAG, "String = " + s);
// }
//
// @Override
// public void afterTextChanged(Editable s) {
// // TODO Auto-generated method stub
// Log.i(TAG , "afterTextChanged() is called");
// Log.e(TAG, "String = " + s);
// }
// };
// mEditText.addTextChangedListener(mTextWatcher);
/*
* Step 2
* - EditText 에 Text가 입력될 때마다 변경되는 Text를 보기위해 TextWathcer를 implements 한다.
* - 아래 method들을 이용하면 되겠다.
*/
// TextWatcher methods
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
Log.i(TAG , "onTextChanged() is called");
Log.e(TAG, "String = " + s);
// TextView에 입력된 Text를 반영하자.
mTextView.setText(s);
}
3. TouchListener를 이용하여 IME를 보여주자.
* 이 단계는 생략하는 것이 EditText를 사용하는데 더 좋은 것 같다.
/*
* Step 3
* - 이제 TouchListener를 이용하여 IME의 show를 control 해보자.
* - 사길 Step 2까지만 하는 것이 EditText에 텍스트를 입력하는 것에는 더 좋을 것이다.
* - Step 2에서는 cursor의 위치 이동, 텍스트 잘라내기, 붙여넣기 등의 기능들이 자동으로 제공된다.
* - 오히려, EditText를 터치하는 동작에서 IME를 보여주게 되면 기존의 기능들을 별도로 해줘야 한다.
* - cursor 위치 이동, 복사, 잘라내기, 붙여넣기 등...
* - IME를 보이게 하는 것을 테스트하기 위함이라 아래 코드를 추가한다.
*/
mEditText.setOnTouchListener(this);
/*
* Step 3
* - Touch 동작에 맞게 IME를 보여주는 것을 해보자(show).
* - InputMethodManager의 INPUT_METHOD_SERVICE를 이용한다.
*/
@Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
Log.i(TAG , "onTouch() is called");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// Touch Up 동작에서 IME를 보여주자.
showIME(view);
break;
}
return true;
}
/**
* IME를 보이게 해준다.
* @param view : target view
*/
public void showIME(View view) {
Log.i(TAG , "showIME() is called");
CharSequence initText = null;
initText = mTextView.getText();
mEditText.setText(initText); // TextView의 초기 Text를 EditText로 보이게 하자.
InputMethodManager mInputMethod = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
Log.e(TAG , "mInputMethod = " + mInputMethod);
mInputMethod.showSoftInput(view, InputMethodManager.SHOW_FORCED);
}
< InputConnection 이용 >
1. 화면에 TextView를 하나 구성한다.- 위의 1단계의 코드와 별반 다를 것은 없고, EditText만 삭제하면 된다.
2. TextView에 TouchListener를 달아서 테스트를 해보자.
- InputConnection을 이용한다.
/*
* Step 2
* - 이제 TouchListener를 이용하여 IME의 show를 control 해보자.
* - 텍스트를 보여 줄 TextView를 터치하면, IME 가 나오도록 한다.
*/
mTextView.setOnTouchListener(this);
/*
* Step 3
* - IME로부터 입력되는 Text를 보여주기 위한 것.
* - TextView에 연결된 IME로부터 Key 입력을 받기 위해, KeyListener를 연결한다.
*/
mTextView.setFocusable(true);
mTextView.setFocusableInTouchMode(true); // 이게 있어야 TextView안의 Text가 변경된다.
mTextView.requestFocus();
mTextView.focusSearch(View.FOCUS_DOWN);
mKeyListener = TextKeyListener.getInstance();
mTextView.setKeyListener(mKeyListener);
- onTouch()에서 ACTION_UP 이벤트에 동작하게 하자.
/*
* Step 2
* - TextView를 터치하였을 때, IME를 올리도록 하자(show).
* - IME와 연동을 위해 InputConnection을 생성하자.
*/
@Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
Log.i(TAG , "onTouch() is called");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// Touch Up 동작에서 IME를 보여주자.
showIME(view);
break;
}
return true;
}
/**
* IME를 보이게 해준다.
* @param view : target view
*/
public void showIME(View view) {
Log.i(TAG , "showIME() is called");
// Text 정보를 전달하기 위해 InputConnection을 생성한다.
mEditorInfo = new EditorInfo();
onCreateInputConnection(mEditorInfo);
InputMethodManager mInputMethod = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
Log.e(TAG , "mInputMethod = " + mInputMethod);
// IME를 올려보자.
mInputMethod.showSoftInput(view, InputMethodManager.SHOW_FORCED);
// 아래와 같이 하여도 동작한다.
// mInputMethod.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
- InputConnection과 연결을 한다.
/*
* 텍스트 입력을 위해 InputConnection과의 연결을 한다.
*
* @param outAttrs : Editor의 속성 값들을 전달한다.
* @return InputConnection의 Instance.
*/
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
Log.i(TAG , "onCreateInputConnection() is called");
Log.i(TAG , "onCreateInputConnection() mInputConnection = " + mInputConnection);
if(mInputConnection == null ) {
mInputConnection = new EditableInputConnection(mTextView, true);
}
return mInputConnection;
}
* 위에서 테스트한 코드들은 텍스트를 입력하여, TextView에 보이게만 한 것이다.
* EditText를 이용할 때, 복사, 붙여넣기, 잘라내기, Cursor 이동에 대해서는 테스트가 더 필요해 보인다.
* 테스트할 것들이 많구만...
< Source >
https://bitbucket.org/snoh/androidinputmethodtestMercurial command : hg clone https://bitbucket.org/snoh/androidinputmethodtest
< 끝 >