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

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

Добрый день!

 

В теме про наш продукт http://fire-monkey.ru/topic/1519-1c-papyc-mobilnoe-prilozhenie-dlia-masterov-priemschiko/ меня просили поделиться исходным кодом компонента TabControl с поддержкой слайда табов пальцем. С удовольствием делюсь :)

В составе архива сам компонент и пример его использования.

FMXUI.zip

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

я попробовал использовать ваш компонент, но сразуже наткнулся на проблему - после того как бросаешь на страницу TabControl - а другой компонент и задаёшь параметр align - client, перестаёт работать перелистывание.
после отключения HitTest всё становится на свои места, но я не могу поймать момент нажатия на компонент. 

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

Это ограничение платформы - события и жесты ловит тот, кто сверху. Как только HitTest устанавливается в Ложь, то события проваливаются до TUITabControl.

Не разбирались мы с тем, как это обойти. 

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

Простого выхода я не знаю, а так исходники FMX и вперед, отлавливать жесты, разбираться с их хождением и передачей в контролы. Может Ярослав что подскажет?

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

Попробовал на своем проекте. Супер! Именно то что давно хотелось. И почему разработчики сразу так не сделали, судя по исходному коду - не все так страшно.

 

Сразу вдогонку вопрос (ну так на всякий случай): Я правильно понял что Вы разрешаете использовать этот код без ограничений? 

Ссылка на комментарий
  • 1 месяц спустя...
  • 4 недели спустя...

Проверил - действительно, есть такое поведение. Постараюсь выложить исправление в ближайшее время.

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

Я конечно вышел из ситуации взяв TTabControl из исходников XE8. Но просто интересно что же такого изменили что перестало работать. Вроди все отладчиком прошерстил, ничего не нашел.

Ссылка на комментарий
  • 1 месяц спустя...

Добрый день решил сегодня установить данный компонент на DX10 Seattle  компонент действительно очень полезный но я заметил его странное поведение

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

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

 

У меня не видно следующую страницу при перелистывании, в XE8 все работало. Не пойму как исправить.

 

обновите вот эту процедурку

procedure TUITabControl.PaintChildren;
var
  Tab: TTabItem;
begin
  inherited;
  if FSlide then
    for Tab in TransitionTabs do
    begin
      TMyTabItem(Tab).PaintInternal;
      TMyTabItem(Tab).PaintChildren; // fix
    end;
end;
Ссылка на комментарий
  • 1 год спустя...

Hello.

This is my first post here, I’m from Spain (sorry for not posting in Russian).

I’m very impressed with the TUITabControl component, I’ve searching for a long time for this kind of control with sliding pages animations like Android native ViewPager, it works like a charm, very good in Berlin 10.2, but only an issue for me, when a TVertScrollBar is placed within TabItem the sliding animations doesn’t works, Is there any approach or tip to solve it?, many thanks.

Kind Regards.
Juande.

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

Hello Juande,

The first problem of it is a intercepting gestures/mouse events by TVertScrollBar, it's a reason why TUITabControl cannot receive events. The second problem is standard pan gesture doesn't define vertical and horizontal movement. It's a limitation of FireMonkey. 

So there are only one possible solution:

  1. You need catch mouse and pan gesture events in TVertScrollBar.
  2. Manually define is it a horizontal movement or not?
  3. If it's horizontal movement, that transfer it into TUITabControl by direct calling methods CMGesture or MouseXXX.
Ссылка на комментарий
  • 2 недели спустя...
В 17.07.2015 в 14:21, Кривяков Виталий сказал:

Добрый день!

 

В теме про наш продукт http://fire-monkey.ru/topic/1519-1c-papyc-mobilnoe-prilozhenie-dlia-masterov-priemschiko/ меня просили поделиться исходным кодом компонента TabControl с поддержкой слайда табов пальцем. С удовольствием делюсь :)

В составе архива сам компонент и пример его использования.

FMXUI.zip

Спасибо, отличный компонент! Все работает!

Berlin 10.1, Android 5.03

Ссылка на комментарий
  • 4 года спустя...

Заинтересовал этот компонент. Пытаюсь доделать его для использования в 10.4.1. Осталась одна проблема, не видно анимации при отпускании пальца, то есть веду палец по экрану - вижу смену табов, но при отпускании пальца активный таб просто перерисовывается.

Думаю проблема вот в этой процедуре

