Skip to content

[Refactor] Convert date task fragment to compose#3552

Open
shobhitagarwal1612 wants to merge 6 commits intomasterfrom
compose-date-fragment
Open

[Refactor] Convert date task fragment to compose#3552
shobhitagarwal1612 wants to merge 6 commits intomasterfrom
compose-date-fragment

Conversation

@shobhitagarwal1612
Copy link
Member

@shobhitagarwal1612 shobhitagarwal1612 commented Feb 14, 2026

Towards #3549

Before:

date.task.-.compose.-.before.webm

After:

date.task.-.compose.-.after.webm

@andreia-ferreira PTAL?

* Create `DateTaskScreen` Composable using `OutlinedTextField` to replace the XML-based layout.
* Remove `date_task_frag.xml` and associated data binding logic from `DateTaskFragment`.
* Update `DateTaskFragment` to use `createComposeView` and `collectAsStateWithLifecycle` for state management.
* Refactor `DateTaskFragmentTest` to use `composeTestRule` for UI verification and interactions.
@auto-assign auto-assign bot requested a review from anandwana001 February 14, 2026 10:04
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @shobhitagarwal1612, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly modernizes the date task component by migrating its user interface from the legacy Android View system to Jetpack Compose. This change streamlines the UI implementation, enhances maintainability, and updates the associated test suite to align with the new Compose-based interactions, ensuring continued functionality and reliability.

Highlights

  • UI Modernization: The DateTaskFragment has been refactored to use Jetpack Compose for its UI, replacing the traditional Android View system and Data Binding.
  • New Compose UI Component: A new DateTaskScreen.kt file was introduced, containing the Composable function responsible for rendering the date input field.
  • Legacy Layout Removal: The date_task_frag.xml layout file, which previously defined the UI, has been removed as its functionality is now handled by Compose.
  • Test Suite Update: The DateTaskFragmentTest.kt file has been updated to reflect the UI changes, transitioning from Espresso-based testing to Jetpack Compose testing APIs.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • app/src/main/java/org/groundplatform/android/ui/datacollection/tasks/date/DateTaskFragment.kt
    • Removed LiveData and MutableLiveData for date text and hint, transitioning to Compose state management.
    • Eliminated the onTaskViewAttached override, as its logic is now handled within the Compose lifecycle.
    • Replaced the inflation of DateTaskFragBinding with a call to createComposeView, embedding the new DateTaskScreen composable.
    • Updated the visibility of showDateDialog to private, aligning with its internal usage within the fragment.
    • Imported necessary Compose-related classes such as getValue, remember, LocalContext, and collectAsStateWithLifecycle.
    • Added import for java.util.Date to support date formatting within Compose.
    • Removed kotlinx.coroutines.flow imports that were previously used with LiveData.
  • app/src/main/java/org/groundplatform/android/ui/datacollection/tasks/date/DateTaskScreen.kt
    • Added a new Composable function, DateTaskScreen, to render the date input field using Material Design's OutlinedTextField.
    • Implemented interaction handling for onDateClick using MutableInteractionSource and LaunchedEffect to detect press interactions.
    • Included a preview function, DateTaskScreenPreview, to facilitate UI development and testing in isolation.
  • app/src/main/res/layout/date_task_frag.xml
    • Removed the entire XML layout file, as its UI definition has been fully replaced by the new Jetpack Compose implementation.
  • app/src/test/java/org/groundplatform/android/ui/datacollection/tasks/date/DateTaskFragmentTest.kt
    • Replaced Espresso imports and usage with Jetpack Compose testing APIs, including onNodeWithTag, assertIsDisplayed, assertTextContains, and performClick.
    • Removed outdated TODO comments related to testing, reflecting the updated testing approach.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully refactors the DateTaskFragment from using Android Views with data binding to Jetpack Compose. The XML layout has been removed and replaced with a new DateTaskScreen composable, and the fragment now hosts this composable. The corresponding tests have also been updated to use the Compose test framework instead of Espresso. The changes are well-executed and improve the maintainability of the code by adopting modern Android development practices. I have a couple of suggestions to make the code even more idiomatic and readable.

@shobhitagarwal1612
Copy link
Member Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully refactors the DateTaskFragment from using XML layouts to Jetpack Compose, which is a great improvement. The code is now cleaner and more aligned with modern Android development practices. The related XML layout and string resources have been correctly removed, and the tests have been migrated to use Compose testing APIs.

I've added a few suggestions to further improve the code:

  • In DateTaskScreen.kt, I've suggested a more idiomatic way to handle clicks on the read-only text field.
  • In DateTaskFragmentTest.kt, I've pointed out that hardcoding string literals in tests can make them brittle and suggested a way to make them more robust by generating the expected values dynamically.

Comment on lines +48 to +67
val interactionSource = remember { MutableInteractionSource() }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
if (interaction is PressInteraction.Release) {
onDateClick()
}
}
}

Column(modifier = modifier) {
// TODO: Replace with simple text field.
OutlinedTextField(
value = dateText,
onValueChange = {},
readOnly = true,
placeholder = { Text(hintText) },
modifier = Modifier.width(200.dp).testTag("dateInputText"),
interactionSource = interactionSource,
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation for handling clicks on the OutlinedTextField using MutableInteractionSource and LaunchedEffect is more complex than necessary for this use case. A more idiomatic and simpler approach in Jetpack Compose is to use the Modifier.clickable directly on the OutlinedTextField. This simplifies the code, improves readability, and removes unnecessary boilerplate.

  Column(modifier = modifier) {
    // TODO: Replace with simple text field.
    OutlinedTextField(
      value = dateText,
      onValueChange = {},
      readOnly = true,
      placeholder = { Text(hintText) },
      modifier = Modifier
        .width(200.dp)
        .testTag("dateInputText")
        .clickable { onDateClick() },
    )
  }

.check(matches(withText("")))
.check(matches(isDisplayed()))
.check(matches(isEnabled()))
composeTestRule.onNodeWithTag("dateInputText").assertIsDisplayed().assertTextContains("M/D/YY")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Hardcoding the expected hint text "M/D/YY" makes this test brittle as it depends on the default locale of the test environment. It's better to dynamically generate the expected hint string in the same way it's generated in the DateTaskFragment, using DateFormat.getDateFormat(context). This will make the test more robust and less likely to fail if the locale changes.

You will need to add the following imports:

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import java.text.SimpleDateFormat
import android.text.format.DateFormat
Suggested change
composeTestRule.onNodeWithTag("dateInputText").assertIsDisplayed().assertTextContains("M/D/YY")
val context = ApplicationProvider.getApplicationContext<Context>()
val expectedHint = (DateFormat.getDateFormat(context) as SimpleDateFormat).toPattern().uppercase()
composeTestRule.onNodeWithTag("dateInputText").assertIsDisplayed().assertTextContains(expectedHint)

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.

1 participant