Ответ 1
Вам нужно использовать отрицательное значение необходимого состояния. Например:.
states.addState(new int[] {-android.R.attr.state_enabled},R.drawable.btn_disabled);
Обратите внимание на знак "-" перед android.R.attr.state_enabled
.
Я хочу программно изменить селектор кнопки.
Я могу сделать это с помощью 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));
Недостаточно комментариев для комментариев, но принятый ответ не помог мне.
Моя цель состояла в том, чтобы дизайнеры установили разрешенные, отключенные и нажатые цвета фона на некоторой кнопке. Я намеревался использовать их для проверки цветов на разных дисплеях.
Я заметил, что некоторые другие люди упомянули, что это тоже не сработало для них.
Состояние, которое необходимо определить,
Вот какой код, который даст вам представление о состояниях. Я использую Color.Parse() для генерации ints для цветов, затем передаю их этому методу, чтобы получить 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?" предлагая переключить кнопку для LinearLayout
со встроенными ImageView
и TextView
. Для этого есть ряд преимуществ, особенно если позже вы решите настроить свои представления. В результате этого коммутатора нет потери функциональности. Вы по-прежнему сможете присоединять тех же прослушивателей событий, которые вы можете прикрепить к кнопке, но сможете избежать кошмаров кнопок/вкладок. Вот соответствующий код из 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, расположенный в папке с возможностью переноса. Вот содержимое селекторного файла
<?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-коде, вы знаете, что делаете что-то фундаментально неправильно.
Вот что я предлагаю вместо этого. Всякий раз, когда вы хотите, чтобы ваша кнопка была выбрана, вы просто вставляете этот однострочный шрифт:
((LinearLayout)findViewById(R.id.button)).setSelected(true);
Или, когда вы хотите, чтобы кнопка находилась в отключенном состоянии, вот еще один лайнер:
((ImageView)findViewById(R.id.background)).setEnabled(false);
Обратите внимание, что в этом последнем примере я указываю отключенное состояние в ImageView внутри LinearLayout. По какой-то причине, когда вы меняете состояние включения/отключения LinearLayout, селектор не запускается. Он отлично работает, когда вы делаете это на ImageView.
Я не знаю, как вы добавляете StateListDrawable
, так как кода здесь нет. Но обязательно проверьте документацию и добавьте setState()
.
Вы можете установить свойства из представления, например yourView.setEnabled(true)
Я надеюсь, что это поможет