【问题标题】:Get specific drawable from state list drawable从状态列表drawable中获取特定的drawable
【发布时间】:2014-12-30 01:44:20
【问题描述】:

我有一个可绘制的状态列表,我想从可绘制的状态列表中获取特定的可绘制对象:

<?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)) .

【问题讨论】:

  • 你无法获取构成 StateListDrawable 的 Drawable
  • 我在想我可以使用 stateDrawable[0] 中的属性 id 来获取它们,你确定这不可能吗?:(
  • 你需要 id 做什么?我也不明白你为什么需要访问特定的 Drawable...
  • 我使用 ben75 解决方案解决了这个问题,工作正常,但我会对其进行监督,看看是否有变化。
  • 这个答案可以提供帮助并且不使用任何公共 Api:stackoverflow.com/a/25038966/8716371

标签: android android-layout android-drawable android-input-method statelistdrawable


【解决方案1】:

no public API 可以从状态中获取drawable。

StateListDrawable 中有一些方法,但它们是 @hide,带有注释“等待 API 委员会”

您可以通过反射调用它们...但是风险自负!!!。 (它可能会在未来的版本中改变)

这些方法是:

这里是如何继续(省略例外):

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

【讨论】:

  • 现在就像一个魅力。我将对此进行监督,看看将来是否会改变。
  • 谢谢你是天才!如果可能的话,我可以给你这些答案 100 分
  • 请注意,这不适用于 Android P,developer.android.com/preview/…
  • API 终于在 Android Q 中公开了
  • 效果很好!不过,使用非公共 API 有点令人担忧。反射调用的一个小建议是使用getDeclaredMethod(...) 而不仅仅是getMethod(...)。这会抛出 NoSuchMethodException(不确定这是否是 @hide 的副作用)
猜你喜欢
  • 1970-01-01
  • 2011-12-31
  • 2015-11-07
  • 2018-06-17
  • 2011-05-18
  • 2017-08-09
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多