Перейти к содержанию
  • 0
brunnengi

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

Вопросы

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
  • 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

атак?
 

if TOpenCustomScrollBox(Sender).ContainsObject(ICtrl.GetObject) then
Отредактировал Slym

Поделиться сообщением


Ссылка на сообщение
  • 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
4 минуты назад, Slym сказал:

тогда сначала так

даже так попробовал:

if VertScrollBox2.ContainsObject(ICtrl.GetObject) then

мёртво!

Поделиться сообщением


Ссылка на сообщение
  • 0
В 18.03.2021 в 05:30, Slym сказал:

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

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

Поделиться сообщением


Ссылка на сообщение

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

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

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

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

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

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

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

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


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

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

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