abstract class GenericPanel<C : PanelContext>(val frontendContext: FrontendContext) : PanelContextProvider<C> , LifecycleOwner

A panel represents the intention of a Frontend to show a fragment. Panels are intended to be presented to the user by the system UI. The system UI decides whether, when and where the fragment is displayed.

A panel is created by a Frontend. The frontend provides context to the panel to complete the task, like the frontendContext. Depending on the purpose of the panel, a frontend also provides additional details, like which album to display, or the ability to add another panel.

When creating a panel, choosing the right panel type is very important. A panel type is a grouping of panels that can be placed in the same panel container. In other words, this is a hint to the system UI as to where to display a panel. See the system UI anatomy for an overview of the built-in panel types. You're not restricted to using the built-in panel types, custom panel types can be supported by a custom system UI.

The panel type can also affect whether and when a panel is displayed. A panel type can have properties that help the system UI to determine this, like MainProcessPanel.priority. The values of these properties can change over time. A panel is a LifecycleOwner to enable this.

The panel type also defines if a panel is able to handle hardware back presses. Some Panel types support hardware back presses out of the box, see IviOnBackPressedCallbackOwner to know more.

When the system UI decides to present a panel, it attaches the IviFragment returned by createInitialFragment to its layout. The created fragment will internally instantiate a ViewModel (FrontendViewModel) with a reference to this panel.

The system UI may choose to show and stop showing the panel more than once. E.g., a panel may be temporarily detached from the system UI if a similar panel with higher priority is offered to the system UI. Each time, a new fragment, along with its ViewModel, is created and destroyed. As such, it's important to consider whether data should be stored in the ViewModel or in a service. Data that is used by the fragment typically belongs in the ViewModel. The ViewModel will be cleared when the panel is detached and attached again. Data that is important to survive detachment should be kept in a service instead.

Service connections for presenting data are commonly in the ViewModel rather than the panel to avoid keeping services alive for panels that are not attached. (Note that if the service requested in the ViewModel is already alive, creating another connection to it is a cheap operation.) It can however be beneficial for the panel to ask for a service connection in its constructor, allowing the service connection to be created by the Frontend and thus stay alive after the panel is destroyed. This allows panel contents to be populated immediately upon showing and is important when a service call must be performed upon the destruction of the panel or ViewModel, as those calls may fail when the service is closed as a result of the panel's or ViewModel's destruction. Similarly, if a call is needed when the panel is removed, it is not sufficient to perform it within ViewModel.onCleared because the ViewModel may never have been created during the panel's lifespan.

Once the panel is added to its frontend, the state is changed from Lifecycle.State.INITIALIZED to Lifecycle.State.CREATED. The lifecycle changes state to Lifecycle.State.STARTED when it is attached to the system UI. The panel can be detached and then attached again.

If the panel is dismissed or removed from the frontend, its lifecycle transitions to Lifecycle.State.DESTROYED after which it may not be added to a frontend again.

A panel instance can only be added to a single Frontend instance. The frontendContext must be the same Frontend.frontendContext instance of the frontend to which this panel will be added.



An entry point for this GenericPanel to communicate with the rest of the system.



Link copied to clipboard
constructor(frontendContext: FrontendContext)


Link copied to clipboard
Link copied to clipboard
val id: Long

Unique identifier of a GenericPanel. Each ID is an increment of the previously created panel's ID, allowing this value to be used for sorting purposes.

Link copied to clipboard

true if the panel is currently attached.

Link copied to clipboard
open override val lifecycle: Lifecycle
Link copied to clipboard

Whether a panel wants to be removed from its frontend.

Link copied to clipboard
val tag: String

The tag to recognise this panel with. Useful in combination with fragment tags to detect which fragment belongs to which panel.

Link copied to clipboard

A destination that the information contained by this panel transitions to when this panel closes. By default it is null, indicating the information does not transition anywhere.

Link copied to clipboard

The source of the information contained by this panel when the information transitions from another panel to this one. By default it is null, indicating the information does not transition from any other particular panel.


Link copied to clipboard

The fragment used when initially showing the panel. The fragment may be recreated by the system UI upon configuration changes.

Link copied to clipboard
operator override fun equals(other: Any?): Boolean
Link copied to clipboard
open override fun getPanelContext(iviFragmentId: IviFragmentId): C

The PanelContext of an IviFragment identified by iviFragmentId.

Link copied to clipboard
override fun hashCode(): Int
Link copied to clipboard

Called when this panel is added to Frontend.panels, allowing it to be shown in the system UI.

Link copied to clipboard
fun onAttached(panelAttachment: PanelAttachment<C>)

Called when the panel is attached to the system UI.

Link copied to clipboard
fun onDetached(panelAttachment: PanelAttachment<C>)

Called when the panel has been detached from the system UI.

Link copied to clipboard

Called when this panel is removed from Frontend.panels, preventing it from being shown in the system UI.

Link copied to clipboard
open override fun toString(): String