Android:如何以编程方式更新选择器(StateListDrawable)

时间:2011-02-23 15:04:35

标签: android button state

我想以编程方式更新按钮的选择器。

我可以使用下面给出的xml文件执行此操作

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:drawable="@drawable/btn_off" />
   <item android:state_pressed="true"
         android:state_enabled="true" 
         android:drawable="@drawable/btn_off" />
   <item android:state_focused="true"
         android:state_enabled="true" 
         android:drawable="@drawable/btn_on" />
   <item android:state_enabled="true" 
         android:drawable="@drawable/btn_on" />
</selector>

我想以编程方式执行相同的操作。我尝试了下面给出的东西

private StateListDrawable setImageButtonState(int index)
{
    StateListDrawable states = new StateListDrawable();

    states.addState(new int[] {android.R.attr.stateNotNeeded},R.drawable.btn_off); 
    states.addState(new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled},R.drawable.btn_off);
    states.addState(new int[] {android.R.attr.state_focused, android.R.attr.state_enabled},R.drawable.btn_on);
    states.addState(new int[] {android.R.attr.state_enabled},R.drawable.btn_on);

    return states;
}

但它没有用。

如何以编程方式设置android:state_enabled="false"android:state_enabled="true"

5 个答案:

答案 0 :(得分:109)

您需要使用所需状态的负值。 E.g:

states.addState(new int[] {-android.R.attr.state_enabled},R.drawable.btn_disabled);

注意android.R.attr.state_enabled之前的“ - ”符号。

答案 1 :(得分:8)

此处响应非常晚,但是如果其他人在以编程方式设置StateListDrawable时遇到问题。然后与XML文件一样,将状态设置为StateListDrawable的顺序非常重要。

例如,这将按预期工作:

StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.GRAY));
sld.addState(new int[] {}, new ColorDrawable(Color.GREEN));

这不会:

StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] {}, new ColorDrawable(Color.GREEN));
sld.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.GRAY));

答案 2 :(得分:6)

评论不够,但接受的答案对我不起作用。

我的目标是让设计师在某个按钮上设置启用,禁用和按下的背景颜色。我打算让他们用它来测试不同显示器上的颜色。

我注意到其他一些人提到它也不适用于他们。

需要定义的状态是

  • 未按下并启用,这是按钮启用但未按下时所看到的内容。
  • 按下并启用,这是按下并启用按钮时看到的内容
  • 未启用。这是您在禁用按钮时看到的内容

这里有一些代码可以让你了解状态。我正在使用Color.Parse()为颜色生成int,然后我将它们传递给此方法以获取StateListDrawable。

private StateListDrawable createDrawable(int enabled, int pressed, int disabled) {
  StateListDrawable stateListDrawable = new StateListDrawable();

  stateListDrawable.addState(new int[] { -android.R.attr.state_pressed, android.R.attr.state_enabled }, new ColorDrawable(enabled));
  stateListDrawable.addState(new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled }, new ColorDrawable(pressed));
  stateListDrawable.addState(new int[] { -android.R.attr.state_enabled }, new ColorDrawable(disabled));

  return stateListDrawable;
}

答案 3 :(得分:4)

我将回答您的问题“如何以编程方式更新BUTTON的选择器?”建议切换嵌入了LinearLayoutImageView的{​​{1}}按钮。这样做有很多好处,特别是如果您稍后决定自定义您的视图。此切换不会导致功能丢失。您仍然可以附加可以附加到按钮的相同事件侦听器,但是可以避免按钮/标签样式化噩梦。这是layout.xml的相关代码

TextView

接下来,我在drawable文件夹中有一个名为custom_image.xml的选择器文件。以下是选择器文件的内容

    <LinearLayout 
        android:id="@+id/button"
        style="@style/ButtonStyle">
        <ImageView 
            android:id="@+id/background"
            android:src="@drawable/custom_image"/>
        <TextView 
            style="@style/TextStyle"
            android:text="Custom Button"
            android:id="@+id/text"/>
    </LinearLayout> 

三个源图像文件(disabled_img.png,unselected_img.png,selected_img.png)也位于drawable文件夹中。

现在回到您的Java代码。出于多种原因,不需要时髦的<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/disabled_img" android:state_enabled="false" /> <item android:drawable="@drawable/unselected_img" android:state_selected="false" /> <item android:drawable="@drawable/selected_img" android:state_selected="true" /> </selector> 垃圾。首先,它看起来很丑陋,很难维护。但最重要的是,它违背了将逻辑与演示文稿分开的原则。如果您使用Java代码管理可绘制资源,那么您知道自己正在做一些基本错误的事情。

这是我提出的建议。每当你想要选择你的按钮时,你只需在那里弹出这个单行:

StateListDrawable

或者,当您希望按钮处于禁用状态时,这是另一个单行:

((LinearLayout)findViewById(R.id.button)).setSelected(true);

请注意,在最后一个示例中,我在LinearLayout内的ImageView上指定了禁用状态。由于某种原因,每当您更改LinearLayout的启用/禁用状态时,都不会触发选择器。相反,它在ImageView上运行时效果很好。

答案 4 :(得分:0)

我不知道你是如何添加StateListDrawable的,因为代码不在这里。但请务必检查the documentation并添加setState()

您可以在视图中设置属性,例如yourView.setEnabled(true)

我希望有帮助