我正在嘗試遵循 Google 關于在此處使用 KeyboardView.java 的建議:https : //developer.android.com/reference/android/inputmethodservice/KeyboardView
我復制并調整了 KeyboardView.java、Keyboard.java 和 com.android.internal.R 中被標記為已棄用的部分,并創建了一個帶有樣式定義的新 res/values/styles.xml 檔案。
一切都很好,但是當它顯示自定義鍵盤時,我得到一個空指標例外。我可以看到問題出在此處復制的 KeyboardView 代碼中(a.getIndexCount() 的計數為 0,因此 mKeyBackground 永遠不會設定并在呼叫“ mKeyBackground.getPadding(mPadding) ”時導致 null 例外)。我不知道我錯過了什么?:
public KeyboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a =
context.obtainStyledAttributes(
attrs, R.styleable.KeyboardView, defStyle, 0);
LayoutInflater inflate =
(LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int previewLayout = 0;
int keyTextSize = 0;
// n is set to 0
int n = a.getIndexCount();
// since n = 0, the loop is never entered
for (int i = 0; i < n; i ) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.KeyboardView_keyBackground:
// mKeyBackground is supposed to be set but isn't because n = 0
mKeyBackground = a.getDrawable(attr);
break;
case R.styleable.KeyboardView_verticalCorrection:
mVerticalCorrection = a.getDimensionPixelOffset(attr, 0);
break;
case R.styleable.KeyboardView_keyPreviewLayout:
previewLayout = a.getResourceId(attr, 0);
break;
case R.styleable.KeyboardView_keyPreviewOffset:
mPreviewOffset = a.getDimensionPixelOffset(attr, 0);
break;
case R.styleable.KeyboardView_keyPreviewHeight:
mPreviewHeight = a.getDimensionPixelSize(attr, 80);
break;
case R.styleable.KeyboardView_keyTextSize:
mKeyTextSize = a.getDimensionPixelSize(attr, 18);
break;
case R.styleable.KeyboardView_keyTextColor:
mKeyTextColor = a.getColor(attr, 0xFF000000);
break;
case R.styleable.KeyboardView_labelTextSize:
mLabelTextSize = a.getDimensionPixelSize(attr, 14);
break;
case R.styleable.KeyboardView_popupLayout:
mPopupLayout = a.getResourceId(attr, 0);
break;
}
}
// Get the settings preferences
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
mVibrateOn = sp.getBoolean(PREF_VIBRATE_ON, mVibrateOn);
mSoundOn = sp.getBoolean(PREF_SOUND_ON, mSoundOn);
mProximityCorrectOn = sp.getBoolean(PREF_PROXIMITY_CORRECTION, true);
mPreviewPopup = new PopupWindow(context);
if (previewLayout != 0) {
mPreviewText = (TextView) inflate.inflate(previewLayout, null);
mPreviewTextSizeLarge = (int) mPreviewText.getTextSize();
mPreviewPopup.setContentView(mPreviewText);
mPreviewPopup.setBackgroundDrawable(null);
} else {
mShowPreview = false;
}
mPreviewPopup.setTouchable(false);
mPopupKeyboard = new PopupWindow(context);
mPopupKeyboard.setBackgroundDrawable(null);
//mPopupKeyboard.setClippingEnabled(false);
mPopupParent = this;
//mPredicting = true;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(keyTextSize);
mPaint.setTextAlign(Align.CENTER);
mPadding = new Rect(0, 0, 0, 0);
mMiniKeyboardCache = new HashMap<Key,View>();
// Program crashes here from null pointer since mKeyBackground isn't set
mKeyBackground.getPadding(mPadding);
resetMultiTap();
initGestureDetector();
}
這是styles.xml檔案:
樣式檔案
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="KeyboardView" parent="android:Widget">
<item name="android:background">@color/black</item>
<item name="keyBackground">@drawable/background</item>
<item name="keyTextSize">22sp</item>
<item name="keyTextColor">@color/white</item>
<item name="keyPreviewLayout">@layout/preview</item>
<item name="keyPreviewOffset">-12dp</item>
<item name="keyPreviewHeight">80dp</item>
<item name="labelTextSize">14sp</item>
<item name="popupLayout">@layout/preview</item>
<item name="verticalCorrection">-10dp</item>
<!-- <item name="shadowColor">@android:color/transparent</item> -->
<!-- <item name="shadowRadius">2.75</item> -->
</style>
</resources>
這是我的原始 com.android.internal.R 副本(在 values/attrs.xml 中)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="KeyboardView">
<!-- Default KeyboardView style. -->
<attr name="keyboardViewStyle" format="reference" />
<!-- Image for the key. This image needs to be a StateListDrawable, with the following
possible states: normal, pressed, checkable, checkable pressed, checkable checked,
checkable checked pressed. -->
<attr name="keyBackground" format="reference" />
<!-- Size of the text for character keys. -->
<attr name="keyTextSize" format="dimension" />
<!-- Size of the text for custom keys with some text and no icon. -->
<attr name="labelTextSize" format="dimension" />
<!-- Color to use for the label in a key. -->
<attr name="keyTextColor" format="color" />
<!-- Layout resource for key press feedback. -->
<attr name="keyPreviewLayout" format="reference" />
<!-- Vertical offset of the key press feedback from the key. -->
<attr name="keyPreviewOffset" format="dimension" />
<!-- Height of the key press feedback popup. -->
<attr name="keyPreviewHeight" format="dimension" />
<!-- Amount to offset the touch Y coordinate by, for bias correction. -->
<attr name="verticalCorrection" format="dimension" />
<!-- Layout resource for popup keyboards. -->
<attr name="popupLayout" format="reference" />
<!-- <attr name="shadowColor" /> -->
<!-- <attr name="shadowRadius" /> -->
</declare-styleable>
<declare-styleable name="KeyboardViewPreviewState">
<!-- State for {@link android.inputmethodservice.KeyboardView KeyboardView}
key preview background. -->
<attr name="state_long_pressable" format="boolean" />
</declare-styleable>
<declare-styleable name="Keyboard">
<!-- Default width of a key, in pixels or percentage of display width. -->
<attr name="keyWidth" format="dimension|fraction" />
<!-- Default height of a key, in pixels or percentage of display width. -->
<attr name="keyHeight" format="dimension|fraction" />
<!-- Default horizontal gap between keys. -->
<attr name="horizontalGap" format="dimension|fraction" />
<!-- Default vertical gap between rows of keys. -->
<attr name="verticalGap" format="dimension|fraction" />
</declare-styleable>
<declare-styleable name="Keyboard_Row">
<!-- Row edge flags. -->
<attr name="rowEdgeFlags">
<!-- Row is anchored to the top of the keyboard. -->
<flag name="top" value="4" />
<!-- Row is anchored to the bottom of the keyboard. -->
<flag name="bottom" value="8" />
</attr>
<!-- Mode of the keyboard. If the mode doesn't match the
requested keyboard mode, the row will be skipped. -->
<attr name="keyboardMode" format="reference" />
</declare-styleable>
<declare-styleable name="Keyboard_Key">
<!-- The unicode value or comma-separated values that this key outputs. -->
<attr name="codes" format="integer|string" />
<!-- The XML keyboard layout of any popup keyboard. -->
<attr name="popupKeyboard" format="reference" />
<!-- The characters to display in the popup keyboard. -->
<attr name="popupCharacters" format="string" />
<!-- Key edge flags. -->
<attr name="keyEdgeFlags">
<!-- Key is anchored to the left of the keyboard. -->
<flag name="left" value="1" />
<!-- Key is anchored to the right of the keyboard. -->
<flag name="right" value="2" />
</attr>
<!-- Whether this is a modifier key such as Alt or Shift. -->
<attr name="isModifier" format="boolean" />
<!-- Whether this is a toggle key. -->
<attr name="isSticky" format="boolean" />
<!-- Whether long-pressing on this key will make it repeat. -->
<attr name="isRepeatable" format="boolean" />
<!-- The icon to show in the popup preview. -->
<attr name="iconPreview" format="reference" />
<!-- The string of characters to output when this key is pressed. -->
<attr name="keyOutputText" format="string" />
<!-- The label to display on the key. -->
<attr name="keyLabel" format="string" />
<!-- The icon to display on the key instead of the label. -->
<attr name="keyIcon" format="reference" />
<!-- Mode of the keyboard. If the mode doesn't match the
requested keyboard mode, the key will be skipped. -->
<attr name="keyboardMode" />
</declare-styleable>
</resources>
uj5u.com熱心網友回復:
本KeyboardView style,其中包含了默認值,不被使用。
雖然您可以在 XML 中手動設定每個值layout(如您在評論中所述),但像這樣
<your.package.name.KeyboardView
…
app:keyBackground="@drawable/bg_container"
…
/>
或者style直接設定整體,像這樣
<your.package.name.KeyboardView
…
style="@style/KeyboardView"
…
/>
每次使用時都需要設定這些值View。
更好的方法是在 中設定默認值KeyboardView.java:
public KeyboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.KeyboardView,
R.attr.keyboardViewStyle,
R.style.KeyboardView);
// …
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/375836.html
