Например, кнопка по умолчанию имеет следующие зависимости между ее состояниями и фоновыми изображениями:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
Как я могу определить свое собственное состояние (что-то вроде android:state_custom
), чтобы я мог использовать его для динамического изменения внешнего вида моей кнопки?
Ответы:
Решение, обозначенное @ (Ted Hopp), работает, но требует небольшой поправки: в селекторе состояниям элементов требуется префикс «app:», иначе надувной модуль не распознает пространство имен правильно и не выполнит никаких действий; по крайней мере, это то, что происходит со мной.
Позвольте мне сообщить здесь все решение с некоторыми подробностями:
Сначала создайте файл res / values / attrs.xml:
Затем определите свой собственный класс. Например, это может быть класс «FoodButton», производный от класса «Button». Вам нужно будет реализовать конструктор; реализовать этот, который, похоже, используется надувным устройством:
Вверху производного класса:
Также ваши переменные состояния:
И пара сеттеров:
Затем переопределите функцию onCreateDrawableState:
Наконец, самая тонкая часть этой головоломки; селектор, определяющий StateListDrawable, который вы будете использовать в качестве фона для своего виджета. Это файл "res / drawable / food_button.xml":
Обратите внимание на префикс «app:», тогда как в стандартных состояниях Android вы бы использовали префикс «android:». Пространство имен XML имеет решающее значение для правильной интерпретации инфлятором и зависит от типа проекта, в который вы добавляете атрибуты. Если это приложение, замените com.mydomain.mypackage фактическим именем пакета вашего приложения (за исключением имени приложения). Если это библиотека, вы должны использовать «http://schemas.android.com/apk/res-auto» (и использовать Tools R17 или новее), иначе вы получите ошибки во время выполнения.
Пара замечаний:
Похоже, вам не нужно вызывать функцию «refreshDrawableState», по крайней мере, решение работает хорошо, в моем случае
Чтобы использовать свой собственный класс в XML-файле макета, вам нужно будет указать полное имя (например, com.mydomain.mypackage.FoodButton)
Вы можете смешивать стандартные состояния (например, android: нажат, android: включен, android: selected) с настраиваемыми состояниями, чтобы представить более сложные комбинации состояний.
источник
refreshDrawableState
определенно важно. Я не совсем уверен, когда это действительно нужно. Но в моем случае это понадобилось при программной настройке состояния. Я предполагаю, что он, возможно, автоматически вызывается из класса View в onTouchEvent. Лучше я добавлю это в метод setSelected.boolean
? Или селекторы работают только с логическими значениями?В этом потоке показано, как добавлять пользовательские состояния к кнопкам и т.п. (Если вы не можете увидеть новые группы Google в вашем браузере, есть копия нити здесь .)
источник
Пожалуйста, не забудьте позвонить
refreshDrawableState
в поток пользовательского интерфейса:Мне потребовалось много времени, чтобы понять, почему моя кнопка не меняет свое состояние, хотя все выглядит правильно.
источник