Перейти к содержанию
Fire Monkey от А до Я
  • 2

vkbdhelper - поднятие компонентов над клавиатурой


Вопрос

  • Модераторы

Привет Всем!

 

vkbdhelper.pas

 

Force focused control visible when Android Virtual Keyboard showed or hiden
How to use:
place vkdbhelper into your project uses section. No more code needed.

 

Давно пользовался vkbdhelper'ом, но он был только для андроида.

руки добрались и до этого, теперь его можно использовать и на IOS

 

изменения

* почистил uses секцию

* убрал зависимость от платформ (кросс-платформенный)

* добавил глобальную переменную VKOffset

 

VKOffset - расстояние между контролом и клавиатурой

                 для тех случаев когда включены подсказки/автозамена

                 и контрол оказывается под доп. панелькой

 

Не все клавиатуры включают доп. панели в свой размер!

Например для IOS нужно всегда прибавлять 30-32 пикселя, панель с кнопкой Done перекрывает контрол

{$IFDEF IOS}
  VKOffset := 31;
{$ELSE}
  VKOffset := 0; // на свой вкус
  // не знаю как определить размер доп. панельки
  // когда она не входит в размер клавиатуры 
  // и определить есть ли панелька вообще...
{$ENDIF}

vkbdhelper.zip

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
  • Модераторы

 

How to use:

place vkdbhelper into your project uses section. No more code needed.

Как пользоваться:

поместить файл в папку с проектом, прописать в uses желательно в .dpr файле. Всё

Ссылка на комментарий
  • 0

Обожаю вот такую вот реализацию: включил в uses - функционал заработал, исключил - функционала нет, но ни на что другое это не повлияло. И не задумываешься, что "ага, раз мне нужно это, значит еще в 10 модулях нужно переопределить всё подряд и вообще переписать заново".

ZuBy, огромнЕйшее спасибо! Сейчас будем посмотреть, как оно на iOS живет :)

Ссылка на комментарий
  • 0
  • Модераторы

Обожаю вот такую вот реализацию: включил в uses - функционал заработал, исключил - функционала нет, но ни на что другое это не повлияло. И не задумываешься, что "ага, раз мне нужно это, значит еще в 10 модулях нужно переопределить всё подряд и вообще переписать заново".

ZuBy, огромнЕйшее спасибо! Сейчас будем посмотреть, как оно на iOS живет :)

да мне то особо не за что, я просто доработал

Ссылка на комментарий
  • 0

Хммм... не совсем отрабатывает на iOS. Позиция меняется, но не на столько, чтобы контрол стал полностью виден. При этом "верхних" тулбаров на клавиатуре нет.

Правильно ли я понимаю, что для использования этого модуля не нужно извращаться, как предложено в "стандартном" способе - класть все контролы на VertScrollBox?

 

Нет, туплю. Тулбар был, всё классно.

Изменено пользователем kami
Ссылка на комментарий
  • 0
  • Модераторы

 

Хммм... не совсем отрабатывает на iOS. Позиция меняется, но не на столько, чтобы контрол стал полностью виден. При этом "верхних" тулбаров нет.

тестил на iphone 6, ios simulator все отлично. укажите значение VKOffset которое вам подходит. мне подошло 31

 

 

Правильно ли я понимаю, что для использования этого модуля не нужно извращаться, как предложено в "стандартном" способе - класть все контролы на VertScrollBox?

не нужно

Ссылка на комментарий
  • 0
{$IFDEF IOS}
  VKOffset := 31;
{$ELSE}
  VKOffset := 0; // на свой вкус
  // не знаю как определить размер доп. панельки
  // когда она не входит в размер клавиатуры 
  // и определить есть ли панелька вообще...
{$ENDIF}

А это где записать?

Ссылка на комментарий
  • 0

