Не удалось внедрить KeyboardView после копирования кода из AOSP. Ошибка в xml

После того, как KeyboardView устарел, я следую документации Google, и, как они заявили, я скопировал классы KeyboardView и Keyboard в свой проект. Все, что я устанавливаю, как рекомендуется.

Проблема в том, что когда я запускаю свое приложение, оно падает из-за ошибки error inflating KeyboardView.

Вот мой код.

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);
}

Вот класс CandidateView для отображения предлагаемых слов.

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);
}

А вот мой макет xml с моим пользовательским 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" />

Это ошибка, которую я получаю.

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) 

Пожалуйста, скажите мне, что мне не хватает в этом. Мне нужна помощь в этом.


person Nabeel Ahmed    schedule 17.02.2021    source источник


Ответы (1)


Соответствующая часть трассировки стека находится как последняя причина:

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)

В основном это означает, что атрибут keyBackground не был установлен.

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

Причина этого в том, что вы определили новые атрибуты для KeyboardView, а keyboardViewStyle настраивает только атрибуты фреймворка. Таким образом, вам придется указать свои собственные значения по умолчанию для необходимых атрибутов.

person tynn    schedule 19.04.2021