Customizable compass widget for Android with View and Jetpack Compose support.
- π§ Sensor-driven compass rotation with smooth animations
- π¨ Fully customizable colors, degree markers, and orientation labels
- π― Custom needle drawable support
- π Configurable degree steps and border
- π± View-based (XML) and Compose implementations
- β‘ Lightweight with no external dependencies (except Compose for the Compose module)
- π Lifecycle-aware sensor management
For View-based (XML) compass:
dependencies {
implementation("net.kibotu:CompassView:latest-version")
}For Jetpack Compose compass:
dependencies {
implementation("net.kibotu:CompassView-Compose:latest-version")
}Add the JitPack repository:
dependencyResolutionManagement {
repositories {
maven { url = uri("https://jitpack.io") }
}
}Then add the dependency:
dependencies {
// View-based
implementation("com.github.kibotu:CompassView:latest-version")
// Compose
implementation("com.github.kibotu:CompassView:latest-version") {
artifact {
name = "compass-compose"
}
}
}Add the compass to your layout:
<net.kibotu.compassview.Compass
android:id="@+id/compass"
android:layout_width="200dp"
android:layout_height="200dp"
app:degree_color="@color/blue"
app:degrees_step="15"
app:needle="@drawable/ic_needle"
app:orientation_labels_color="@color/red"
app:show_orientation_labels="true"
app:show_degree_value="true"
app:show_border="false"
app:degree_value_color="@color/black"
app:border_color="@color/red" />Listen to sensor events in Kotlin:
val compass = findViewById<Compass>(R.id.compass)
compass.setListener(object : CompassListener {
override fun onSensorChanged(event: SensorEvent) {
Log.d("Compass", "Degree: ${event.values[0]}")
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
Log.d("Compass", "Accuracy: $accuracy")
}
})Use the Compass composable:
import net.kibotu.compassview.compose.Compass
import net.kibotu.compassview.compose.rememberCompassState
@Composable
fun MyScreen() {
val compassState = rememberCompassState(
onSensorChanged = { event ->
Log.d("Compass", "Degree: ${event.values[0]}")
}
)
Compass(
state = compassState,
modifier = Modifier.size(200.dp),
degreeColor = Color.Blue,
degreesStep = 15,
showOrientationLabels = true,
orientationLabelsColor = Color.Red,
showDegreeValue = true,
degreeValueColor = Color.Black,
showBorder = false,
borderColor = Color.Red
)
}| Attribute | Type | Description | Default |
|---|---|---|---|
degree_color |
color | Color of compass degree lines | Black |
degrees_step |
integer | Step between degree markers (must divide 360) | 15 |
needle |
drawable | Custom needle drawable | Default red/white needle |
show_orientation_labels |
boolean | Show N, E, S, W labels | false |
orientation_labels_color |
color | Color of orientation labels | Black |
show_degree_value |
boolean | Show current degree value as text | false |
degree_value_color |
color | Color of degree value text | Black |
show_border |
boolean | Show outer circle border | false |
border_color |
color | Color of border circle | Black |
| Parameter | Type | Description | Default |
|---|---|---|---|
modifier |
Modifier | Modifier for the compass | Modifier |
state |
CompassState | State holder for sensor data | rememberCompassState() |
degreeColor |
Color | Color of compass degree lines | Color.Black |
degreesStep |
Int | Step between degree markers | 15 |
needle |
Painter? | Custom needle painter | Default needle |
showOrientationLabels |
Boolean | Show N, E, S, W labels | false |
orientationLabelsColor |
Color | Color of orientation labels | Color.Black |
showDegreeValue |
Boolean | Show current degree value | false |
degreeValueColor |
Color | Color of degree value text | Color.Black |
showBorder |
Boolean | Show outer circle border | false |
borderColor |
Color | Color of border circle | Color.Black |
onSensorChanged |
((SensorEvent) -> Unit)? | Sensor change callback | null |
onAccuracyChanged |
((Sensor, Int) -> Unit)? | Accuracy change callback | null |
Compass - Custom View that displays a compass
Methods:
setListener(listener: CompassListener?)- Set sensor event listener
CompassListener - Interface for sensor callbacks
interface CompassListener {
fun onSensorChanged(event: SensorEvent)
fun onAccuracyChanged(sensor: Sensor, accuracy: Int)
}Compass - Composable function that displays a compass
rememberCompassState - Creates and remembers a CompassState with lifecycle-aware sensor management
CompassState - State holder for compass data
Properties:
currentDegree: Float- Current rotation degreedirection: String- Current direction (e.g., "45.0Β° NE")
- View: Custom
RelativeLayoutwith sensor-driven rotation usingRotateAnimation - Compose: Composable using
Canvasfor drawing andanimateFloatAsStatefor smooth rotation - Both implementations use Android's
SensorManagerwithTYPE_ORIENTATIONsensor - Lifecycle-aware sensor registration/unregistration
No special permissions required. The compass uses the device's orientation sensor, which is available by default. If the sensor is not available, the compass will not rotate.
- minSdk: 23 (Android 6.0)
- targetSdk: 36 (Android 15)
- Kotlin: 2.3.10
- Gradle: 9.4.0
Copyright 2018 Belkilani Ahmed Radhouane, Jan Rabe 2025
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
