Как применить кастомный атрибут?

Посмотреть в Telegram: @AndroidSobes/82
Когда view создается системой из xml, параметром в ее конструктор передается объект класса AttributeSet.

AttributeSet содержит в себе значения атрибутов view, которые задаются в xml. Значения можно получить из AttributeSet напрямую, но это не рекомендуется делать, потому что в этом случае не резолвятся ссылки на ресурсы и не применяются значения стилей.
Для получения значений атрибутов следует использовать метод obtainStyledAttributes().

obtainStyledAttributes() принимает параметрами:

• объект AttributeSet, который был передан в конструктор view. Этот параметр может быть null;
• массив интов attrs, содержащий IDs атрибутов, значения которых нужно получить. С примером из предыдущего поста это будет ID элемента <declare-styleable>: R.styleable.ValidatableInput;
• переменную defStyleAttr типа int, являющуюся ID атрибута в текущей теме, который содержит ссылку на style. Значения из этого стиля будут использованы как дефолтные для атрибутов, которых нет в объекте AttributeSet. Если этот параметр имеет значение 0, то система не будет его использовать.
• переменную defStyleRes типа int, являющуюся ID ресурса style, который будет использоваться для дефолтных значений. По сути предыдущий параметр defStyleAttr является ссылкой на ресурс стиля, который может быть передан напрямую параметром defStyleRes. Этот параметр рассматривается только если defStyleAttr = 0. defStyleRes также может принимать значение 0.
Метод obtainStyledAttributes() читает значения атрибутов, запрашиваемых в параметре attrs. obtainStyledAttributes() берет значения из первого источника, в котором они заданы. Приоритет источников следующий:

1. Объект AttributeSet;
2. Style, заданный в AttributeSet (в случае если в xml для view задан атрибут @style/...);
3. Дефолтное значение в стиле, заданном параметром defStyleAttr или defStyleRes;
4. Значения в объекте Theme, на котором вызван obtainStyledAttributes().

obtainStyledAttributes() возвращает объект типа TypedArray, являющийся контейнером для полученных значений атрибутов. TypedArray имеет методы get...(), принимающие IDs атрибутов. После использования объекта TypedArray, необходимо вызывать метод recycle(), который освобождает TypedArray и позволяет системе переиспользовать уже созданный объект.

Подробный разбор кастомных атрибутов.