procedure TUITabControl.EndSlide;


  procedure LocalAnimateInt(AParent : TFmxObject; const APropertyName: string; const NewValue: Integer; Duration: Single = 0.2;
    AType: TAnimationType = TAnimationType.In;
    AInterpolation: TInterpolationType = TInterpolationType.Linear);
  var
    A: TIntAnimation;
  begin
    TAnimator.StopPropertyAnimation(Self, APropertyName);
    A := TIntAnimation.Create(AParent);
    A.Parent := AParent;
    A.AnimationType := AType;
    A.Interpolation := AInterpolation;
    A.OnFinish := AnimationFinished;
    A.Duration := Duration;
    A.PropertyName := APropertyName;
    A.StartFromCurrent := True;
    A.StopValue := NewValue;
    A.Start;
  end;

  procedure LocalAnimateIntWait(AParent : TFmxObject; const APropertyName: string; const NewValue: Integer; Duration: Single = 0.2;
    AType: TAnimationType = TAnimationType.In;
    AInterpolation: TInterpolationType = TInterpolationType.Linear);
  var
    A: TIntAnimation;
  begin
    TAnimator.StopPropertyAnimation(Self, APropertyName);
    A := TIntAnimation.Create(AParent);
    try
      A.Parent := AParent;
      A.AnimationType := AType;
      A.Interpolation := AInterpolation;
      A.Duration := Duration;
      A.PropertyName := APropertyName;
      A.StartFromCurrent := True;
      A.StopValue := NewValue;
      A.Start;
      while A.Running do
      begin
        Application.ProcessMessages;
        Sleep(0);
      end;
    finally
      A.DisposeOf;
    end;
  end;

const
  Duration = 0.2;

begin
  if not FSlide then Exit;
{  if SlideVolume>0.5 then begin
    LocalAnimateInt(Layout1, 'Position.X', Round(-Layout1.Width));
    LocalAnimateIntWait(Layout2, 'Position.X', 0);
    ActiveTab := Tab2;
  end else begin
    LocalAnimateInt(Layout1, 'Position.X', 0);
    LocalAnimateIntWait(Layout2, 'Position.X', Round(Layout1.Width));
    ActiveTab := Tab1;
  end;}
          if (SlideVolume<0.5) and not IsSpeedUp then
          begin
            if SlideDirection=TSlideDirection.sdNext then begin

              P := Tab1.AbsoluteToLocal(LayoutPos);
              LocalAnimateInt(internalLayout1, 'Position.X', Round(P.X), Duration, TAnimationType.Out, TInterpolationType.Exponential);
              P := Tab2.AbsoluteToLocal(LayoutPos);
              LocalAnimateIntWait(internalLayout2, 'Position.X', Round(P.X + LayoutRect.Width), Duration, TAnimationType.Out, TInterpolationType.Exponential);

            end else begin
              P := Tab1.AbsoluteToLocal(LayoutPos);
              LocalAnimateInt(internalLayout1, 'Position.X', Round(P.X), Duration, TAnimationType.Out, TInterpolationType.Exponential);
              P := Tab2.AbsoluteToLocal(LayoutPos);
              LocalAnimateIntWait(internalLayout2, 'Position.X', Round(P.X - LayoutRect.Width), Duration, TAnimationType.Out, TInterpolationType.Exponential);
            end;
            ActiveTab := Tab1;
          end
          else
          begin
            if SlideDirection=TSlideDirection.sdNext then begin
              P := Tab1.AbsoluteToLocal(LayoutPos);
              LocalAnimateInt(internalLayout1, 'Position.X', Round(P.X - LayoutRect.Width), Duration, TAnimationType.Out, TInterpolationType.Exponential);
              P := Tab2.AbsoluteToLocal(LayoutPos);
              LocalAnimateIntWait(internalLayout2, 'Position.X', Round(P.X), Duration, TAnimationType.Out, TInterpolationType.Exponential);
            end else begin
              P := Tab1.AbsoluteToLocal(LayoutPos);
              LocalAnimateInt(internalLayout1, 'Position.X', Round(P.X+ + LayoutRect.Width), Duration, TAnimationType.Out, TInterpolationType.Exponential);
              P := Tab2.AbsoluteToLocal(LayoutPos);
              LocalAnimateIntWait(internalLayout2, 'Position.X', Round(P.X), Duration, TAnimationType.Out, TInterpolationType.Exponential);
            end;
            ActiveTab := Tab2;
          end;
  SetLength(TransitionTabs,0);
//  ClipChildren := False;
  SlideDirection := TSlideDirection.sdNone;
  FSlide := False;
end;

а конкретно тут

while A.Running do
      begin
        Application.ProcessMessages;
        Sleep(0);
      end;

но как исправить, пока не пойму.

Нашел оригинальную функцию в FMX.TabControl, выглядит она вот так

