Skip to content

Listen Plan Events

Listen and respond to user interactions and runtime messages from a plan.

Overview

  • Implement IExpoFpPlanMessageListener to receive event callbacks.
  • Assign the listener when creating the presenter (recommended) or later via setMessageListener(...).
  • Callbacks are invoked on the main thread.
  • The SDK does not retain your listener globally; manage its lifecycle in your UI/component.

Step 1. Implement a Listener

class YourListener : IExpoFpPlanMessageListener {

    override fun bookmarkDidClick(
        bookmark: ExpoFpResult<ExpoFpBookmark>,
        from: ExpoFpLinkType
    ) {
        // Handle bookmark click (success or error)
    }

    override fun boothDidClick(
        boothEvent: ExpoFpResult<ExpoFpBoothClickEvent>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    override fun categoryDidClick(
        category: ExpoFpResult<ExpoFpCategory>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    override fun currentFloorDidChange(
        floor: ExpoFpResult<ExpoFpFloor>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    override fun currentPositionDidChange(
        position: ExpoFpResult<ExpoFpPosition>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    override fun detailsDidClick(
        details: ExpoFpResult<ExpoFpDetails?>,
        from: ExpoFpLinkType
    ) { /* ... */ } // details may be null

    override fun directionDidBuild(
        direction: ExpoFpResult<ExpoFpDirection?>,
        from: ExpoFpLinkType
    ) { /* ... */ } // direction may be null (reset)

    override fun exhibitorCustomButtonDidClick(
        buttonEvent: ExpoFpResult<ExpoFpCustomButtonEvent>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    override fun visitedDidClick(
        visitedEvent: ExpoFpResult<ExpoFpVisitedClickEvent>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    // Debug-only (fires only in debug mode, see below)
    override fun windowErrorDidReceive(
        error: ExpoFpResult<ExpoFpWindowError>,
        from: ExpoFpLinkType
    ) { /* ... */ }

    override fun consoleMessageDidReceive(
        message: ExpoFpResult<ExpoFpConsoleMessage>,
        from: ExpoFpLinkType
    ) { /* ... */ }
}

Step 2. Attach the Listener

val listener = YourListener()

val presenter = ExpoFpPlan.createPlanPresenter(
    planLink = ExpoFpLinkType.ExpoKey("demo"),
    messageListener = listener
)

Alternatively: set after creation

presenter.setMessageListener(YourListener())

// Later, to remove:
presenter.removeMessageListener()

Tip: Attaching the listener at creation ensures you do not miss early events during initial loading.


Step 3. Use in UI

View-based UI (Activity/Fragment)

class MainActivity : AppCompatActivity() {

    private lateinit var presenter: IExpoFpPlanPresenter
    private val listener = YourListener()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ExpoFpPlan.initialize(this)

        presenter = ExpoFpPlan.createPlanPresenter(
            planLink = ExpoFpLinkType.RawLink("https://demo.expofp.com"),
            messageListener = listener
        )

        val expoView = ExpoFpView(this).apply { attachPresenter(presenter) }
        setContentView(expoView)
    }

    override fun onDestroy() {
        presenter.removeMessageListener()
        super.onDestroy()
    }
}

Jetpack Compose

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ExpoFpPlan.initialize(this)

        val listener = YourListener()
        val presenter = ExpoFpPlan.createPlanPresenter(
            planLink = ExpoFpLinkType.RawLink("https://demo.expofp.com"),
            messageListener = listener
        )

        setContent {
            AndroidView(factory = { presenter.getView() })
        }
    }
}

Events Reference

Event (method) Payload type Notes
bookmarkDidClick(bookmark, from) ExpoFpResult<ExpoFpBookmark> User tapped a bookmark.
boothDidClick(boothEvent, from) ExpoFpResult<ExpoFpBoothClickEvent> Booth pressed on the plan.
categoryDidClick(category, from) ExpoFpResult<ExpoFpCategory> Category selected.
currentFloorDidChange(floor, from) ExpoFpResult<ExpoFpFloor> Current floor changed.
currentPositionDidChange(position, from) ExpoFpResult<ExpoFpPosition> Position updates (if location provider is active).
detailsDidClick(details, from) ExpoFpResult<ExpoFpDetails?> Details selected/deselected. null means deselected.
directionDidBuild(direction, from) ExpoFpResult<ExpoFpDirection?> Direction built or reset. null on reset.
exhibitorCustomButtonDidClick(buttonEvent, from) ExpoFpResult<ExpoFpCustomButtonEvent> Custom button pressed.
visitedDidClick(visitedEvent, from) ExpoFpResult<ExpoFpVisitedClickEvent> Visited pressed.
windowErrorDidReceive(error, from) ExpoFpResult<ExpoFpWindowError> Debug only: JS window.onerror.
consoleMessageDidReceive(message, from) ExpoFpResult<ExpoFpConsoleMessage> Debug only: Web console messages.

About ExpoFpResult<T>
Handle both success and error branches. Do not assume success-only callbacks. Treat nullable payloads (T?) accordingly.


Debug-only Events

These fire only if you enable debug mode before loading a plan.

// Enable debug mode (do this before creating/loading the presenter)
ExpoFpPlan.isDebugModeEnabled = true
  • WebView window.onerror: windowErrorDidReceive(error, from)ExpoFpResult<ExpoFpWindowError>
  • Web console messages: consoleMessageDidReceive(message, from)ExpoFpResult<ExpoFpConsoleMessage>

Note: Debug mode can slow down initialization and increase logging. Use it only in debug builds.


Best Practices

  • Attach early: Provide messageListener in createPlanPresenter(...) to capture early lifecycle events.
  • Main thread work: Keep callbacks lightweight; offload heavy work to background coroutines.
  • Lifecycle ownership: Create and remove the listener with your screen/component lifecycle to prevent leaks.
  • Null-aware handling: Some payloads can be null (e.g., details, direction on reset). Check before use.
  • Error-aware handling: Always handle ExpoFpResult errors (network, parsing, etc.).
  • Debug mode: Enable only when troubleshooting. Disable in production.