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

[Android] Разделить скроллинг и нажатие


brunnengi

Вопрос

Опубликовано

Здравствуйте.

-------------

Delphi XE7

-------------

В компонент TVertScrollBox положил несколько Layout'ов. Layout'ы имеют события MouseDown и MouseUp.

При прокручивание списка идет реакция события того layout'а на который пришелся "click" пальцем.

Как сделать так, что бы MouseDown и MouseUp компонентов Tlayout отрабатывались только в том случае, если это не скроллинг, т.е. так, как это сделано во всех приложениях для андройда?

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

  • 0
Опубликовано

событие onTap я использую. Но не всегда нужен именно OnTap.

Например вам требуется смена цвета когда элемент нажат, а когда с элемент отпущен, то цвет надо вернуть назад.

Т.е. надо использовать MouseDown и MouseUp.

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

 

Я не спорю что это абсолютно правильная и ожидаемая реакция. Однако я вижу что в других приложениях это не проблема. Если идет скроллинг, то элементы на которые пришёлся клик не реагируют, а если это именно нажатие, то реагируют.

 

Как такое реализовать.

  • 0
Опубликовано

Очень актуален, даже события OnClick срабатывает на Button раньше жеста. Не могу допереть никак, если реализовать включение таймера при OnClick а на таймере с интервалом 0,5 сек проверить был ли жест путем проверки переменной, тогда пуск процедуры, конечно на OnGesture переменной присвоит 1. Еще не пробывал, но уверен что есть нормальный способ, а ни трактор как этот.

Кстати читал что событие OnClick в принципе срабатывает раньше чем жест, был прям список что срабатывает раньше, и у разных компонентов разыне очередности, что означает я полагаю, что дело в компоненте, подскажите как изменить компонент например Button, то есть очередность срабатывания процедур в компоненте? 

  • 0
Опубликовано

решал эту проблему через ручное отлавливание координат между MouseDown и MouseUp
элементам внутри контейнера HitTest:=false
если скролл контейнера был - ничего не делать 
если скролла не было - определить по координатам, есть ли объект под пальцем, и запустить, что там надо запускать по клику

  • 0
Опубликовано (изменено)

Тоже решал эту проблему через ручное отлавливание координат. Приведу небольшой пример.

 

Есть ComboBox который открывался, если на него поставить палец при скроле.

ComboBox лежит на Layout.

Layout лежит на ScrollBox. А так же имеется ToolBar вверху.

Для начала у ComboBox.Enabled = False;

А потом OnTap Parent компоненты, на которой лежит ComboBox был написан так.

LayoutOnTap(Sender: TObject; const Point: TPointF);
var
  PointComponent : TPointF;
  PixelRegion: TRectF;
begin
    PointComponent := TPointF.Create(ComboBox.Position.X,
                                     ComboBox.Position.Y);
    PixelRegion := TRectF.Create(PointComponent, ComboBox.Width,
                                 ComboBox.Height);
    if PixelRegion.Contains(TPointF.Create(Point.X, Point.Y - ToolBar.Height + ScrollBox.ViewportPosition.Y)) then begin
      ComboBox.DropDown;
      exit;
    end{if};
end{LayoutOnTap};

Для Еdit: 

1) Еdit.ReadOnly := True;

2) EditOnTap(Еdit.ReadOnly := False;);

3) EditOnExit(Еdit.ReadOnly := True;) 

Для DateEdit всё так же как с комбобоксом, только DateEdit.OpenPicker;

 

Возможно это кому-то поможет.

Изменено пользователем umkes
  • 0
Опубликовано

я эту проблему решал через переписывание обработок событий мышки компонентов. то есть в обычном десктопе нажатие на элемент означает его нажатие. в тачевом это не всегда так. я сделал такой примерно алгоритм - в onMouseDown регистрировал что был выбран элемент, в onMouseMove на сколько далеко после этого двинулись координаты, а onMouseUp обработку, если координаты поменялись более чем на 20 точек то ничего не делать, если координаты не поменялись или поменялись незначительно то вызов процедур какие должны были вызваться в OnMouseDown. Я об этом писал уже и тему создавал, но разработчикам пофигу, для них это не проблема. А для меня было проблемой скролить комбобоксы, вечно они выпадали. 

  • 0
Опубликовано
В 21.08.2015 в 08:18, krapotkin сказал:

решал эту проблему через ручное отлавливание координат между MouseDown и MouseUp
элементам внутри контейнера HitTest:=false
если скролл контейнера был - ничего не делать 
если скролла не было - определить по координатам, есть ли объект под пальцем, и запустить, что там надо запускать по клику

