Skip to content

Getting Started

petterp edited this page Aug 30, 2026 · 2 revisions

Getting Started

This page covers two things: which modules to depend on, and the fewest lines that get each of the four hosts running. Detailed usage for each host lives on its own page.

Modules & dependencies

Module Purpose minSdk Floor imposed on consumers
floatingx-core State machine, anchor layout, gestures, features, registry, FxControl 21 androidx.core 1.13.1compileSdk ≥ 34
floatingx-app AppHost: global window that follows the foreground Activity 21 same as core
floatingx-system SystemHost: WindowManager window, overlay permission, keyboard support 21 same as core
floatingx-scope ViewGroupHost / FragmentHost: local windows (androidx.fragment is compileOnly) 21 same as core
floatingx-compose compose {} content, FxComposeOwner, stateFlow() / positionFlow() 23 compose-ui 1.11.4compileSdk ≥ 35, lifecycle 2.10.0

Kotlin metadata of every module follows Kotlin 2.2, so consumers need Kotlin ≥ 2.1.

Gradle

dependencies {
    implementation "io.github.petterpx:floatingx-core:3.0.0"      // pulled in by every other module; declare only when using core alone
    implementation "io.github.petterpx:floatingx-app:3.0.0"       // app-level global window (follows Activity)
    implementation "io.github.petterpx:floatingx-system:3.0.0"    // system window (WindowManager + permission)
    implementation "io.github.petterpx:floatingx-scope:3.0.0"     // local window (Activity / ViewGroup / Fragment)
    implementation "io.github.petterpx:floatingx-compose:3.0.0"   // Jetpack Compose content
}

core comes transitively (api) with each of the other four modules, so it rarely needs to be declared; everything else is opt-in. Skip system windows and no WindowManager code comes along; skip Compose and no Compose dependency comes along.

No AndroidManifest setup needed

The app and system modules ship their own manifests: floatingx-app registers the Activity tracker from a ContentProvider at process start, so install picks up the current foreground Activity no matter when you call it; floatingx-system already declares the SYSTEM_ALERT_WINDOW permission and the transparent permission-request Activity — you don't have to configure anything.

Version requirements

  • minSdk 21: core / app / system / scope.
  • minSdk 23: floatingx-compose (Compose's own floor).
  • compileSdk ≥ 34 (imposed by core), and compileSdk ≥ 35 when you use floatingx-compose.
  • Kotlin ≥ 2.1, Java 17 toolchain.

Minimal setup for the four hosts

App-level global window

val control = FloatingX.install("music") {
    layout(R.layout.fx_card)
    anchor(FxGravity.CENTER_END, dy = 120f)
    margin(top = 24f, bottom = 24f)
    adsorb(FxAdsorb.Edges(setOf(FxEdge.START, FxEdge.END), halfHide = FxHalfHide(0.3f)))
    persist(FxSpStorage(app))
    enableLog("Fx-demo")
    appHost(app) {
        // pass a Class, not a class name: matched with isInstance, so subclasses are hit too
        blacklist(SplashActivity::class.java)
    }
}
control.show()

Black / white lists, filter, attach target, theme and the Java builder are on App Host.

System window

FloatingX.install("sys") {
    layout(R.layout.fx_input)
    anchor(FxGravity.TOP_START, dx = 24f, dy = 200f)
    adsorb(FxAdsorb.Edges(setOf(FxEdge.START, FxEdge.END)))
    systemHost(app) {
        permission(FxPermissionStrategy.auto())          // default: request automatically
        // fall back to an app-level window when permission is denied (2.x's SYSTEM_AUTO)
        fallback(AppHost.builder(app).build())
    }
}.show()

The three permission strategies, downgrading, layoutParams customisation, keyboard / back key and installing from a Service are on System Host.

Local window

// Activity: attached to android.R.id.content (must be called after setContentView)
val actFx = fxScope("scope-act") {
    layout(R.layout.fx_card)
    anchor(FxGravity.BOTTOM_END)
    persist(FxSpStorage(this@ScopeHostActivity))
}
actFx.show()

Attaching to any ViewGroup, using it inside a Fragment and the Java entry point are on Scope Host.

Compose

FloatingX.install("compose") {
    compose { control ->
        val vm: CounterViewModel = viewModel()                        // the window's own ViewModelStore
        var count by rememberSaveable { mutableIntStateOf(0) }        // survives container detach
        val state by control.stateFlow().collectAsState()             // FxState
        val pos by control.positionFlow().collectAsState()            // screen coords of the content's top-left
        Surface(shape = CircleShape, modifier = Modifier.size(110.dp)) {
            Column(Modifier.clickable { count++; vm.clicks++ }) {
                Text("count $count")
                Text("${pos.x.toInt()},${pos.y.toInt()} $state")
            }
        }
    }
    anchor(FxGravity.CENTER_START, dy = -100f)
    appHost(app)
}.show()

FxComposeOwner, surviving page changes and stateFlow() / positionFlow() are on Compose.

Next steps

Anchor / margin / overflow / safeArea / adsorption / gestures / animation / modal / persistence live on Configuration; the method reference for FxControl / FxListener / the FloatingX registry is on API Reference.


Back to Home · Related: Configuration · API Reference · Migration from 2.x

Clone this wiki locally