UI: Navigation
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt
- app/src/main/java/com/musagenius/ocrapp/MainActivity.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/editor/ImageEditorScreen.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/ocr/OCRResultScreen.kt
- TODO.md
- app/src/main/res/values/strings.xml
The navigation system in the OCR Android App is built using Jetpack Navigation Compose. It provides a declarative, single-activity architecture for navigating between different composable screens. The core of the system is managed within MainActivity.kt, which hosts a NavHost containing the application's navigation graph.
Routes and their arguments are defined in a type-safe manner using the Screen.kt sealed class. This approach centralizes route definitions and simplifies navigation actions. The primary navigation flow involves capturing or selecting an image, optionally editing it, and then processing it to display the OCR results. The system also includes placeholders for future features like a scan history and settings screen, as outlined in the project's TODO.md.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt, app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt, TODO.md
Architecture Overview
The navigation architecture is composed of three main parts:
NavController: Manages the app's navigation state and back stack. An instance is created usingrememberNavController()inOCRAppNavigation.NavHost: A composable that displays the current destination based on theNavController's state. It links routes (string paths) to their corresponding composable destinations.ScreenSealed Class: A custom class that defines all possible navigation destinations as objects, providing type-safe routes and helper functions for creating routes with arguments.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:53-58
Screen Definitions
All navigation routes are defined in the Screen sealed class. This centralizes route management and provides a type-safe way to reference screens throughout the app. For routes requiring arguments, like ImageEditor and Results, a createRoute function is provided to correctly format and encode the argument.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt:6-23
The structure of the Screen class is as follows:
This diagram shows the sealed class Screen and its subtypes, each representing a unique destination in the app.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt:6-23
Navigation Routes
The following table summarizes the routes defined in the application.
| Screen | Route String | Argument(s) | Description |
|---|---|---|---|
Camera | camera | None | The initial screen for capturing images. |
ImageEditor | image_editor/{imageUri} | imageUri (String) | Allows rotating an image before OCR. |
Results | results/{imageUri} | imageUri (String) | Displays the extracted text and OCR metadata. |
History | history | None | Placeholder for viewing past scans. |
Settings | settings | None | Placeholder for application settings. |
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt:8-23, app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:59-158, app/src/main/res/values/strings.xml:5-7
Navigation Graph and Flow
The navigation graph is defined in the OCRAppNavigation composable within MainActivity.kt. The NavHost is configured with Screen.Camera.route as the starting destination.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:56-58
The primary user flow is as follows:
- The app starts at the
CameraScreen. - If an image is captured directly, the app navigates to
OCRResultScreen. - If an image is selected from the gallery, the app navigates to
ImageEditorScreen. - From
ImageEditorScreen, the user can either cancel (returning toCameraScreen) or save, which navigates toOCRResultScreen. When saving, the editor screen is popped from the back stack to prevent navigating back to it from the results.
This diagram illustrates the main navigation flow:
Argument Passing
The imageUri is passed as a string argument between screens. To ensure the URI is safely transmitted as part of the route, it is URL-encoded before navigation and decoded upon retrieval.
Encoding and Navigation
The createRoute function in the Screen class handles encoding the URI.
// app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt:15-18
fun createRoute(imageUri: String): String {
val encodedUri = Uri.encode(imageUri)
return "results/$encodedUri"
}
Navigation is then triggered with the generated route.
// app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:63-64
onImageCaptured = { imageUri ->
navController.navigate(Screen.Results.createRoute(imageUri.toString()))
},
Decoding and Retrieval
In the destination composable, the argument is retrieved from the NavBackStackEntry and decoded.
// app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:108-115
composable(
route = Screen.Results.route,
// ...
) { backStackEntry ->
val encodedUriString = backStackEntry.arguments?.getString("imageUri")
// ...
val decodedUriString = Uri.decode(encodedUriString)
val imageUri = Uri.parse(decodedUriString)
// ...
}
This ensures that complex URI strings do not break the navigation routing.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt:10-21, app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:82-89, 108-118
Back Stack Management
The navigation logic includes specific back stack management. When navigating from ImageEditorScreen to OCRResultScreen after saving an image, the ImageEditorScreen is removed from the back stack. This is achieved using the popUpTo builder in the navigate call, ensuring that pressing "back" from the OCRResultScreen returns the user directly to the CameraScreen.
// app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:96-99
onImageSaved = { editedUri ->
navController.navigate(Screen.Results.createRoute(editedUri.toString())) {
popUpTo(Screen.Camera.route)
}
},
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:96-99
Placeholder Screens
Screens for future features, such as History and Settings, are already included in the navigation graph. They currently navigate to a generic PlaceholderScreen composable, which displays the screen title and a message indicating it's a future feature. This allows the basic routing to be in place while development on these features is pending.
// app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:128-135
composable(Screen.History.route) {
PlaceholderScreen(
title = "History Screen",
subtitle = "Coming in Phase 4",
onNavigateBack = { navController.popBackStack() }
)
}
This aligns with the development plan outlined in ROADMAP.md and TODO.md.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:127-142, TODO.md
Summary
The navigation in the OCR Android App is robustly implemented using Jetpack Navigation Compose. It employs a Screen sealed class for type-safe route definitions and argument passing, with proper URI encoding to handle data transfer. The navigation graph, centered in MainActivity, defines a clear and logical user flow from image capture to result display, while also providing a scaffold for future screens. Thoughtful back stack management enhances the user experience by creating intuitive navigation paths.
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt, app/src/main/java/com/musagenius/ocrapp/presentation/navigation/Screen.kt