我有一个状态列表drawable,我想从状态列表dravable中获得一个特定的drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:kplus="http://schemas.android.com/apk/res-auto">
<item kplus:key_type_space_alt="true" android:state_pressed="true" android:drawable="@drawable/space_1_pressed" />
<item kplus:key_type_space_alt="true" android:drawable="@drawable/space_1_normal" />
<!-- TopNav keys. -->
<item kplus:key_type_topnav="true" android:state_pressed="true" android:drawable="@drawable/tab_down" />
<item kplus:key_type_topnav="true" android:state_selected="true" android:drawable="@drawable/tab_down" />
<item kplus:key_type_topnav="true" android:drawable="@drawable/tab_normal" />
<!-- TopRow keys. -->
<item kplus:key_type_toprow="true" android:state_pressed="true" android:drawable="@drawable/numeric_presseed" />
<item kplus:key_type_toprow="true" android:drawable="@drawable/numeric_normal" />
</selector>
我为每个键选择正确的可绘制状态,类似于这样:
if (keyIsNumbers) {
if (KPlusInputMethodService.sNumbersState == 2) {
drawableState = mDrawableStatesProvider.KEY_STATE_TOPNAV_CHECKED;
}
}
现在状态定义如下:
KEY_STATE_TOPNAV_NORMAL = new int[] {keyTypeTopNavAttrId};
KEY_STATE_TOPNAV_PRESSED = new int[] {keyTypeTopNavAttrId, android.R.attr.state_pressed};
KEY_STATE_TOPNAV_CHECKED = new int[] {keyTypeTopNavAttrId, android.R.attr.state_selected};
现在我的问题是如何提取每个州的正确绘图?我需要获得drawable的9patch填充,因为如果状态在9patch上有不同的填充,它将只为顶部drawable获得填充,并且我想为每个键手动设置填充(drawable.getPadding(rect))。
没有公共的API可以从状态获取drawable。
StateListDrawable
中有一些方法,但它们是@hide
,注释"待定的API理事会"。
你可以通过反思来调用它们。。。但风险自负。(可能会在未来版本中更改)
这些方法是:
- getStateDrawableIndex
- getStateDrawable
以下是如何进行(省略例外):
int[] currentState = view.getDrawableState();
StateListDrawable stateListDrawable = (StateListDrawable)view.getBackground();
Method getStateDrawableIndex = StateListDrawable.class.getMethod("getStateDrawableIndex", int[].class);
Method getStateDrawable = StateListDrawable.class.getMethod("getStateDrawable", int.class);
int index = (int) getStateDrawableIndex.invoke(stateListDrawable,currentState);
Drawable drawable = (Drawable) getStateDrawable.invoke(stateListDrawable,index);
现在它是在没有反射的情况下获得特定可绘制内容的方法:
StateListDrawable pressedDrawable = (StateListDrawable) this.mPressed;
final int state = android.R.attr.state_pressed;
final int index = pressedDrawable.findStateDrawableIndex(new int[]{state});
if (index >= 0) {
Drawable drawable = pressedDrawable.getStateDrawable(index);
if (drawable instanceof GradientDrawable) {
((GradientDrawable) drawable).setCornerRadius(mRoundConerRadius);
}
}