Skip to content

Replace ViewPager2 with Compose-based TaskScreenContainer for Data Collection#3735

Open
shobhitagarwal1612 wants to merge 11 commits into
masterfrom
datacollection-pager
Open

Replace ViewPager2 with Compose-based TaskScreenContainer for Data Collection#3735
shobhitagarwal1612 wants to merge 11 commits into
masterfrom
datacollection-pager

Conversation

@shobhitagarwal1612
Copy link
Copy Markdown
Member

Fixes #3709

This PR overhauls the data collection flow by migrating it to a Compose-based architecture. It removes the legacy ViewPager2 and fragment-based approach (DataCollectionTaskFragment, DataCollectionViewPagerAdapter) in favor of a new TaskScreenContainer. It also refactors event handling to be more deeply integrated with ViewModels.

Key Changes:

  • Replace ViewPager2 and task fragments with Compose-based TaskScreenContainer.
  • Replace custom TaskMapFragmentContainer with the official Compose AndroidFragment.
  • Move map fragment instantiation into individual Compose task screens.
  • Simplify event handling in DataCollectionViewModel by removing MutableSharedFlow and using UI effects.
  • Remove onButtonClicked parameter from task screens and handle clicks via individual ViewModels.
  • Refactor OpenSettings and SetAwaitingPhotoCapture to use DataCollectionViewModel UI effects.
  • Fix failing tests and clean up unused imports/parameters.

Steps to verify:

  1. Open the app and start a new data collection submission.
  2. Verify that you can navigate smoothly between tasks (Next/Previous).
  3. Check map-based tasks (Drop Pin, Draw Area, Capture Location) to ensure the map renders correctly and interactions work as expected.
  4. Test permission dialogs and photo capture to ensure the new UI effects handle them properly.

@andreia-ferreira PTAL?

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 66.37931% with 39 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.01%. Comparing base (8485e39) to head (4b7ec09).

Files with missing lines Patch % Lines
...oid/ui/datacollection/tasks/TaskScreenContainer.kt 52.94% 12 Missing and 4 partials ⚠️
...droid/ui/datacollection/DataCollectionViewModel.kt 38.46% 6 Missing and 2 partials ⚠️
.../android/ui/datacollection/DataCollectionScreen.kt 85.00% 0 Missing and 3 partials ⚠️
...ection/tasks/location/CaptureLocationTaskScreen.kt 50.00% 3 Missing ⚠️
...ndroid/ui/datacollection/DataCollectionFragment.kt 75.00% 1 Missing ⚠️
...ui/datacollection/tasks/AbstractTaskMapFragment.kt 0.00% 0 Missing and 1 partial ⚠️
...oid/ui/datacollection/tasks/date/DateTaskScreen.kt 50.00% 0 Missing and 1 partial ⚠️
...lection/tasks/instruction/InstructionTaskScreen.kt 50.00% 0 Missing and 1 partial ⚠️
...ui/datacollection/tasks/number/NumberTaskScreen.kt 50.00% 0 Missing and 1 partial ⚠️
...d/ui/datacollection/tasks/photo/PhotoTaskScreen.kt 50.00% 0 Missing and 1 partial ⚠️
... and 3 more
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3735      +/-   ##
============================================
+ Coverage     67.99%   68.01%   +0.02%     
+ Complexity     1612     1596      -16     
============================================
  Files           370      368       -2     
  Lines          9563     9490      -73     
  Branches       1248     1241       -7     
============================================
- Hits           6502     6455      -47     
+ Misses         2382     2365      -17     
+ Partials        679      670       -9     
Files with missing lines Coverage Δ
...d/ui/datacollection/tasks/AbstractTaskViewModel.kt 93.33% <100.00%> (+0.11%) ⬆️
...oid/ui/datacollection/tasks/DataCollectionEvent.kt 100.00% <100.00%> (ø)
...ion/tasks/location/CaptureLocationTaskViewModel.kt 93.47% <100.00%> (+0.14%) ⬆️
...n/tasks/multiplechoice/MultipleChoiceTaskScreen.kt 52.27% <100.00%> (ø)
...ui/datacollection/tasks/point/DropPinTaskScreen.kt 66.66% <100.00%> (+4.16%) ⬆️
...datacollection/tasks/polygon/DrawAreaTaskScreen.kt 47.31% <100.00%> (+3.63%) ⬆️
...ndroid/ui/datacollection/DataCollectionFragment.kt 92.59% <75.00%> (-3.41%) ⬇️
...ui/datacollection/tasks/AbstractTaskMapFragment.kt 60.27% <0.00%> (ø)
...oid/ui/datacollection/tasks/date/DateTaskScreen.kt 76.56% <50.00%> (-0.37%) ⬇️
...lection/tasks/instruction/InstructionTaskScreen.kt 87.50% <50.00%> (-0.74%) ⬇️
... and 9 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Collaborator

@andreia-ferreira andreia-ferreira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only issue I found was when restoring a draft where the current task was conditional. Clicking on any of the previous/next buttons makes the app crash. Tested this behavior on master to confirm it's not an existing issue and couldn't reproduce

Screen_recording_20260513_175154.webm

tested on API 24 and 36 and happens on both

* @param onAllowLocationClicked Callback when the allow location button is clicked in the dialog.
* @param onOpenSettings Callback to open app settings.
* @param onButtonClicked Callback when a button is clicked.
* @param mapContent Composable for rendering the map.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this parameter is still in the arguments so it should be part of the kdoc

* routing.
*
* @param viewModel The view model for this task.
* @param mapContent Composable for rendering the map.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: same comment as above. The params here in general don't match the ones in the composable

* @param onLoiNameAction Callback when user interacts with the LOI name dialog.
* @param onInstructionsDismiss Callback when user dismisses the instructions dialog.
* @param onDismissSelfIntersectionDialog Callback when the self-intersection dialog is dismissed.
* @param mapContent Composable for rendering the map.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: same comment as above

Comment on lines +329 to +334
DataCollectionEvent.OpenSettings ->
viewModelScope.launch { _uiEffects.send(DataCollectionUiEffect.OpenSettings) }
is DataCollectionEvent.SetAwaitingPhotoCapture ->
viewModelScope.launch {
_uiEffects.send(DataCollectionUiEffect.SetAwaitingPhotoCapture(event.awaiting))
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: the logic for each of these events could be extracted to a separate method like the events above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[KMP] Migrate ViewPager2 in DataCollectionFragment with a Compose HorizontalPager

2 participants