Skip to content

🪟 Floating Overlay (Picture-in-Picture) Widget ​

The :speed-overlay module provides a lightweight, circular Floating Speedometer Widget (PipWidget) designed to hover above third-party navigation apps (such as Google Maps, Waze, or delivery driver apps) using Android's SYSTEM_ALERT_WINDOW.


🎯 Key Capabilities ​

  • Floating Screen Overlay: Stays pinned on top of any navigation or dispatch app.
  • Dynamic Ring Warnings: Animates border colors between Safe (Green), Over-Speed (Red), and Under-Speed (Cyan).
  • Translucent Glassmorphism: Semi-transparent dark background (0x66000000) prevents obscuring navigation map turns.
  • Decoupled Architecture: Pure Jetpack Compose widget with zero Activity lifecycle dependencies.

📦 Gradle Dependency ​

Add :speed-overlay to your build.gradle.kts:

kotlin
dependencies {
    implementation(platform("com.vegsahayyak:speed-bom:2.2.0"))
    implementation("com.vegsahayyak:speed-core")
    implementation("com.vegsahayyak:speed-overlay")
}

💻 Basic Usage (PipWidget) ​

kotlin
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.vegsahayyak.speedoverlay.PipWidget
import com.vegsahayyak.speedoverlay.PipWidgetConfig

@Composable
fun FloatingSpeedometer(
    currentSpeed: Float,
    isOverLimit: Boolean,
    isUnderLimit: Boolean = false
) {
    PipWidget(
        speed = currentSpeed,
        unitLabel = "km/h",
        isOverLimit = isOverLimit,
        isUnderLimit = isUnderLimit
    )
}

🎨 Customizing Brand Colors (PipWidgetConfig) ​

You can fully customize size, typography, and alert colors via PipWidgetConfig:

kotlin
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.vegsahayyak.speedoverlay.PipWidgetConfig

val customFleetOverlayConfig = PipWidgetConfig(
    size = 110.dp,
    safeColor = Color(0xFF00E676),          // Neon Green
    warningColor = Color(0xFFFF1744),       // Bright Crimson Red
    underSpeedColor = Color(0xFF00E5FF),    // Electric Cyan
    backgroundColor = Color(0x99000000),    // Dark Glass
    speedTextSize = 40.sp,
    unitTextSize = 13.sp,
    textColor = Color.White
)

PipWidget(
    speed = currentSpeed,
    unitLabel = "mph",
    isOverLimit = isOverLimit,
    config = customFleetOverlayConfig
)

🛠️ Displaying via Android WindowManager ​

To render PipWidget as a system overlay above other applications:

1. Declare Permission in AndroidManifest.xml ​

xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2. Request Permission at Runtime ​

kotlin
if (!Settings.canDrawOverlays(context)) {
    val intent = Intent(
        Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
        Uri.parse("package:${context.packageName}")
    )
    context.startActivity(intent)
}

3. Attach Compose View to WindowManager ​

kotlin
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager

val layoutParams = WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
    else
        WindowManager.LayoutParams.TYPE_PHONE,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    PixelFormat.TRANSLUCENT
).apply {
    gravity = Gravity.TOP or Gravity.START
    x = 100
    y = 200
}

val composeView = ComposeView(context).apply {
    setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnDetachedFromWindow)
    setContent {
        PipWidget(
            speed = currentSpeedKmh,
            unitLabel = "km/h",
            isOverLimit = currentSpeedKmh > 80f
        )
    }
}

windowManager.addView(composeView, layoutParams)

Released under Commercial Enterprise License. Follow us on LinkedIn | Contact Us.