-
Notifications
You must be signed in to change notification settings - Fork 31
FormatWatcher и форматирование в EditText "на лету"
В ситуациях, когда необходимо форматировать текст в TextView "на лету", например во время ввода пользователем
текста в EditText
, нам необходимо постоянно модифицировать текст внутри маски. Для этой цели используется
абстрактный класс FormatWatcher
(aka форматтер). Класс создержит внутри маску и синхронизирует содержмое TextView
с ней.
Он инкапсулирует создание маски и работу с ней. Создание маски не
определено в базовом классе и дожно быть реализовано в наследниках. Форматтер устанавливается на
TextView
и отслеживает изменения текста с помощью механизма TextWatcher
.
ВАЖНО: не рекомендуется ипользование форматтера вместе с другими TextWatcher'ами. Для
получения оповещений об изменении текста в TextView
можно использовать FormattedTextChangeListener
.
Он устанавливается на форматтер методом FormatWatcher#setCallback(FormattedTextChangeListener)
.
В Decoro предоставлены две реализации FormatWatcher
: DescriptorFormatWatcher
и MaskFormatWatcher
.
В настоящее время DescriptorFormatWatcher
считается устарешвшим и оставлен в библиотеке только в целях
совместимости. Для форматирования "на лету" рекомендуется использовать MaskFormatWatcher
, т.к. он предоставляет
наиболее удобный интерфейс.
Внутренне устройство обоих форматтеров отличается только механизмом создания маски. Само форматирование происходит одинаково.
Маска для этого форматтера создается на основе MaskDescriptor
и (при необходимости) SlotsParser
.
Для корректной работы DescriptorFormatWatcher
требуется указать как минимум MaskDescriptor
. Сделать это
необходимо до установки форматтера на TextView
- в конструкторе или
с помощью метода DescriptorFormatWatcher#changeMask(MaskDescriptor)
(с помощью этого метода можно
также сменить маску после установки watcher'a).
Если указанный MaskDescriptor
содержит массив слотов, то его достаточно для создания маски. Если же
в декрипторе указана только raw-маска, то для создания маски потребуется предоставить SlotsParser
.
Сделать это можно либо в конструкторе DescriptorFormatWatcher
, либо с помощью метода
DescriptorFormatWatcher#setSlotsParser(SlotsParser)
.
FormatWatcher formatWatcher = new DescriptorFormatWatcher(
new UnderscoreDigitSlotsParser(),
MaskDescriptor.ofRawMask("___ ___ ___", true).withShowingEmptySlots(true)
);
formatWatcher.installOn(editText);
editText.setText("123456");
System.out.println(editText.getText()); // 123 456 ___
editText.getText().insert(0, "789");
System.out.println(editText.getText()); // 789 123 456
С появлением в версии 1.1 конструктора копирования для MaskImpl
появилась возможность не использовать
MaskDescriptor
для корректной работы форматтера. Новый класс MaskFormatWatcher
позволяет пересоздавать маску на
основе уже существующей, что дклает работу форматтера более явной. Для работы MaskFormatWatcher
необходимо вручную
создать маску (см. Создание маски) и передать ее форматтеру.
Slot[] slots = new UnderscoreDigitSlotsParser().parseSlots("___ ___ ___");
Mask mask = MaskImpl.createTerminated(slots);
mask.setShowingEmptySlots(true);
FormatWatcher formatWatcher = new MaskFormatWatcher(mask);
formatWatcher.installOn(editText);
editText.setText("123456");
System.out.println(editText.getText()); // 123 456 ___
editText.getText().insert(0, "789");
System.out.println(editText.getText()); // 789 123 456