gifts2017

Сказ о том, как мы мобильное приложение писали. Часть 2. Обработка долгого нажатия

Опубликовал Вадим Невзоров (vadnevzorov) в раздел Программирование - Мобильные приложения

Делимся опытом, как мы обходим ограничения мобильной платформы.

Эта публикация – вторая из цикла статей о создании простого приложения для мобильной торговли - Контейнер (Google Play и App Store). Что такое Контейнер, почему оно так называется и как мы боролись с двойным заголовком, мы рассказали в первой статье:

Сказ о том, как мы мобильное приложение писали. Часть 1. Двойной заголовок

А сегодня мы расскажем, как в 1С отловить событие долгого нажатия на строку табличной части. Для простоты будем называть его долгим тапом, или просто тапом (от слова tap – касание). По сравнению с первой частью эта статья уже более техническая, поэтому здесь не будет веселых фотографий розовых контейнеров. Ну а что вы хотели – мы в первую очередь разработчики, а не маркетологи. :)

Проблема

В 1С невозможно отловить событие долгого тапа. Данное пожелание уже звучало на партнерском форуме, но разработчики платформы не планируют его реализовывать, т.к. долгий тап не принято использовать на iOS.

 

На самом деле в мобильной платформе долгий тап есть. Если просто нажать на строку, то сразу происходит ее открытие, но если нажать и держать – то строка подсвечивается синим и ничего не происходит. Это сделано, чтобы пользователь мог выделить строку для выполнения дальнейших действий – например, сдвинуть или удалить. Проблема в том, что разработчик не может переопределить это поведение, и, например, показать пользователю контекстное меню с вариантами действий.

Не может? Ой, да шо вы говорите!

Решение

Как известно, при обычном нажатии на строку срабатывает событие Выбор, и строка открывается. Если строку просто выделить, то сработает событие ПриАктивизацииЯчейки. Казалось бы – что мешает поместить наш код в это событие? Не всё так просто – оно срабатывает не только при выделении, но и при нажатии. Когда мы нажимаем на строку – она на мгновение выделяется (это можно увидеть невооруженным глазом), а потом уже открывается.

Итак, что мы имеем? При долгом тапе отрабатывает только ПриАктивизацииЯчейки, при коротком – ПриАктивизацииЯчейки и Выбор. Вывод напрашивается сам собой – если сработали оба события – значит это Выбор, если сработала только Активизация – значит это долгий тап.

Как мы будем это определять? Напрашивается простой вариант – у формы завести переменную ДолгийТап с типом булево, в событии ПриАктивизацииЯчейки устаналивать ее в Истину, а в Выборе в Ложь. При этом в Активизации подключить Обработчик ожидания, который через полсекунды проверяет – если ДолгийТап = Истина, тогда показываем пользователю меню, если Ложь – тогда ничего не делаем.
Сказано – сделано. Пишем код:

&НаКлиенте
Перем ДолгийТап;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ДолгийТап = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура КлиентыПриАктивизацииЯчейки(Элемент)
	
	ДолгийТап = Истина;
	ПодключитьОбработчикОжидания("Подключаемый_ПроверитьДолгийТап", 0.5, Истина);
	
КонецПроцедуры


&НаКлиенте
Процедура КлиентыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	ДолгийТап = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПроверитьДолгийТап()
	
	Если ДолгийТап Тогда
		Предупреждение("Это долгий тап!");
	КонецЕсли;
	
КонецПроцедуры

Открываем форму на телефоне – и при открытии сразу же выскакивает наше предупреждение. Как так, мы ведь даже ничего не нажали? Это связано с тем, что при открытии формы первая строка таблицы активизируется и 1С думает, что это долгий тап.
Есть еще один неприятный эффект – долгий тап не срабатывает для уже выделенной строки. То есть если тапнуть по строке, откроется меню, пользователь его закроет и снова тапнет – то второй раз меню не откроется. Такое происходит потому, что событие ПриАктивизацииЯчейки не вызывается второй раз для выделенной строки.

Впрочем, даже в таком варианте этим пользоваться можно. Но “можно” нас не устраивает, поэтому мы продолжаем эксперименты.

Если присмотреться, то корень обеих проблем кроется в выделенной строке. Значит, сделаем так – будем очищать выделенные строки везде, кроме обработчика Активизации, а в обработчике ожидания поставим проверку на выделенные строки. Если выделенные строки есть – значит, Активизации сработала, а Выбор – нет, следовательно, это долгий тап. Пишем алгоритм:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Элементы.Клиенты.ВыделенныеСтроки.Очистить();
	
КонецПроцедуры

