Я собираюсь ответить на ваш вопрос "Как программно обновить селектор для КНОПКИ?" предлагая переключить кнопку на 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, расположенный в папке drawable. Вот содержимое файла селектора
<?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 вместо этого.