Page Controller

A Page Controller is a special variable type that manages navigation and animation between pages in a PageView widget. It allows you to programmatically switch pages, create page-based animations, and build features like onboarding flows or image galleries.

Supported Widgets

The Page Controller can be used with:

When to Use

Use a Page Controller when you need to:

  • Build onboarding or tutorial flows

  • Create image galleries or carousels

  • Implement tab-based navigation

  • Programmatically navigate between pages

  • Create page-driven animations

  • Track current page index

  • Implement custom page indicators

Creating a Page Controller

  1. Navigate to Variables in your project

  2. Click Add Variable

  3. Select Page Controller as the type

  4. Give it a descriptive name (e.g., onboardingController, galleryController)

Binding to Widgets

PageView Example

PageView:
  Controller: ${onboardingController}
  
  Pages:
    - Page 1 content
    - Page 2 content
    - Page 3 content

Animation Builder Example

Create page-driven animations:

Animation Builder:
  Controller: ${onboardingController}
  
  Child:
    Container:
      Opacity: ${animationValue}

Controller Methods

Use the Control Object action to invoke these methods on the controller.

jumpToPage

Instantly switches to a specific page without animation.

Parameter
Type
Description

page

Number

The target page index (zero-based)

Example Use Cases:

  • Jump to first page: page: 0

  • Jump to last page: page: 2

  • Jump to specific page: page: 1

When to Use:

  • Immediate page changes (e.g., reset to first page)

  • No animation needed

  • Faster than animateToPage


animateToPage

Smoothly animates the transition to a specific page.

Parameter
Type
Description

page

Number

The target page index (zero-based)

durationInMs

Number

Animation duration in milliseconds

curve

String

The easing curve for animation

Available Curves:

  • linear - Constant speed

  • easeIn - Slow start, fast end

  • easeOut - Fast start, slow end

  • easeInOut - Slow start and end, fast middle

  • bounceOut - Bouncing effect at end

  • elasticOut - Elastic spring effect

Example Use Cases:

  • Smooth page transition: page: 1, durationInMs: 400, curve: 'easeInOut'

  • Quick flip: page: 2, durationInMs: 200, curve: 'linear'

  • Bouncy effect: page: 0, durationInMs: 600, curve: 'bounceOut'

When to Use:

  • Better UX with smooth transitions

  • User-triggered navigation

  • Highlighting the page change


nextPage

Animates to the next page.

Parameter
Type
Description

durationInMs

Number

Animation duration in milliseconds

curve

String

The easing curve for animation

Example:

On Next Button Click:
  Control Object:
    Object: ${onboardingController}
    Method: nextPage
    Arguments:
      durationInMs: 400
      curve: 'easeInOut'

When to Use:

  • "Next" or "Continue" buttons

  • Sequential navigation flows

  • Automatic page advancement


previousPage

Animates to the previous page.

Parameter
Type
Description

durationInMs

Number

Animation duration in milliseconds

curve

String

The easing curve for animation

Example:

On Back Button Click:
  Control Object:
    Object: ${onboardingController}
    Method: previousPage
    Arguments:
      durationInMs: 400
      curve: 'easeInOut'

When to Use:

  • "Back" or "Previous" buttons

  • Reverse navigation

  • Undo-like interactions


Common Use Cases

1. Onboarding Flow

Create a multi-step onboarding with navigation controls.

Setup:

Variable: onboardingController (Page Controller)
Variable: currentPage (Number)
Initial Value: 0

PageView:
  Controller: ${onboardingController}
  On Page Changed:
    Set State: currentPage = ${currentPageIndex}

Navigation:

Button (Next):
  On Click:
    Control Object:
      Object: ${onboardingController}
      Method: nextPage
      Arguments:
        durationInMs: 400
        curve: 'easeInOut'

Button (Back):
  Visible: ${gt(currentPage, 0)}
  On Click:
    Control Object:
      Object: ${onboardingController}
      Method: previousPage
      Arguments:
        durationInMs: 400
        curve: 'easeInOut'

Button (Skip):
  On Click:
    Control Object:
      Object: ${onboardingController}
      Method: jumpToPage
      Arguments:
        page: 2

Create an image gallery with page indicators.

Setup:

Variable: galleryController (Page Controller)
Variable: currentImageIndex (Number)
Initial Value: 0

Variable: images (List)
Value: [
  "image1.jpg",
  "image2.jpg",
  "image3.jpg"
]

PageView:
  Controller: ${galleryController}
  On Page Changed:
    Set State: currentImageIndex = ${currentPageIndex}

Page Indicator:

Row:
  Data Source: ${images}
  
  Container (Dot):
    Width: 8
    Height: 8
    Background Color: ${if(isEqual(index, currentImageIndex), 'blue', 'gray')}
    On Click:
      Control Object:
        Object: ${galleryController}
        Method: animateToPage
        Arguments:
          page: ${index}
          durationInMs: 300
          curve: 'easeOut'

3. Custom Tab Navigation

Implement a tab-based interface using PageView.

Variable: tabController (Page Controller)
Variable: activeTab (Number)
Initial Value: 0

Row (Tab Bar):
  Button (Tab 1):
    Background: ${if(isEqual(activeTab, 0), 'blue', 'gray')}
    On Click:
      Control Object:
        Object: ${tabController}
        Method: animateToPage
        Arguments:
          page: 0
          durationInMs: 300
          curve: 'easeOut'
  
  Button (Tab 2):
    Background: ${if(isEqual(activeTab, 1), 'blue', 'gray')}
    On Click:
      Control Object:
        Object: ${tabController}
        Method: animateToPage
        Arguments:
          page: 1
          durationInMs: 300
          curve: 'easeOut'

PageView:
  Controller: ${tabController}
  On Page Changed:
    Set State: activeTab = ${currentPageIndex}

Create a carousel that automatically advances.

Variable: carouselController (Page Controller)

On Page Load:
  Execute Callback:
    Delay: 3000
    Callback:
      Control Object:
        Object: ${carouselController}
        Method: nextPage
        Arguments:
          durationInMs: 500
          curve: 'easeInOut'

5. Conditional Navigation

Navigate based on conditions (e.g., skip pages based on user input).

On Submit Button Click:
  Conditional Logic:
    If ${hasCompletedProfile}:
      Control Object:
        Object: ${setupController}
        Method: jumpToPage
        Arguments:
          page: 3
    Else:
      Control Object:
        Object: ${setupController}
        Method: nextPage
        Arguments:
          durationInMs: 400
          curve: 'easeInOut'

Best Practices

  • Track current page: Store the current page index in a variable to enable conditional logic

  • Use descriptive names: Name controllers after their purpose (onboardingController, galleryController)

  • Choose appropriate curves: Use easeInOut for most page transitions

  • Set reasonable durations: 300-500ms works well for page animations

  • Handle edge cases: Disable "next" on last page, "previous" on first page

  • Use nextPage/previousPage: Prefer these over animateToPage with calculated indices for sequential navigation

  • Reset on navigation: Jump to page 0 when entering/exiting flows

Common Patterns

Next Button with Validation

Button (Next):
  Enabled: ${isCurrentPageValid}
  On Click:
    Control Object:
      Object: ${controller}
      Method: nextPage
      Arguments:
        durationInMs: 400
        curve: 'easeInOut'

Conditional Back Button

Button (Back):
  Visible: ${gt(currentPage, 0)}
  On Click:
    Control Object:
      Object: ${controller}
      Method: previousPage
      Arguments:
        durationInMs: 400
        curve: 'easeInOut'

Skip to End

Button (Skip):
  On Click:
    Control Object:
      Object: ${controller}
      Method: jumpToPage
      Arguments:
        page: ${diff(totalPages, 1)}

Page Indicator Dots

Container (Dot):
  Background: ${if(isEqual(index, currentPage), 'active', 'inactive')}
  On Click:
    Control Object:
      Object: ${controller}
      Method: animateToPage
      Arguments:
        page: ${index}
        durationInMs: 300
        curve: 'easeOut'

Troubleshooting

Controller Not Working

  • Ensure the controller variable is properly created

  • Check that the controller is bound using ${controllerName}

  • Verify the widget supports Page Controller

Page Index Out of Bounds

  • Check that page indices are within valid range (0 to pageCount - 1)

  • Handle edge cases for first and last pages

Animation Feels Choppy

  • Reduce animation duration

  • Use simpler easing curves

  • Optimize page content for better performance

Last updated