procedure TTabControl.SetActiveTabWithTransition(const ATab: TTabItem; const ATransition: TTabTransition;
const ADirection: TTabTransitionDirection = TTabTransitionDirection.Normal);

  procedure AnimateControlPositionX(AParent: TFmxObject; const NewValue: Integer);
  var
    A: TIntAnimation;
  begin
    TAnimator.StopPropertyAnimation(AParent, 'Position.X');

    A := TIntAnimation.Create(AParent);
    A.Parent := AParent;
    A.AnimationType := DefaultSlidingAnimationType;
    A.Interpolation := DefaultSlidingInterpoation;
    A.OnFinish := AnimationFinished;
    A.OnProcess := WebBrowserRealign;
    A.Duration := DefaultSlidingDuration;
    A.PropertyName := 'Position.X';
    A.StartFromCurrent := True;
    A.StopValue := NewValue;
    A.Start;
  end;

  procedure AnimateControlPositionXWait(AParent: TFmxObject; const NewValue: Integer);
  var
    A: TIntAnimation;
  begin
    TAnimator.StopPropertyAnimation(AParent, 'Position.X');

    A := TIntAnimation.Create(AParent);
    try
      A.Parent := AParent;
      A.AnimationType := DefaultSlidingAnimationType;
      A.Interpolation := DefaultSlidingInterpoation;
      A.Duration := DefaultSlidingDuration;
      A.PropertyName := 'Position.X';
      A.StartFromCurrent := True;
      A.StopValue := NewValue;
      A.Start;
      while A.Running do
      begin
        Application.ProcessMessages;
        Sleep(0);
      end;
    finally
      A.DisposeOf;
    end;
  end;

var
  Tab1, Tab2: TTabItem;
  Layout1, Layout2: TControl;
  LayoutRect: TRectF;
  P, LayoutPos: TPointF;
begin
  if ATab = ActiveTab then
    Exit;

  FinishCurrentTabTransition;

  case ATransition of
    TTabTransition.Slide:
      begin
        FTransitionRunning := True;
        ClipChildren := True;
        try
          LayoutPos := ActiveTab.Content.LocalToAbsolute(TPointF.Zero);
          LayoutRect := ActiveTab.Content.BoundsRect;

          Tab1 := ActiveTab;
          Layout1 := ActiveTab.Content;
          ActiveTab := ATab;
          Tab2 := ActiveTab;
          Layout2 := ActiveTab.Content;

          FTransitionTabs := [Tab1, Tab2];

          DisableDisappear(Tab1);

          Layout1.Visible := True;
          Layout2.Visible := True;
          if not Tab2.DisableDisappear then
          begin
            DisableDisappear(Tab2);
            PreloadContent(Layout2);
          end;

          if ADirection = TTabTransitionDirection.Normal then
          begin
            P := Tab1.AbsoluteToLocal(LayoutPos);
            Layout1.SetBounds(P.X, P.Y, LayoutRect.Width, LayoutRect.Height);
            AnimateControlPositionX(Layout1, Round(P.X - LayoutRect.Width));
            P := Tab2.AbsoluteToLocal(LayoutPos);
            Layout2.SetBounds(P.X + LayoutRect.Width, P.Y, LayoutRect.Width, LayoutRect.Height);
            AnimateControlPositionXWait(Layout2, Round(P.X));
          end
          else
          begin
            P := Tab1.AbsoluteToLocal(LayoutPos);
            Layout1.SetBounds(P.X, P.Y, LayoutRect.Width, LayoutRect.Height);
            AnimateControlPositionX(Layout1, Round(P.X + LayoutRect.Width));
            P := Tab2.AbsoluteToLocal(LayoutPos);
            Layout2.SetBounds(P.X - LayoutRect.Width, P.Y, LayoutRect.Width, LayoutRect.Height);
            AnimateControlPositionXWait(Layout2, Round(P.X));
          end;
        finally
          SetLength(FTransitionTabs, 0);
          ClipChildren := False;
          FTransitionRunning := False;
          Realign;
        end;
        // Force repaint
        Application.ProcessMessages;
      end;
  else
    ActiveTab := ATab;
  end;
end;

Работает вроде правильно, только нет анимации при движении пальца.

Как бы теперь получить то, что нужно.

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

Надеюсь понятно объяснил))

 

 

Ссылка на комментарий
6 часов назад, gonzales сказал:

Спасибо, буду пробовать

Хороший набор компонентов, спасибо OnePeople, один трабл с TabControl, нет возможности использовать loop, прокрутить с последнего таба на первый.

OnePeople, не сталкивались случайно, как исправить?

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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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