Unable to implement KeyboardView after coping the code from AOSP. Error in xml
Asked Answered
P

1

4

After the KeyboardView is deprecated, I follow the google documentation and as they stated I copied the KeyboardView and Keyboard classes to my project. Everything I set-up as recommended.

The problem is when I run my app, it crashes by throwing an error of error inflating KeyboardView.

Here is my code.

public class SimpleKB extends InputMethodService implements
    KeyboardView.OnKeyboardActionListener {

private KeyboardView kv;
private Keyboard keyboard;
private Keyboard symbols;
private Keyboard eng_keyboard;

//Core overridden Functions
@Override public View onCreateInputView() {
    kv = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard, null);
    keyboard = new Keyboard(this, R.xml.qwerty);
    symbols = new Keyboard(this, R.xml.symbol);
    eng_keyboard = new Keyboard(this, R.xml.eng_qwerty);
    kv.setKeyboard(keyboard);
    kv.setOnKeyboardActionListener(this);
    return kv;
}

@Override public void onInitializeInterface() {
    if (keyboard != null) {
        // Configuration changes can happen after the keyboard gets recreated,
        // so we need to be able to re-build the keyboards if the available
        // space has changed.
        int displayWidth = getMaxWidth();
        if (displayWidth == mLastDisplayWidth) return;
        mLastDisplayWidth = displayWidth;
    }
    keyboard = new Keyboard(this, R.xml.qwerty);
}

Here is CandidateView class for showing suggested words.

public class CandidateView extends View {

private static final int OUT_OF_BOUNDS = -1;

private SimpleKB mService;
private List<String> mSuggestions;
private int mSelectedIndex;
private int mTouchX = OUT_OF_BOUNDS;
private Drawable mSelectionHighlight;
private boolean mTypedWordValid;

private Rect mBgPadding;

private static final int MAX_SUGGESTIONS = 32;
private static final int SCROLL_PIXELS = 20;

private int[] mWordWidth = new int[MAX_SUGGESTIONS];
private int[] mWordX = new int[MAX_SUGGESTIONS];

private static final int X_GAP = 10;

private static final List<String> EMPTY_LIST = new ArrayList<String>();

private int mColorNormal;
private int mColorRecommended;
private int mColorOther;
private int mVerticalPadding;
private Paint mPaint;
private boolean mScrolled;
private int mTargetScrollX;

private int mTotalWidth;

private GestureDetector mGestureDetector;



/**
 * Construct a CandidateView for showing suggested words for completion.
 * @param context
 */
public CandidateView(Context context) {
    super(context);
    mSelectionHighlight = context.getResources().getDrawable(
            android.R.drawable.list_selector_background);
    mSelectionHighlight.setState(new int[] {
            android.R.attr.state_enabled,
            android.R.attr.state_focused,
            android.R.attr.state_window_focused,
            android.R.attr.state_pressed
    });

    Resources r = context.getResources();

    setBackgroundColor(r.getColor(R.color.candidate_background));

    mColorNormal = r.getColor(R.color.candidate_normal);
    mColorRecommended = r.getColor(R.color.candidate_recommended);
    mColorOther = r.getColor(R.color.candidate_other);
    mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding);

    mPaint = new Paint();
    mPaint.setColor(mColorNormal);
    mPaint.setAntiAlias(true);
    mPaint.setTextSize(r.getDimensionPixelSize(R.dimen.candidate_font_height));
    mPaint.setStrokeWidth(0);

    mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
            mScrolled = true;
            int sx = getScrollX();
            sx += distanceX;
            if (sx < 0) {
                sx = 0;
            }
            if (sx + getWidth() > mTotalWidth) {
                sx -= distanceX;
            }
            mTargetScrollX = sx;
            scrollTo(sx, getScrollY());
            invalidate();
            return true;
        }
    });
    setHorizontalFadingEdgeEnabled(true);
    setWillNotDraw(false);
    setHorizontalScrollBarEnabled(false);
    setVerticalScrollBarEnabled(false);
}