Добрый день !

Не поделитесь "определить по координатам, есть ли объект под пальцем, и запустить, что там надо запускать по клику" ?

  • 0
Опубликовано
В 17.04.2018 в 08:30, krapotkin сказал:

у каждого компонента есть BoundsRect. Нужно просто сравнить, не попадает ли XY в этот rect .

Согласитесь, что это не корректное решение? У меня на ScrollBox некуда пальцем ткнуть, что бы не задеть BoundRect. И при скроллинге, естественно отжимается RadioButton ( а их 4 в примере). Т.е. вопрос остаётся открытым и по сей день?

Кстати, поймал себя на мысли, что лет 5 назад такая проблема была в браузерах. При пролистывании "срабатывали" ссылки на страницы. Сейчас подобного не встречаю. Так каким методом решить эту проблему?

Screenshot_20210317-035451.jpg

  • 0
Опубликовано

очень трудно сформулировать логику, чтобы всем подошла
я еще при исходной задаче хотел задать вопрос, а что вы собираетесь делать, когда это перестанет влезать на экран?? но не задал. решил, что всему свое время))


нормальное решение - сделать отдельно радио, отдельно текст к нему, тогда и прокрутка будет работать нормально и радио тоже

  • 0
Опубликовано
1 час назад, krapotkin сказал:

я еще при исходной задаче хотел задать вопрос, а что вы собираетесь делать, когда это перестанет влезать на экран?? но не задал. решил, что всему свое время))

Доброго дня!

Если честно, я сразу предполагал скроллинг, ибо на PC задачу реализовал ещё в конце прошлого года. Пока на больничном, решил реализовать её для мобильной платформы, благо логика вся отлажена. Естественно, не сталкиваясь ранее с FMX, не ожидал столько нерешённых проблем непосредственно с компонентами. Читая ветки, вижу, что множество вопросов возникали лет 5 назад, а воз, как говорится и ныне там. И многое актуально для дня сегодняшнего.  

  • 0
Опубликовано (изменено)
type
  TOpenCustomScrollBox=class(TCustomScrollBox);
procedure TScrollBoxService.OnViewportPositionChange(Sender: TObject;
  const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
var ICtrl:IControl;
begin
  ICtrl:=TControl(Sender).Root.Captured;
  if not assigned(ICtrl) then
  begin
    ICtrl:=TControl(Sender).Root.Focused;
    if not assigned(ICtrl) then
      exit;
  end;

  if TOpenCustomScrollBox(Sender).Content.ContainsObject(ICtrl.GetObject) then
  begin
    ICtrl.MouseUp(TMouseButton.mbLeft,[],0,0);
    ICtrl.DoMouseLeave;
  end;
end;

 

Изменено пользователем Slym
  • 0
Опубликовано (изменено)
В 18.03.2021 в 05:30, Slym сказал:

procedure VertScrollBox2OnViewportPositionChange

Без изменений.

Изменено пользователем Hevard
  • 0
Опубликовано
5 минут назад, Slym сказал:

атак?

Тоже никак. Оно вообще как-то через одно место. И так, и эдак.

А ошибку я бы и не нашел... Вообще впервые этот FMX грызу.?

Выбираю 1й пункт, 3-м скролю и он же выделяется... 

  • 0
Опубликовано (изменено)

тогда сначала так, без проверки парента

//if TOpenCustomScrollBox(Sender).ContainsObject(ICtrl.GetObject) then

закоментируй иф... так понятней?:

 

procedure TScrollBoxService.OnViewportPositionChange(Sender: TObject;
  const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
var ICtrl:IControl;
begin
  ICtrl:=TControl(Sender).Root.Captured;
  if not assigned(ICtrl) then
  begin
    ICtrl:=TControl(Sender).Root.Focused;
    if not assigned(ICtrl) then
      exit;
  end;
  ICtrl.MouseUp(TMouseButton.mbLeft,[],0,0);
  ICtrl.DoMouseLeave;
end;
Изменено пользователем Slym
  • 0
Опубликовано
В 18.03.2021 в 05:30, Slym сказал:

ICtrl.MouseUp(TMouseButton.mbLeft,[],0,0); ICtrl.DoMouseLeave;

ну, меня Mouse смутил слегка... но, чем чёрт не шутит. Мало ли, так положено! ?

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить на вопрос...

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

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

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

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

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

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...