&НаКлиенте
Процедура КлиентыПриАктивизацииЯчейки(Элемент)
	
	ПодключитьОбработчикОжидания("Подключаемый_ПроверитьВыделенныеСтроки", 0.5, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура КлиентыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	Элементы.Клиенты.ВыделенныеСтроки.Очистить();
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПроверитьВыделенныеСтроки()
	
	Если Элементы.Клиенты.ВыделенныеСтроки.Количество() <> 0 Тогда
		Предупреждение("Это долгий тап!");
		Элементы.Клиенты.ВыделенныеСтроки.Очистить();
	КонецЕсли;
	
КонецПроцедуры

Проверяем – первая проблема осталась. При открытии формы первая строка всё равно остается выделенной (и срабатывает долгий тап), как будто вызов процедуры принудительной очистки строк игнорируется платформой. Причем то же поведение наблюдается и в настольной версии.

Зато вторая проблема решилась – несмотря на то, что после открытия формы строки сама строка визуально остается выделенной, повторный тап по ней срабатывает и выполняется наш обработчик.

Подумаем над первой проблемой. Здесь есть несколько вариантов обхода, но мы остановились на следующей реализации: заведем переменную формы ЛожноеВыделение с типом булево и при открытии будем присваивать ей Истину, а в событии Активизации пропишем, что если это ложное выделение – то выделенные строки очищаются и ничего не происходит. Пробуем:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ЛожноеВыделение = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура КлиентыПриАктивизацииЯчейки(Элемент)
	
	Если ЛожноеВыделение Тогда
		Элементы.Клиенты.ВыделенныеСтроки.Очистить();
		ЛожноеВыделение = Ложь;
	Иначе
		ПодключитьОбработчикОжидания("Подключаемый_ПроверитьВыделенныеСтроки", 0.5, Истина);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура КлиентыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	Элементы.Клиенты.ВыделенныеСтроки.Очистить();
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПроверитьВыделенныеСтроки()
	
	Если Элементы.Клиенты.ВыделенныеСтроки.Количество() <> 0 Тогда
		Предупреждение("Это долгий тап!");
		Элементы.Клиенты.ВыделенныеСтроки.Очистить();
	КонецЕсли;
	
КонецПроцедуры

Запускаем на телефоне – работает!

Причем обратите внимание – можно не только определить свой обработчик долгого тапа, но и установить время задержки перед его срабатываем (второй параметр процедуры ПодключитьОбработчикОжидания).

Ну и чтобы вам два раза не вставать, к этой статье мы прикладываем обработку, в которой реализован простенький обработчик долгого тапа – можно тапнуть по строке и выбрать, что с ней сделать – переместить вверх, вниз, или удалить.

Вывод

Для обработки события длительного нажатия по строке табличной части следует воспользоваться комбинаций событий ПриАктивизацииЯчейки и Выбор, в которых проверяется, выделена ли текущая строка.

Пример реализации приведен в обработке, прикрепленной к статье. В описанном алгоритме также можно задать длительность задержки, после которой срабатывает обработчик. Метод одинаково работает на Android и iOS.

Послесловие

Я не удивлюсь, если первым комментарием к этой статье будет фраза “Мсье знает толк...” А что поделаешь – именно так выглядит программирование под мобильную платформу 1С, если хочется выжать из нее немножко больше, чем 100%. Впрочем мы уверены, что оно того стоит, и наше приложение Контейнер – тому пример.

Мы не прощаемся, и в следующей статье расскажем про наши прекрасные диаграммы расходов и платежей. Оставайтесь с нами!

Вадим Невзоров
ХВОЯ интегра, Одесса

Скачать файлы

Наименование Файл Версия Размер
Обработка долгого нажатия 7
.epf 6,81Kb
05.02.15
7
.epf 6,81Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
2. Ruslan (flyer) 05.02.15 17:36
хорошо что такие статьи пошли с опытом по моб.платформе. жду еще от вас интересных фишек. может вскоре сделаете слайд влево или вправо. по таблице.
3. Дмитрий Шерстобитов (DitriX) 05.02.15 23:40
(2) тут уже ква :) Ждите новый интерфейс. То что тут описано - это стандартное поведение стационарной 1С, за исключением того, что мобильная эмулирует как бы двойной щелчек мыши.
А слайды уже не отловить, хотя не, вру. Отловить их в принципе реально, но делать это надо не в 1с, а в 1с передавать только событие слайда :)
4. Сергей Галюк (dj_serega) 06.02.15 12:48
Нужно было такое дело. А времени поэкспериментировать не было.
Спасибо за то что проделали огромную работу :)
5. Vladimir Savelyev (gigapevt) 11.02.15 17:36
6. Роман Зиновьев (Широкий) 16.04.15 10:42
Программную активацию клавиатуры удалось реализовать?
7. Вадим Невзоров (vadnevzorov) 17.04.15 11:41
(6) Широкий, нет. Даже в 8.3.6 такой возможности не дают, что очень странно.
8. Seeker Seeker (Seeker) 16.05.16 13:17
добрый день,

А как нибудь можно редактировать таблицу значений в списке?
ну т.е. вообще не открывать форму для редактирования строки, а изменять количество сразу в таблице?
9. rhtr Иванов (rhtr) 28.10.16 12:51
10. rhtr Иванов (rhtr) 29.10.16 20:47
Цуки, на 8.3.9 сломали, вылетает приложение при ДолгийТап
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа