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
< 끝 >