Skip to content

Manage Plan

Control the plan and query its state through the presenter instance.

Overview

  • Use IExpoFpPlanPresenter to send commands and request information from the loaded plan.
  • All public APIs are available in two forms:
    • Coroutine (suspend) functionsrecommended.
    • Callback functions — for Java or legacy cases.
  • Most commands do not return a value. Requests return ExpoFpResult<T>.

Step 1. Apply Commands

Reload a plan

Reload the plan with new or previous settings. If a parameter is null, the previous value is reused.

presenter.reloadPlan(
    planLink = ExpoFpLinkType.ExpoKey("YourExpoKey"),
    additionalParams = listOf(
        ExpoFpPlanParameter.NoOverlay(true),
        ExpoFpPlanParameter.HideHeaderLogo(true)
    ),
    locationProvider = YourLocationProvider(),
    messageListener = YourMessageListener()
)
presenter.activateFloor(floor)   // floor: ExpoFpFloor
presenter.findLocation()         // show current location if available
presenter.fitBounds()            // fit to full plan
presenter.fitBounds(bounds = ExpoFpBounds(leftTop = ExpoFpPoint(x = 996.5, y = 787.0), rightBottom = ExpoFpPoint(x = 1015.5, y = 798.0)))
presenter.fitBounds(bounds = ExpoFpBounds(leftTop = ExpoFpPoint(x = 996.5, y = 787.0), rightBottom = ExpoFpPoint(x = 1015.5, y = 798.0)), options = ExpoFpZoomOptions(padding = 200))
presenter.zoomTo(ExpoFpPOISelectors(booths = listOf(ExpoFpPOISelector(name = "10.1-19"))))
presenter.zoomTo(ExpoFpPOISelectors(exhibitors = listOf(ExpoFpPOISelector(externalId = "exhibitorId"))), ExpoFpZoomOptions(padding = 100))
presenter.getBounds(ExpoFpPOISelectors(booths = listOf(ExpoFpPOISelector(name = "10.1-19")))) // returns ExpoFpResult<ExpoFpBounds?>
presenter.reset()                // reset the plan to its original state

Change language

presenter.changeLanguage(ExpoFpLanguage.English)
presenter.changeLanguage(ExpoFpLanguage.German)
// ... see ExpoFpLanguage for all available languages

Highlight and selection

presenter.highlightBooths(listOf("boothExternalId1", "boothExternalId2"))
presenter.highlightExhibitors(listOf("exhibitorExternalId1"))
presenter.highlightEntities(listOf("entityExternalId1", "entityExternalId2"))
presenter.selectBooth("BoothNameOrExternalId")
presenter.selectCategory("CategoryName")
presenter.selectExhibitor("ExhibitorNameOrExternalId")

val position = ExpoFpPosition(x = 8490.0, y = 8188.0)
presenter.selectCurrentPosition(position, focus = true)
presenter.deselectCurrentPosition() // reset current position

Routing

Use ExpoFpRouteWaypoint to describe waypoints.

Build a route:

val route = listOf(
    ExpoFpRouteWaypoint.Position(ExpoFpPosition(x = 8490.0, y = 8188.0)),
    ExpoFpRouteWaypoint.Position(ExpoFpPosition(x = 8515.0, y = 8188.0))
)
presenter.selectRoute(route)

Clear the route:

presenter.deselectRoute()

Build a route with start and/or destination point:

// From current position to a booth
presenter.selectRoute(
    from = null, // null means current position
    to = ExpoFpRouteWaypoint.BoothName("Booth A")
)

// From one booth to another
presenter.selectRoute(
    from = ExpoFpRouteWaypoint.BoothName("Booth A"),
    to = ExpoFpRouteWaypoint.BoothName("Booth B")
)

// From a position to an exhibitor
presenter.selectRoute(
    from = ExpoFpRouteWaypoint.Position(ExpoFpPosition(x = 8490.0, y = 8188.0)),
    to = ExpoFpRouteWaypoint.ExhibitorName("Acme Corp")
)

Bookmarks

presenter.setBookmarks(
    listOf(
        ExpoFpBookmark(
            name = "BioCycle Africa",
            externalId = "RXhoaWJpdG9yXzE4OTc5NDQ=",
            isBookmarked = true
        )
    )
)

