Android:如何以编程方式更新select器(StateListDrawable)
我想以编程方式更新button的select器。
我可以用下面给出的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"
。
提前致谢。
你需要使用所需状态的负值。 例如:
states.addState(new int[] {-android.R.attr.state_enabled},R.drawable.btn_disabled);
注意android.R.attr.state_enabled
之前的“ – ”符号。
在这里很晚的回应,但在其他人遇到问题以编程方式设置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));
没有足够的代表评论,但接受的答案不适合我。
我的目标是让devise师在某个button上设置启用,禁用和按下的背景颜色。 我打算让他们用它来testing不同显示器上的颜色。
我注意到其他一些人提到它也不适合他们。
需要定义的状态是
- 没有按下和启用,这是你看到,当button被启用,而没有按下。
- 按下并启用,这是您按下并启用button时所看到的内容
- 未启用。 这是button被禁用时所看到的内容
这里有一些代码会给你一个国家的想法。 我使用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; }
我将回答你的问题“如何以编程方式更新button的select器? 通过build议为embedded式ImageView
和TextView
切换LinearLayout
的button。 这样做有许多好处,特别是如果您稍后决定自定义视图。 这个开关不会导致function损失。 你仍然可以附加同样的事件监听器,你可以附加到一个button,但将能够避免button/标签造型的噩梦。 这是来自layout.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>
接下来,我有一个名为custom_image.xml的select器文件位于drawable文件夹中。 这是select器文件的内容
<?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>
三个源图像文件(disabled_img.png,unselected_img.png,selected_img.png)也位于绘图文件夹中。
现在回到你的Java代码。 由于多种原因,不需要时髦的StateListDrawable
垃圾。 首先,它看起来很丑,很难维护。 但最重要的是违背了保持逻辑与演示分离的原则。 如果你用Java代码来pipe理可绘制的资源,那么你知道你在做一些基本上是错误的事情。
这是我所提议的。 每当你想要你的button被选中,你只需在这里popup这一行:
((LinearLayout)findViewById(R.id.button)).setSelected(true);
或者,只要你想让button处于禁用状态,这里就是另外一个选项:
((ImageView)findViewById(R.id.background)).setEnabled(false);
请注意,在最后一个例子中,我在LinearLayout的ImageView中指定了禁用状态。 出于某种原因,无论何时更改LinearLayout的启用/禁用状态,都不会触发select器。 它可以正常工作,而不是在ImageView上。
我不知道如何添加StateListDrawable
,因为代码不在这里。 但一定要检查文档并添加setState()
。
您可以从View中设置属性,例如yourView.setEnabled(true)
我希望有帮助