I have designed a custom key board with only numeric keys. I have followed the below link: example
Now when i am touching the edit box, key board is appearing. But if i have 10 editboxes, and i am touching the 10th edit box, key board is appeared and hiding the edit box.How can i make the edit box will scroll up automatically so that it will be not hidden.
I have written the below layout code for xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="@+id/edittext0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:inputType="text" />
<EditText
android:id="@+id/edittext1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/edittext0"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:inputType="text" />
<EditText
android:id="@+id/edittext2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/edittext1"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:inputType="text" />
<EditText
android:id="@+id/edittext3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/edittext2"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:inputType="text" />
<EditText
android:id="@+id/edittext4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/edittext3"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:inputType="text" />
</RelativeLayout>
</ScrollView>
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboardview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:visibility="gone" />
</RelativeLayout>
Also here is my custom keyboard java class:
class CustomKeyboard {
/** 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 CodePrev = 55000;
public final static int CodeNext = 55001;
public final static int CodeDone = 55002;
@Override
public void onKey(int primaryCode, int[] keyCodes) {
// NOTE We can say '<Key android:codes="49,50" ... >' 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 == CodeDone) {
hideCustomKeyboard();
}
else if (primaryCode == CodeDelete)
{
if (editable != null && start > 0)
editable.delete(start - 1, start);
}
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 { // insert character
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
* <var>viewid</var>) of the <var>host</var> activity, and load the keyboard
* layout from xml file <var>layoutid</var> (see {@link Keyboard} for
* description). Note that the <var>host</var> activity must have a
* <var>KeyboardView</var> 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 CustomKeyboard(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);
}
/** 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 <var>EditText<var> with resource id <var>resid</var> (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
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);
}
}
Help me please!!
Thanks, Arindam
I had the exact same problem and after a full days research i have finally solved it.
Here is how:
I have nearly identical xml layout as yours but i have multiple KeyboardViews because i need different keyboards for different EditTexts.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="HardcodedText,TextFields" >
<ScrollView
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:paddingBottom="16dp">
<TextView
android:id="@+id/DecLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Decimal" />
<EditText
android:id="@+id/DecText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true" />
<TextView
android:id="@+id/HexLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Hexadecimal" />
<EditText
android:id="@+id/HexText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true" />
<TextView
android:id="@+id/BinaryLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Binary" />
<EditText
android:id="@+id/BinaryText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true" />
<TextView
android:id="@+id/OctalLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Octal" />
<EditText
android:id="@+id/OctalText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_gravity="fill" />
</LinearLayout>
</ScrollView>
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboardview_hex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/btn_keyboard_key_ics"
android:visibility="gone" />
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboardview_dec"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/btn_keyboard_key_ics"
android:visibility="gone" />
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboardview_oct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/btn_keyboard_key_ics"
android:visibility="gone" />
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboardview_bin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/btn_keyboard_key_ics"
android:visibility="gone" />
It is not enough. I also needed to set ScrollView's android:layout_above property when the KeyboardView is shown and i did this with an interface:
public interface OnKeyboardStateChangedListener
{
public void OnDisplay(View currentview, KeyboardView currentKeyboard);
public void OnHide(KeyboardView currentKeyboard);
}
And implemented this interface to my MainActivity to edit ScrollView's properties:
public class MainActivity extends Activity BaseKeyboard.OnKeyboardStateChangedListener
Also i passed MainActivity as a parameter and saved as OnKeyboardStateChangedListener:
private OnKeyboardStateChangedListener mStateListener;
public BaseKeyboard(Activity host, int viewid, int layoutid, OnKeyboardStateChangedListener listener) {
..
..
mStateListener = listener;
}
And invoked it when displaying/hiding the keyboard:
public void showCustomKeyboard( View v ) {
mKeyboardView.setVisibility(View.VISIBLE);
mKeyboardView.setEnabled(true);
if( v!=null ) {
mStateListener.OnDisplay(v, mKeyboardView);
((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
public void hideCustomKeyboard() {
mKeyboardView.setVisibility(View.GONE);
mKeyboardView.setEnabled(false);
mStateListener.OnHide(mKeyboardView);
}
And finally i edited the parameters in the MainActivity:
@Override
public void OnDisplay(View currentview, KeyboardView currentKeyboard) {
ScrollView mScroll = (ScrollView) findViewById(R.id.scroll_content);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
params.addRule(RelativeLayout.ABOVE, currentKeyboard.getId());
mScroll.setLayoutParams(params);
mScroll.scrollTo(0, currentview.getBaseline()); //Scrolls to focused EditText
}
@Override
public void OnHide(KeyboardView currentKeyboard) {
ScrollView mScroll = (ScrollView) findViewById(R.id.scroll_content);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
mScroll.setLayoutParams(params);
}
Here are the screenshots:
I have LinearLayout instead of RelativeLayout inside ScrollView because when my keyboard is shown, ScrollView works as needed but it cuts the most bottom View in half and padding or margin doesn't work with RelativeLayout in this situation but adding a paddingBottom to LinearLayout pushes it back and all of the View is visible. I couldn't find another way to fix this.
You should try different size of paddings to satisfy your needs.
I can provide full source code and additional info if you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With