🪟 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)