В модуле есть неточность с определением координат, из-за этого и введено VKOffset.
Дело в том, что координаты клавиатуры получаются абсолютными относительно экрана, а координаты контрола, которому нужно провести позиционирование - абсолютными относительно формы. Сама же форма имеет TopLeft отличные от нуля (шторка).
Нужно преобразование координат клавиатуры относительно формы. В этом случае VKOffset не нужен, т.к. координаты клавиатуры включают в себя тулбар (если он есть).
 
Прикладываю уточненный модуль, оттестировано на iOS. Прошу проверить на Android.

Ссылка на комментарий
  • 0
  • Модераторы

В модуле есть неточность с определением координат, из-за этого и введено VKOffset.

Дело в том, что координаты клавиатуры получаются абсолютными относительно экрана, а координаты контрола, которому нужно провести позиционирование - абсолютными относительно формы. Сама же форма имеет TopLeft отличные от нуля (шторка).

Нужно преобразование координат клавиатуры относительно формы. В этом случае VKOffset не нужен, т.к. координаты клавиатуры включают в себя тулбар (если он есть).

 

Прикладываю уточненный модуль, оттестировано на iOS. Прошу проверить на Android.

да, для IOS Ваш вариант работает, но для Android не подходит по двум причинам:

1) поднимает контрол выше, чем нужно

2) разные производители на андроиде творят что хотят...

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

Для примера на Nexus 5 панель входит в размер, а на HTC не входит

 

Ваш вариант работает медленней, каждый раз поиск формы...

Ссылка на комментарий
  • 0

Увы - на андроиде протестировать не могу.

Да, медленнее из-за поиска (а сильно? на IOS Simulator я разницы не ощутил, да и вызывается он однократно при показе).

Однако в стандартной клавиатуре на iOS 9 всегда вверху есть кнопки типа "отменить/копировать" и т.п.

При этом IFMXVirtualKeyboardToolbarService.IsToolbarEnabled возвращает False. В iOS8 такого я не видел.

Т.е. получается, что в iOS9 всегда нужно добавлять VKOffset, а в iOS8 - нет.

 

Зоопарк андроида всегда впечатлял :) Но думается, введением переменной дело в любом случае не ограничить, раз "там включают, а тут не включают" тулбар в размер клавиатуры.

 

По поводу п.1 - а как отрабатывает стандартный способ от Embarcadero?

Изменено пользователем kami
Ссылка на комментарий
  • 0
  • Модераторы

Немноно не так: если форм много он каждый раз будет искать форму.

И на счёт стандартного способа, это вы про ScrollableForm?

Он также работает как и хелпер без вашего вмешательства))

Ссылка на комментарий
  • 0

Немноно не так: если форм много он каждый раз будет искать форму.

Тоже немного не так - он будет каждый раз искать форму при показе клавиатуры. Что, впрочем, и без того проделывается в ScrollInToRect

 

 

И на счёт стандартного способа, это вы про ScrollableForm?

Он также работает как и хелпер без вашего вмешательства))

Совершенно верно, именно про него.

А вот то что он работает как ваш исходный код модуля - не согласен. потому что в ScrollableForm как раз и проводится ScreenToClient для координат клавиатуры в FormVirtualKeyboardShown.

 

Повторюсь - про Android судить не могу, но в iOS правильное позиционирование должно быть именно с ScreenToClient преобразованием координат клавиатуры.

Ссылка на комментарий
  • 0
  • Модераторы

 

Немноно не так: если форм много он каждый раз будет искать форму.

Тоже немного не так - он будет каждый раз искать форму при показе клавиатуры. Что, впрочем, и без того проделывается в ScrollInToRect

 

 

И на счёт стандартного способа, это вы про ScrollableForm?

Он также работает как и хелпер без вашего вмешательства))

Совершенно верно, именно про него.

А вот то что он работает как ваш исходный код модуля - не согласен. потому что в ScrollableForm как раз и проводится ScreenToClient для координат клавиатуры в FormVirtualKeyboardShown.

 

Повторюсь - про Android судить не могу, но в iOS правильное позиционирование должно быть именно с ScreenToClient преобразованием координат клавиатуры.

 

по сути разницы не вижу, у меня просто универсальней и результат тот же.

