Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android custom keyboard - Preview view constrained to parent layout

I have created a custom keyboard, which works fine - except the preview views for the top two rows of keys are not displayed high enough. Their vertical position is being constrained by the parent layout.

These screenshots illustrate the problem - the position of the preview for '0' and '8' is good, but for '5' and '2' it is not:

The preview for key '0' is shown above the button...

Button '0'

The preview for key '8' is also shown above the button...

Button '8'

But the preview for key '5' is not shown above the button...

Button '5'

And the preview for key '2' is not shown above the button...

Button '2'

How to overcome, so the preview for '5' and '2' are displayed at the same distance above their respective key as it is for '0' and '8'.

Here is my keyboard.xml...

<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:keyPreviewLayout="@layout/keyboard_key_preview" />

Here is my keyboard_key_preview.xml...

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@color/keyboard_preview_bg"
    android:textColor="@color/keyboard_preview_fg"
    android:textStyle="bold"
    android:textSize="@dimen/keyboard_preview_text_size" />

Here is my keyboard_numeric.xml layout...

<Keyboard
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="33.33%p"
    android:keyHeight="@dimen/keyboard_key_height"
    android:horizontalGap="@dimen/keyboard_horizontal_gap"
    android:verticalGap="@dimen/keyboard_vertical_gap">
    <Row android:rowEdgeFlags="top">
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3" android:keyEdgeFlags="right"/>
    </Row>
    <Row>
        <Key android:codes="52" android:keyLabel="4" android:keyEdgeFlags="left"/>
        <Key android:codes="53" android:keyLabel="5"/>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="right"/>
    </Row>
    <Row>
        <Key android:codes="55" android:keyLabel="7" android:keyEdgeFlags="left"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9" android:keyEdgeFlags="right"/>
    </Row>
    <Row android:rowEdgeFlags="bottom">
        <Key android:codes="-5" android:keyIcon="@drawable/ic_backspace_white_24dp" android:isRepeatable="true" android:keyEdgeFlags="left" />
        <Key android:codes="48" android:keyLabel="0"/>
        <Key android:codes="-4" android:keyLabel="DONE" android:keyEdgeFlags="right"/>
    </Row>
</Keyboard>
like image 709
ban-geoengineering Avatar asked Oct 04 '17 12:10

ban-geoengineering


People also ask

How do I turn off soft keyboard on Android?

Hiding the Soft Keyboard Programmatically You can force Android to hide the virtual keyboard using the InputMethodManager, calling hideSoftInputFromWindow, passing in the token of the window containing your edit field. This will force the keyboard to be hidden in all situations.


1 Answers

For anyone coming here in the future, I recommend not using KeyboardView. At least at the time of this writing (API 27), it hasn't been updated for a long time. The problem described in the question above is just one of its many shortcomings.

It is more work, but you can make your own custom view to use as a keyboard. I describe that process at the end of this answer.

When you create the popup preview window in your custom keyboard, you need to call popupWindow.setClippingEnabled(false) in order to get the popup window to display above the keyboard for Android API 22+. (Thanks to this answer for that insight.)

Here is an example in context from one of my recent projects.

private void layoutAndShowPopupWindow(Key key, int xPosition) {
    popupWindow = new PopupWindow(popupView,
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    popupWindow.setClippingEnabled(false);// <-- let popup display above keyboard
    int location[] = new int[2];
    key.getLocationInWindow(location);
    int measureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    popupView.measure(measureSpec, measureSpec);
    int popupWidth = popupView.getMeasuredWidth();
    int spaceAboveKey = key.getHeight() / 4;
    int x = xPosition - popupWidth / popupView.getChildCount() / 2;
    int y = location[1] - popupView.getMeasuredHeight() - spaceAboveKey;
    popupWindow.showAtLocation(key, Gravity.NO_GRAVITY, x, y);

    // using popupWindow.showAsDropDown(key, 0, yOffset) might be
    // easier than popupWindow.showAtLocation() 
}
like image 149
Suragch Avatar answered Sep 29 '22 13:09

Suragch