Skip to content

Создание маски

Mikhail Artemev edited this page Oct 28, 2016 · 2 revisions

Создать маску можно несколькими способами:

  1. Фабричными методами MaskImpl#createTerminated(Slot[]) и Mask#createNonTeminated(Slot[]);
  2. С помощью конструктора MaskImpl#MaskImpl(Slot[], boolean);
  3. Скопировать существующую маску с помощью конструкторов копирования MaskImpl#MaskImpl(MaskImpl) и MaskImpl#MaskImpl(MaskImpl, boolean)*.
  4. С помощью реализации интерфейса MaskFactory, например MaskFactoryImpl.
  5. (Устаревший способ) Если маска используется вместе DescriptorFormatWatcher, то явное создание Mask не требуется. Вместо этого необходимо создать экземпляр MaskDescriptor (см. ниже).

* Конструктор копирования по умолчанию выставит флаг терминированности в то же самое значение, что и у оригинальной маски. Изменить это поведение может конструктор MaskImpl#MaskImpl(MaskImpl, boolean). Вторым аргументом является флаг новый флаг терминированности. Других допустимых способов изменить признак терминированности существующей маски нет.

Парсер слотов (SlotParser.java)

Для создания маски необходимо иметь массив слотов. Но часто приходится создавать маску из некоторого строкового представления (raw-строки). Примером такого строкового представления могут быть +7 (___) ___-__-__ и DD.MM.YYYY. Чтобы иметь возможность создания маски из строки используется интерфейс SlotsParser. Он позволяет конвертировать строковое представление маски в массив слотов, которым умеет оперирровать маска.

public interface SlotsParser {
    Slot[] parseSlots(CharSequence rawMask);
}

В модуле предусмотрены две его реализации: UnderscoreDigitSlotsParser и PhoneNumberUnderscoreSlotsParser .

  • UnderscoreDigitSlotsParser создает массив слотов, заменяя _ на слоты для ввода цифры, а остальные символы на hardcoded-слоты.
  • PhoneNumberUnderscoreSlotsParser работает также, как и предыдущий парсер, но с одной особенностью: Первая hardcoded цифра будет имет парвило RULE_REPLACE. Например, в маске +369 (___) __-__-__ цифра 3 будет иметь флаг RULE_REPLACE. Это необходимо для корректного форматирования, когда ввод производится в пустой EditText. Если пользователь введет цифру 3, будет автоматически отображение строки +369 ( и курсор будет установлен после (. Если же пользователь вводит первым символом 6 или 9 - будет отображено +369 (6 или +369 (9 соответственно. Также PhoneNumberUnderscoreSlotsParser помечает все hardcoded символы кроме цифр и + как декоративные (см. Что такое лот).

MaskDescriptor

Класс используется совместно с DescriptorFormatWatcher для (пере)создания маски.

В настоящий момент использование DescriptorFormatWatcher и считается устаревшим. Поддержка данных классов оставлена в целях совместимости.

Поскольку маска хранит введенные в нее символы и позволяет получать форматированный или неформатированный ввод, пересоздание маски является частой операцией при использовании FormatWatcher. Для облегчения процесса создания маски и сохранения параметров будущей маски (слоты, форматные строки и флаги) используется класс MaskDescriptor. Сущности данного класса можно использовать для задания маски в DescriptorFormatWatcher (см. раздел о форматировании на "лету") или создания маски с помощью MaskFactoryImpl.

MaskDescriptor может хранить как массив слотов для создания маски, так и raw-маску (строковое представление). Во втором случае для создания маски из дескриптора понадобится также SlotsParser. Если для дескриптора указаны оба - массив слотов и raw-маска, то приоритет имеет массив слотов (для создания маски из такого дескриптора не понадобится SlotsParser). Также MaskDescriptor хранит все дополнительные параметры для маски.

Пример 1. Использование MaskDescriptor

MaskDescriptor descriptor = MaskDescriptor.ofRawMask("+7 ___ ___-__-__")
        .withShowingEmptySlots(true)
        .withEmptySlotPalceholder('*')
        .withForbiddingInputWhenFilled(true)
        .withTermination(true)
        .withHideHardcodedHead(true)
        .withInitialValue("999");    // значение, которое будет предустановлено в маску, при ее создании

FormatWatcher watcher = new DescriptorFormatWatcher(
    new PhoneNumberUnderscoreSlotsParser(),
    descriptor
);
watcher.installOn(editText);

Кроме слотов (в виде массива или raw-строки) остальные параметры дескриптора являются необязательными.