Ссылка на комментарий
  • 0

Видимо, у нас разные понятия об универсальности. Ручное задание значения "глобального смещения", имхо, следует считать "тонкой доводкой" исключительно под конкретный тип окружения. Но - ваше право.

Еще раз огромное спасибо за модуль. За сим умолкаю.

Ссылка на комментарий
  • 0

Подцепил vkbdhelper в dpr-е.

На форме в Fill - Bitmap - Bitmap загрузил бэкграунд (png-файл темного цвета 1920х1200), wrap-mode=TileStretch, color=Black.

В центре стоит layout, у которого Align=Center, в нем пара Edit-ов.

 

Так вот когда жму на один из Edit-ов, компоненты как полагается поднимаются, но бэкграунд формы становится светлым - не чисто белый (картинка просто пропадает).

 

Как избавиться от этого? Пробовал и старую и новую версию vkbdhelper.pas - background также пропадает. Для проверки делал invalidate формы - не помогло.

 

PS. Android 5

Изменено пользователем Rusland
Ссылка на комментарий
  • 0

Крайне интересно. Основной принцип этого модуля - если нет скроллбокса, то положить всё, лежащее на форме, на созданный в Runtime TLayout и уже его двигать.

Дык вот, если берем за основу форму из описания Rusland, то кроме Layout-а с какого-то перепугу на форме оказывается TRectangle. Вот из-за его перемещения на Layout изображение и пропадает.

К сожалению, проблема конечно решаема, но только с некоторыми допусками. Совершенно непонятно, как отличить TRectangle, который служит фоновым изображением от TRectangle "своего", который может уже лежать на форме. Может, Ярослав чем поможет?  Вечером постараюсь выложить решение.

 

Вот сейчас пишу это и думаю, что у этого модуля есть один существенный недостаток - девелопер не знает, что после первого показа клавиатуры все его контролы уже лежат на TLayout. Если контролы меняются в runtime, то последовательное показ клавиатуры ->перенос всего на Layout->добавление нового контрола на форму->показ клавиатуры->перенос всего на Layout приведет к такой гребенке из вложенности TLayout-ов, что...

Ссылка на комментарий
  • 0

Ну вот, собственно, что получилось.
Решение, к сожалению, мне не нравится, поскольку основывается исключительно на том, что этот "левый" Rectangle лежит прямо на форме и имеет Align = Contents.
В остальном - работает.
 
Еще раз заострю внимание на своем предыдущем сообщении - если вы создаете контролы в runtime и выставляете родителем для них саму форму, то пользоваться этим модулем для вас противопоказано.

 

Upd: заменил вложение. Прошу обратить внимание на комментарии в файле, касаемые known issues.

 

vkbdhelper.zip

Изменено пользователем kami
Ссылка на комментарий
  • 0

kami, попробовал новую версию, теперь срабатывает правильно только в первый раз, затем при каждой активации Edit-а происходит подъем и моментальное возвращение (доли секунды) в то же положение, где изначально стоял Edit.

 

PS. Delphi RX. Android 5.0. Контролов в runtime не создаю.

Изменено пользователем Rusland
Ссылка на комментарий
  • 0

Update. Исправили недостаток на Android 5. Большое спасибо Rusland за тестирование.

Итоговый файл прикладываю.

 

По прежнему не рекомендую использовать этот модуль, если создаваемые в runtime контролы ложатся напрямую на форму.

Перед написанием претензий, пожалуйста прочитайте known issues в комментарии в начале файла.

 

vkbdhelper.zip

Изменено пользователем kami
Ссылка на комментарий
  • 0
  • Модераторы

По прежнему не рекомендую использовать этот модуль, если создаваемые в runtime контролы ложатся напрямую на форму.

Перед написанием претензий, пожалуйста прочитайте known issues в комментарии в начале файла.

Решение ведь простое для тех кто в runtime создаёт компоненты, поместить на форму самим TLayout с именем sVKBHelperLayout

и указать Parent у компонентов этот layout

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...