Develop
Develop
Select your platform

Register 2D panels

Updated: Oct 1, 2025

Overview

Using 2D panels requires two steps: registration and spawning them in your scene. This page covers registration.

Registering a panel

Panel registration creates a blueprint for your panel. It does not add the panel to the scene. To spawn a panel into your scene, add an Entity with a Panel component that references this blueprint. Learn more in Spawn and remove 2D panels.
To register a panel, create a PanelRegistration object and configure it for your specific panel. Here is an example PanelRegistration configuration:
import com.meta.spatial.toolkit.PanelRegistration
...

// In your immersive activity, override registerPanels()
// and return a list of PanelRegistration objects
override fun registerPanels(): List<PanelRegistration> {
  return listOf(
      LayoutXMLPanelRegistration( /* registration info */ ),
      ActivityPanelRegistration( /* registration info */ ),
  )
}
Note: The samples in this documentation are using v0.8.0. If you are using an earlier version, see the advanced PanelCreator section below for details on previous APIs.
Register a panel dynamically by calling the registerPanel() API in your immersive activity:
registerPanel(ViewPanelRegistration( /* registration info */ ))
Panel registration involves a few critical elements:
  • Defining an ID for the panel.
  • Determining a UI to render to the panel.
  • Configuring the panel.
  • Hooking-up behavior to layout within the panel.

Define an ID for the panel

Pass a registrationId in the constructor for any PanelRegistration. This is the ID of your blueprint. Use this ID to spawn the panel into the scene using the Panel component on an Entity.
For example:
LayoutXMLPanelRegistration(
    R.id.my_panel,
    ...
)
This registers a panel using R.id.my_panel. You define resource IDs in the res/values/ids.xml file of your application:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="my_panel" type="id"/>
</resources>
Panel ID in res/values/ids.xml
The ID can be any integer. Using a resource ID (R.id.{id here}) is recommended for type safety and to avoid ID conflicts.
Create multiple Entities in your scene with the same panel UI by creating multiple Panel Entities that point to the same PanelRegistration ID.

Determine a UI to render to the panel

The UI you render to your panel can be defined in a few ways:
  1. Layout XML: Use LayoutXMLPanelRegistration to define panel UI using layout XML.
  2. View: Use ViewPanelRegistration to define panel UI using a View at runtime.
  3. Activity: Use ActivityPanelRegistration to define panel UI using an Activity.
  4. Intent: Use IntentPanelRegistration to define panel UI using an Intent (allowing you to pass information along to your inflated Activity).
  5. Media: Take a look at Media panels for more information on registering media panels.
  6. Jetpack Compose: Take a look at Jetpack Compose for more information on registering Jetpack Compose panels.
If you are new to Spatial SDK, start with Jetpack Compose.
Running many activities simultaneously reduces performance. Activity-based panels (activity/intent) have higher performance costs than view-based panels (layout xml/runtime).

Configure the panel

Panels are configured using the settingsCreator callback. For UI panels this means defining a UIPanelSettings object. (For media panels please see Media panels for information on additional PanelSettings types.)
The UIPanelSettings object configures the panel’s size, position, and other properties. It has these settable options:
class UIPanelSettings(
    val shape: UIPanelShapeOptions,
    val display: UIPanelDisplayOptions,
    val rendering: UIPanelRenderOptions,
    val style: PanelStyleOptions,
    val input: PanelInputOptions,
)
  • shape: How the panel looks in 3d. This can be a rectangle or a cylinder.
  • display: Set the resolution of the panel content.
  • rendering: Configure how the panel is rendered including whether it uses a mesh or a layer.
  • style: Set the Android theme for the panel content.
  • input: Configure the input behavior of the panel.
For more information on all of the configuration settings, see 2D panel config and resolution and 2D UI quality.
Here is an example of a panel registration with a fully configured UIPanelSettings object:
LayoutXMLPanelRegistration(
    R.id.my_panel,
    layoutIdCreator = { R.layout.my_layout },
    settingsCreator = {
      UIPanelSettings(
          shape = QuadShapeOptions(width = 0.8f, height = 0.6f),
          display = DpDisplayOptions(width = 400f, height = 300f),
          rendering = UIPanelRenderOptions(),
          style = PanelStyleOptions(themeResourceId = R.style.PanelAppThemeTransparent),
          input = PanelInputOptions(),
      )
    })
Customize the inflated panel using information about the Entity that is inflating the panel. The following example defines a settingsCreator that changes the panel width based on a custom component.
settingsCreator = { ent: Entity ->
      // Use a custom component to attach data to the Entity
      // which is used to change the size of the created panel
      val myComponent = ent.getComponent<MyCustomPanelSizeComponent>()
      UIPanelSettings(
          shape = QuadShapeOptions(width = myComponent.width, height = 1.5f),
          display = ScreenFractionDisplayOptions(),
      )
    },

Hook-up behavior to UI within your panel (Layout XML/view)

When defining a Layout XML or view-based panel, add behavior (like responding to button presses) using the panelSetupWithRootView argument in the constructors for LayoutXMLPanelRegistration and ViewPanelRegistration.
Here is an example of a panel defined by Layout XML that responds to button presses:
LayoutXMLPanelRegistration(
    registrationId = R.id.my_panel
    layoutIdCreator = { R.layout.my_layout },
    settingsCreator = {
      UIPanelSettings(shape = QuadShapeOptions(width = 1.0f, height = 1.5f))
    },
    panelSetupWithRootView = {
        rootView: View,
        _panelSceneObject: PanelSceneObject,
        _entity: Entity ->
      // Set up a button click listener
      rootView.findViewById<Button>(R.id.btn_intent_panel)?.setOnClickListener {
        buttonPushed()
      }
    }
)

Advanced panel registration

Advanced Usage: This section is for developers who need to modify panel settings that aren’t covered by the standard PanelSettings APIs. Most developers won’t need this.
If you need to customize panel behavior beyond what the PanelSettings APIs provide, use PanelCreator to directly create a PanelSceneObject. A PanelSceneObject is the underlying runtime object that manages the panel. Configure it using PanelConfigOptions.
Behind the scenes, the PanelSettings APIs such as UIPanelSettings are convenience functions for constructing PanelConfigOptions. Start with UIPanelSettings to generate the basic configuration, then customize as needed. Here is an example:
import com.meta.spatial.toolkit.PanelCreator
import com.meta.spatial.toolkit.PanelRegistration

PanelCreator(
    registrationId = R.id.custom_panel,
    panelCreator = { entity ->
        // Start with Panel Settings for basic configuration
        val baseSettings = UIPanelSettings(
            shape = QuadShapeOptions(width = 2f, height = 1.5f),
            display = DpDisplayOptions(width = 800f, height = 600f)
        )
        // Convert to PanelConfigOptions and customize further
        val options = baseSettings.toPanelConfigOptions().apply {
            // Access properties not available through UIPanelSettings
            // Here are a few examples of the many things you can set
            mips = 8 // Custom mip levels
            effectShader = "data/shaders/custom/gammaCorrection.frag" // Custom effect shader
            // Custom mesh creator for specialized geometry
            sceneMeshCreator = { texture ->
                // Create custom mesh geometry
                createCustomPanelMesh(texture, entity)
            }
        }
        // Create the panel with custom options
        PanelSceneObject(
            scene,
            spatialContext,
            R.layout.my_custom_layout,
            entity,
            options
        )
    }
)

Design guidelines

Did you find this page helpful?
Thumbs up icon
Thumbs down icon