And here is my xml layout with have my custom KeyboardView.

<?xml version="1.0" encoding="UTF-8"?>
<com.android.urdu.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:keyTextSize="15sp"
android:layout_alignParentBottom="true"
android:keyPreviewLayout="@layout/preview" />

This is the error I get.

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.urdu, PID: 17584
android.view.InflateException: Binary XML file line #2 in com.android.urdu:layout/keyboard: Binary XML file line #2 in com.android.urdu:layout/keyboard: Error inflating class com.android.urdu.KeyboardView
Caused by: android.view.InflateException: Binary XML file line #2 in com.android.urdu:layout/keyboard: Error inflating class com.android.urdu.KeyboardView
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
    at android.view.LayoutInflater.createView(LayoutInflater.java:858)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1014)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:663)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:538)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:481)
    at com.android.urdu.SimpleKB.onCreateInputView(SimpleKB.java:62)
    at android.inputmethodservice.InputMethodService.updateInputViewShown(InputMethodService.java:1531)
    at android.inputmethodservice.InputMethodService.prepareWindow(InputMethodService.java:1961)
    at android.inputmethodservice.InputMethodService.showWindow(InputMethodService.java:1908)
    at android.inputmethodservice.InputMethodService$InputMethodImpl.showSoftInput(InputMethodService.java:643)
    at android.inputmethodservice.IInputMethodWrapper.executeMessage(IInputMethodWrapper.java:220)
    at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:44)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:224)
    at android.app.ActivityThread.main(ActivityThread.java:7561)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.drawable.Drawable.getPadding(android.graphics.Rect)' on a null object reference
    at com.android.urdu.KeyboardView.<init>(KeyboardView.java:278)
    at com.android.urdu.KeyboardView.<init>(KeyboardView.java:200)
    at java.lang.reflect.Constructor.newInstance0(Native Method) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
    at android.view.LayoutInflater.createView(LayoutInflater.java:858) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1014) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:663) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:538) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:481) 
    at com.android.urdu.SimpleKB.onCreateInputView(SimpleKB.java:62) 
    at android.inputmethodservice.InputMethodService.updateInputViewShown(InputMethodService.java:1531) 
    at android.inputmethodservice.InputMethodService.prepareWindow(InputMethodService.java:1961) 
    at android.inputmethodservice.InputMethodService.showWindow(InputMethodService.java:1908) 
    at android.inputmethodservice.InputMethodService$InputMethodImpl.showSoftInput(InputMethodService.java:643) 
    at android.inputmethodservice.IInputMethodWrapper.executeMessage(IInputMethodWrapper.java:220) 
    at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:44) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:224) 
    at android.app.ActivityThread.main(ActivityThread.java:7561) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995) 

Please tell me what I'm missing in this. I need help with it.

Park answered 17/2, 2021 at 9:38 Comment(1)
Did you resolved the issue??Burnedout
S
1

The relevant portion of the stacktrace is found as the last cause:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.drawable.Drawable.getPadding(android.graphics.Rect)' on a null object reference
   at com.android.urdu.KeyboardView.<init>(KeyboardView.java:278)
   at com.android.urdu.KeyboardView.<init>(KeyboardView.java:200)

This basically means that the keyBackground attribute was not set.

mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground)
mKeyBackground.getPadding(mPadding)

The reason for this is, that you defined new attributes for the KeyboardView, while keyboardViewStyle only configures the framework attributes. So you'll have to provide your own default values for the required attributes.

Surber answered 19/4, 2021 at 10:58 Comment(2)
I copied the attributes from https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/attrs.xml#8019 But still facing the same issue. Any idea please.Burnedout
@VijayadhasChandrasekaran did you manage to fix this issue?Luciano

© 2022 - 2024 — McMap. All rights reserved.