GPS tracking

Control built-in GPS tracking. For 3rd party location providers, built-in GPS tracking must be disabled to avoid conflicts.

presenter.setBuiltInGpsTrackingEnabled(false)  // disable built-in GPS tracking
presenter.setBuiltInGpsTrackingEnabled(true)   // enable built-in GPS tracking

// Check if built-in GPS tracking is enabled
val gpsEnabled: ExpoFpResult<Boolean> = presenter.isBuiltInGpsTrackingEnabled()

Note: setLocationProvider() automatically disables built-in GPS tracking. removeLocationProvider() automatically re-enables it.

Custom message handlers

Subscribe to custom JavaScript callbacks on a plan.

val handler = object : IExpoFpCustomMessageHandler {
    override fun onMessage(message: String) {
        Log.i("ExpoTest", "Custom callback: $message")
    }
}
presenter.setMessageHandler(handler, "onCustomButtonClick")
presenter.removeMessageHandler("onCustomButtonClick")

UI controls

presenter.setElementsVisibility(
    ExpoFpElementsVisibility(
        controls = false,
        levels = false,
        header = false,
        overlay = false
    )
)
presenter.switchView() // toggle 2D/3D
presenter.zoomIn()
presenter.zoomOut()

Step 2. Request Information

All requests return ExpoFpResult<T>.

val booths: ExpoFpResult<List<ExpoFpBooth>> = presenter.boothsList()
val categories: ExpoFpResult<List<ExpoFpCategory>> = presenter.categoriesList()
val exhibitors: ExpoFpResult<List<ExpoFpExhibitor>> = presenter.exhibitorsList()
val visibility: ExpoFpResult<ExpoFpElementsVisibility> = presenter.getElementsVisibility()
val floors: ExpoFpResult<List<ExpoFpFloor>> = presenter.getFloors()

val optimized: ExpoFpResult<List<ExpoFpRouteInfo>> =
    presenter.getOptimizedRoutes(
        waypoints = listOf(
            ExpoFpRouteWaypoint.Position(ExpoFpPosition(x = 8490.0, y = 8188.0)),
            ExpoFpRouteWaypoint.Position(ExpoFpPosition(x = 8515.0, y = 8188.0))
        )
    )

val search: ExpoFpResult<List<ExpoFpSearchModel>> = presenter.search("coffee")
val gpsEnabled: ExpoFpResult<Boolean> = presenter.isBuiltInGpsTrackingEnabled()

Step 3. Callback Alternatives

All requests are also available as callback variants:

presenter.boothsList { result -> /* ... */ }
presenter.categoriesList { result -> /* ... */ }
presenter.exhibitorsList { result -> /* ... */ }
presenter.getElementsVisibility { result -> /* ... */ }
presenter.getFloors { result -> /* ... */ }
presenter.getOptimizedRoutes(route) { result -> /* ... */ }
presenter.search("coffee") { result -> /* ... */ }
presenter.isBuiltInGpsTrackingEnabled { result -> /* ... */ }

Recommended: Prefer coroutine APIs for cleaner cancellation, lifecycle scoping, and easier composition.


Step 4. Debug Helpers

For development, you may run arbitrary JS in the plan:

val evalResult: ExpoFpResult<Any?> =
    presenter.evaluateCustomScript("console.log('ping')")

Enable debug mode:

val presenter = ExpoFpPlan.createPlanPresenter(
    planLink = ExpoFpLinkType.ExpoKey("demo"),
    isDebugModeEnabled = true
)

or

presenter.reloadPlan(
    planLink = ExpoFpLinkType.ExpoKey("demo"),
    isDebugModeEnabled = true
)

Debug mode may slow down initialization. Use it only in debug builds.


Best Practices

  • Prefer coroutines: cleaner and safer lifecycle integration.
  • Check results: always handle both success and error in ExpoFpResult<T>.
  • Be null-aware: some responses may be null (e.g., direction reset).
  • Group UI changes: avoid calling multiple UI-affecting commands in very short intervals.
  • Debug mode: enable only during development or troubleshooting.