Android Custom Keyboard 예제2
직전에 포스팅했던것은 Custom Keyboard에서 Cursor 처리와 백스페이스 처리가 안되었었다.
그러다가 http://www.fampennings.nl/maarten/android/09keyboard/index.htm 여기서
어느정도 Cursor 처리와 백스페이스 처리가 된 hex custom keyboard 를 발견하게 된다.
기능 또한 매우 좋고 잘 정리가 되었으나, 이것 또한 Cusor 처리가 약간 미흡한 부분이 있었다.
그래서 내가 필요한것은 number custom keyboard 이고, Cursor 처리가 필요하지 않게 만들었다.
EditText를 선택하면 selectAll() 하여 모두선택하고,
사용자가 입력한 키보드값을 처음부터 입력하도록 하였고,
Copy & Paste 기능을 이용할 수 있도록 하였다.
1. MainActivity.java
public class MainActivity extends Activity { CustomNumKeyboard mCustomNumKeyboard; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCustomNumKeyboard = new CustomNumKeyboard(this, R.id.keyboardview, R.xml.numkbd); mCustomNumKeyboard.registerEditText(R.id.edittext0); // mCustomNumKeyboard.registerEditText(R.id.edittext1); // mCustomNumKeyboard.registerEditText(R.id.edittext2); mCustomNumKeyboard.registerEditText(R.id.edittext3); mCustomNumKeyboard.registerEditText(R.id.edittext4); } @Override public void onBackPressed() { // NOTE Trap the back key: when the CustomKeyboard is still visible hide // it, only when it is invisible, finish activity if (mCustomNumKeyboard.isCustomKeyboardVisible()) mCustomNumKeyboard.hideCustomKeyboard(); else this.finish(); } }
2. CustomNumKeyboard.java
class CustomNumKeyboard { /** A link to the KeyboardView that is used to render this CustomKeyboard. */ private KeyboardView mKeyboardView; /** A link to the activity that hosts the {@link #mKeyboardView}. */ private Activity mHostActivity; /** The key (code) handler. */ private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() { public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL public final static int CodePrev = 55000; public final static int CodeAllLeft = 55001; public final static int CodeLeft = 55002; public final static int CodeRight = 55003; public final static int CodeAllRight = 55004; public final static int CodeNext = 55005; public final static int CodeClear = 55006; public final static int CodeCopy = 55007; public final static int CodePaste = 55008; public String CopyValue = ""; @Override public void onKey(int primaryCode, int[] keyCodes) { // NOTE We can say '' in the xml file; all codes come in keyCodes, the first in this list in primaryCode // Get the EditText and its Editable View focusCurrent = mHostActivity.getWindow().getCurrentFocus(); if( focusCurrent==null || focusCurrent.getClass()!=EditText.class ) return; EditText edittext = (EditText) focusCurrent; Editable editable = edittext.getText(); int start = edittext.getSelectionStart(); // Apply the key to the edittext if( primaryCode==CodeCancel ) { hideCustomKeyboard(); } else if( primaryCode==CodeDelete ) { if( editable!=null && start>0 ) editable.delete(start - 1, start); if(edittext.hasSelection() == true){ // 마스킹된 상태이면 모두 지움 edittext.setText(Character.toString((char) primaryCode)); } } else if( primaryCode==CodeClear ) { if( editable!=null ) editable.clear(); } else if( primaryCode==CodeLeft ) { if( start>0 ) edittext.setSelection(start - 1); } else if( primaryCode==CodeRight ) { if (start < edittext.length()) edittext.setSelection(start + 1); } else if( primaryCode==CodeAllLeft ) { edittext.setSelection(0); } else if( primaryCode==CodeAllRight ) { edittext.setSelection(edittext.length()); } else if( primaryCode==CodePrev ) { View focusNew= edittext.focusSearch(View.FOCUS_BACKWARD); if( focusNew!=null ) focusNew.requestFocus(); } else if( primaryCode==CodeNext ) { View focusNew= edittext.focusSearch(View.FOCUS_FORWARD); if( focusNew!=null ) focusNew.requestFocus(); }else if(primaryCode == CodeCopy){ CopyValue = edittext.getText().toString(); if(CopyValue != null && CopyValue != ""){ Toast.makeText(mHostActivity, CopyValue+"을 복사하였습니다.", Toast.LENGTH_SHORT).show(); myKeys.get(12).label = CopyValue; mKeyboardView.invalidateKey(12); } }else if(primaryCode == CodePaste){ if(CopyValue != null && CopyValue != ""){ edittext.setText(CopyValue); edittext.setSelection(edittext.length()); } } else { // insert character if(edittext.hasSelection() == true){ // 마스킹된 상태이면 기존값을 지우고, 현재 입력된 키보드값만 입력함. Toast.makeText(mHostActivity, "Selected", Toast.LENGTH_SHORT).show(); edittext.setText(Character.toString((char) primaryCode)); edittext.setSelection(edittext.length()); // 커서를 마지막으로 이동 }else{ editable.insert(start, Character.toString((char) primaryCode)); } } } @Override public void onPress(int arg0) { } @Override public void onRelease(int primaryCode) { } @Override public void onText(CharSequence text) { } @Override public void swipeDown() { } @Override public void swipeLeft() { } @Override public void swipeRight() { } @Override public void swipeUp() { } }; /** * Create a custom keyboard, that uses the KeyboardView (with resource id viewid) of the host activity, * and load the keyboard layout from xml file layoutid (see {@link Keyboard} for description). * Note that the host activity must have a KeyboardView in its layout (typically aligned with the bottom of the activity). * Note that the keyboard layout xml file may include key codes for navigation; see the constants in this class for their values. * Note that to enable EditText's to use this custom keyboard, call the {@link #registerEditText(int)}. * * @param host The hosting activity. * @param viewid The id of the KeyboardView. * @param layoutid The id of the xml file containing the keyboard layout. */ public List myKeys = null; public CustomNumKeyboard(Activity host, int viewid, int layoutid) { mHostActivity= host; mKeyboardView= (KeyboardView)mHostActivity.findViewById(viewid); mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid)); mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener); // Hide the standard keyboard initially mHostActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); myKeys = mKeyboardView.getKeyboard().getKeys(); } /** Returns whether the CustomKeyboard is visible. */ public boolean isCustomKeyboardVisible() { return mKeyboardView.getVisibility() == View.VISIBLE; } /** Make the CustomKeyboard visible, and hide the system keyboard for view v. */ public void showCustomKeyboard( View v ) { mKeyboardView.setVisibility(View.VISIBLE); mKeyboardView.setEnabled(true); if( v!=null ) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0); } /** Make the CustomKeyboard invisible. */ public void hideCustomKeyboard() { mKeyboardView.setVisibility(View.GONE); mKeyboardView.setEnabled(false); } /** * Register EditText with resource id resid (on the hosting activity) for using this custom keyboard. * * @param resid The resource id of the EditText that registers to the custom keyboard. */ public void registerEditText(int resid) { // Find the EditText 'resid' EditText edittext= (EditText)mHostActivity.findViewById(resid); // Make the custom keyboard appear edittext.setOnFocusChangeListener(new OnFocusChangeListener() { // NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus @Override public void onFocusChange(View v, boolean hasFocus) { if( hasFocus ){ showCustomKeyboard(v); }else{ hideCustomKeyboard(); } } }); edittext.setOnClickListener(new OnClickListener() { // NOTE By setting the on click listener, we can show the custom keyboard again, by tapping on an edit box that already had focus (but that had the keyboard hidden). @Override public void onClick(View v) { showCustomKeyboard(v); } }); // Disable standard keyboard hard way // NOTE There is also an easy way: 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a cursor, and no 'edittext.setCursorVisible(true)' doesn't work ) edittext.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { EditText edittext = (EditText) v; int inType = edittext.getInputType(); // Backup the input type edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard edittext.onTouchEvent(event); // Call native handler edittext.setInputType(inType); // Restore input type // edittext.setSelection(edittext.length()); // 커서를 맨 마지막으로 이동 edittext.selectAll(); // 모든 텍스트를 마스킹 return true; // Consume touch event } }); // Disable spell check (hex strings look like words to Android) edittext.setInputType(edittext.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); } }
3. numkbd.xml
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="12.50%p"
android:keyHeight="10%p">
<!--
android:horizontalGap="0.50%p"
android:verticalGap="0.50%p"
NOTE When we add a horizontalGap in pixels, this interferes with keyWidth in percentages adding up to 100%
NOTE When we have a horizontalGap (on Keyboard level) of 0, this make the horizontalGap (on Key level) to move from after the key to before the key... (I consider this a bug)
-->
<Row>
<Key
android:codes="49"
android:keyEdgeFlags="left"
android:keyLabel="1" />
<Key
android:codes="50"
android:keyLabel="2" />
<Key
android:codes="51"
android:keyLabel="3" />
<Key
android:codes="52"
android:keyLabel="4" />
<Key
android:codes="53"
android:keyLabel="5" />
<Key
android:codes="54"
android:keyLabel="6" />
<Key
android:codes="55"
android:keyLabel="7" />
<Key
android:codes="56"
android:keyLabel="8" />
<Key
android:codes="57"
android:keyLabel="9" />
<Key
android:codes="48"
android:keyLabel="0" />
<Key
android:codes="-5"
android:keyIcon="@drawable/sym_keyboard_delete" android:isRepeatable="true"
android:horizontalGap="3.25%p"
/>
<Key android:codes="55007" android:keyLabel="COPY" />
<Key android:codes="55008" android:keyLabel="PASTE" android:keyEdgeFlags="right" />
</Row>
</Keyboard>
'안드로이드 개발 팁' 카테고리의 다른 글
android textview setlayoutparams programmatically (0) | 2014.05.29 |
---|---|
android dp, px 해상도 변환 및 폰 해상도 구하기 (0) | 2014.05.28 |
Android Custom Keyboard 예제 (2) | 2014.05.19 |
android 색칠하기 알고리즘 (0) | 2014.05.13 |
android webview popup 보여주기 (0) | 2014.03.25 |