This example demonstrates smooth camera animations in OpenMapView, showing how to animate map position and zoom level changes with customizable durations and completion callbacks.
- Animated camera movements to specific locations
- Smooth zoom animations (zoom in/out)
- Different animation durations (fast: 500ms, normal: 1000ms, slow: 2000ms)
- Animation completion callbacks (onFinish, onCancel)
- Animation cancellation with stopAnimation()
- Multiple markers as animation targets
- Open the OpenMapView project in Android Studio
- Select
examples.Example05Camerafrom the run configuration dropdown - Click Run (green play button)
- Deploy to device or emulator
# From project root - build, install, and launch
./gradlew :examples:Example05Camera:installDebug
# Launch the app
adb shell am start -n de.afarber.openmapview.example05camera/.MainActivitymapView.animateCamera(
CameraUpdateFactory.newLatLngZoom(targetLocation, 15.0),
1000, // 1 second duration
object : CancelableCallback {
override fun onFinish() {
Toast.makeText(context, "Animation finished", Toast.LENGTH_SHORT).show()
}
override fun onCancel() {
Toast.makeText(context, "Animation cancelled", Toast.LENGTH_SHORT).show()
}
}
)// Zoom in with 500ms animation
mapView.animateCamera(
CameraUpdateFactory.zoomIn(),
500
)
// Zoom out with 500ms animation
mapView.animateCamera(
CameraUpdateFactory.zoomOut(),
500
)// Cancel any running animation
mapView.stopAnimation()// Jump to location immediately without animation
mapView.moveCamera(
CameraUpdateFactory.newLatLngZoom(location, 14.0)
)Factory for creating camera update operations:
newLatLng(LatLng)- Move to location, keep current zoomnewLatLngZoom(LatLng, Double)- Move to location with specific zoomnewCameraPosition(CameraPosition)- Full control over camera statezoomIn()- Increment zoom by 1zoomOut()- Decrement zoom by 1zoomTo(Double)- Set specific zoom levelzoomBy(Double)- Adjust zoom by amount (positive or negative)
// Default 250ms duration, no callback
animateCamera(cameraUpdate)
// Custom duration, no callback
animateCamera(cameraUpdate, durationMs)
// Custom duration with callback
animateCamera(cameraUpdate, durationMs, listener)Callback interface for animation lifecycle:
onFinish()- Called when animation completes normallyonCancel()- Called when animation is interrupted by stopAnimation() or new animation
moveCamera()- Instant camera update, no animationanimateCamera()- Smooth interpolated transition
- Location Buttons - Click "Loc 1", "Loc 2", "Loc 3" to animate to different markers
- Different Durations - Notice Location 3 uses 2 second animation (slower)
- Zoom Controls - Use + and - buttons for smooth zoom animations
- Callbacks - Location 1 shows toast messages on animation finish/cancel
- Stop Button - Click during animation to cancel and see onCancel callback
- Sequential Animations - Start animation, then immediately click another location (first animation cancels)
This example sets up three marker locations around Bochum, Germany:
| Location | Coordinates | Animation Duration | Callbacks |
|---|---|---|---|
| Location 1 | (51.4700, 7.2400) | 1000ms | Yes (toast) |
| Location 2 | (51.4620, 7.2600) | 1000ms | No |
| Location 3 | (51.4550, 7.2350) | 2000ms | No |
- Uses Kotlin coroutines for smooth frame-by-frame updates
- Linear interpolation between start and end positions
- 60 FPS target (16ms frame delay)
- Automatically handles map tile loading during animation
- Lifecycle-aware: animations cancelled when activity destroyed
- Animations run in MapController's coroutine scope
- Automatic cleanup via existing lifecycle hooks
- No memory leaks when activity is destroyed
- onDestroy() cancels all running animations
- Efficient coroutine-based implementation
- Minimal CPU usage during animation
- Smooth rendering on all supported devices
- Tile downloads continue during animation
val distance = calculateDistance(currentPosition, targetPosition)
val duration = (distance * 100).toInt().coerceIn(500, 3000)
mapView.animateCamera(
CameraUpdateFactory.newLatLng(targetPosition),
duration
)mapView.animateCamera(
CameraUpdateFactory.newLatLng(location1),
1000,
object : CancelableCallback {
override fun onFinish() {
// Start second animation when first completes
mapView.animateCamera(
CameraUpdateFactory.zoomIn(),
500
)
}
override fun onCancel() {
// Handle cancellation
}
}
)// This will be available in future versions
val bounds = LatLngBounds.builder()
.include(marker1.position)
.include(marker2.position)
.include(marker3.position)
.build()
mapView.animateCamera(
CameraUpdateFactory.newLatLngBounds(bounds, padding)
)Default Center: Bochum, Germany (51.4620°N, 7.2480°E) at zoom 13.0
All three marker locations are positioned around Bochum within approximately 2km radius.
