Skip to content

ADFA-3123 | Adaptive navigation patterns#1055

Merged
jatezzz merged 5 commits intostagefrom
feat/ADFA-3123-adaptive-navigation-patterns
Mar 11, 2026
Merged

ADFA-3123 | Adaptive navigation patterns#1055
jatezzz merged 5 commits intostagefrom
feat/ADFA-3123-adaptive-navigation-patterns

Conversation

@jatezzz
Copy link
Collaborator

@jatezzz jatezzz commented Mar 9, 2026

This PR refactors the UI to properly support adaptive navigation patterns across different screen sizes and orientations, specifically addressing the editor's toolbars and the project template list.

Changes include:

  • Editor Toolbars: Replaced imperative view manipulation in BaseEditorActivity with a native FlexboxLayout in content_editor.xml. This automatically handles wrapping the ProjectActionsToolbar below the title_toolbar on smaller screens and places them side-by-side on larger screens (like tablets or in landscape mode), eliminating the need for complex layout calculations in code.
  • Template List: Migrated from a FlexboxLayoutManager with a custom GlobalLayoutListener to a dynamic GridLayoutManager in TemplateListFragment. This natively adjusts the number of columns (between 1 and 4) based on the available screen width, providing a much smoother and more performant reflow when resizing the window (e.g., in DeX mode) or rotating the device.
  • Template Items: Updated layout_template_list_item.xml to use match_parent widths, ensuring the cards properly fill their assigned grid columns without leaving awkward empty spaces.
  • Cleanup: Removed unused diff calculation logic from TemplateListAdapter.

Details

1000097917.mp4

Ticket

ADFA-3123

Observation

The use of GridLayoutManager combined with onConfigurationChanged for the template list provides a significant performance improvement over the previous GlobalLayoutListener approach, especially in desktop-like environments (Samsung DeX) where window resizing triggers frequent layout passes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Removes orientation-driven toolbar rearrangement and DiffUtil list diffing; replaces Flexbox-based template grid with a GridLayoutManager that recalculates span counts on configuration changes; refactors the editor AppBar to a FlexboxLayout containing a ProjectActionsToolbar and adjusts related layout widths and item sizing.

Changes

Cohort / File(s) Summary
Toolbar Configuration Simplification
app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
Removed syncProjectToolbarRowForOrientation and its invocations; removed unused LinearLayout import; simplified toolbar title TextView lookup.
Template Adapter Simplification
app/src/main/java/com/itsaky/androidide/adapters/TemplateListAdapter.kt
Removed DiffUtil-based diffing and fillDiff logic; eliminated artificial list growth and diff dispatch; minor lambda parameter adjustment in long-press tooltip handling.
Template List Fragment — Layout & Span Logic
app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt
Replaced Flexbox-based layout usage with GridLayoutManager (initial span=1); added onConfigurationChanged and updateSpanCount() to compute and apply span counts; removed Flexbox-specific listeners while keeping window insets and tooltip behavior.
Editor AppBar UI (combined container)
app/src/main/res/layout/content_editor.xml, app/src/main/res/layout-land/content_editor.xml
Replaced AppBar container with FlexboxLayout that encloses the title MaterialToolbar and a new ProjectActionsToolbar; adjusted flex attributes, sizing, margins, and wrapping for responsive behavior.
Project Actions Toolbar Width Adjustment
common/src/main/res/layout/project_actions_toolbar.xml
Changed android:layout_width from match_parent to wrap_content on the MaterialToolbar and its inner HorizontalScrollView.
Template Item Width Change
app/src/main/res/layout/layout_template_list_item.xml
Changed MaterialCardView and inner LinearLayout width from wrap_content to match_parent so items occupy full width.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • itsaky-adfa
  • jomen-adfa
  • hal-eisen-adfa

Poem

"I hopped through XML and Kotlin with a grin,
Pushed toolbars to flex and let grids march in.
Cards stretch wider, spans find their place,
I left a carrot-shaped gap in code—my trace. 🥕🐇"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective of the PR: implementing adaptive navigation patterns across different screen sizes and orientations.
Description check ✅ Passed The description is comprehensive and directly related to all the changes in the PR, explaining the rationale and implementation details for each modification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ADFA-3123-adaptive-navigation-patterns

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt`:
- Around line 79-84: The tooltip is being anchored to binding.root inside the
setOnLongClickListener attached to binding.exitButton, which can position it far
from the pressed control; update the call to
TooltipManager.showIdeCategoryTooltip (inside the
binding.exitButton.setOnLongClickListener block) to use the exit button as the
anchor (e.g., anchorView = binding.exitButton or the listener's view parameter)
while keeping context=requireContext() and tag=EXIT_TO_MAIN so the tooltip
appears next to the long-pressed button.
- Around line 68-73: The span calculation currently uses
resources.configuration.screenWidthDp; change to compute span count from the
actual RecyclerView width by adding a helper method (e.g.,
updateSpanCount(minItemWidthDp: Int)) in TemplateListFragment that measures
binding.list.width (after layout) and sets gridLayoutManager.spanCount
accordingly, call this helper from binding.list.doOnLayout for initial setup and
from onConfigurationChanged() to recompute on rotations/size changes; ensure you
keep the GridLayoutManager instance (gridLayoutManager) and update its spanCount
rather than recreating the adapter or list.

In `@app/src/main/res/layout/content_editor.xml`:
- Around line 65-74: The ProjectActionsToolbar is declared wrap_content but
inflates project_actions_toolbar.xml whose root MaterialToolbar uses
android:layout_width="match_parent", causing measurement ambiguity; open
project_actions_toolbar.xml and change the root MaterialToolbar's
android:layout_width to "wrap_content" (and likewise change any immediate child
views that use match_parent to wrap_content or use wrap_content with appropriate
paddings) so the custom view ProjectActionsToolbar can size itself correctly
within the FlexboxLayout.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c2c5a9c-d4dd-4eef-8f67-57efbc14f805

📥 Commits

Reviewing files that changed from the base of the PR and between 5a56a46 and b66cbf0.

📒 Files selected for processing (5)
  • app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
  • app/src/main/java/com/itsaky/androidide/adapters/TemplateListAdapter.kt
  • app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt
  • app/src/main/res/layout/content_editor.xml
  • app/src/main/res/layout/layout_template_list_item.xml
💤 Files with no reviewable changes (1)
  • app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt

@dara-abijo-adfa dara-abijo-adfa requested a review from a team March 10, 2026 10:30
@jatezzz jatezzz force-pushed the feat/ADFA-3123-adaptive-navigation-patterns branch from b66cbf0 to 290fe77 Compare March 10, 2026 13:48
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt (1)

99-111: Consider using actual RecyclerView width for span calculation.

The current approach uses orientation and item count, but doesn't account for the actual available width of binding.list. This can cause issues in constrained layouts (split-screen, foldables, embedded containers) where the RecyclerView may be narrower than expected.

Using binding.list.width after layout would provide more accurate span counts across all scenarios.

Suggested approach using actual width
+import androidx.core.view.doOnLayout
 ...
+	private val minItemWidthDp = 160
+
 	override fun onConfigurationChanged(newConfig: Configuration) {
 		super.onConfigurationChanged(newConfig)
-
-		updateSpanCount()
+		_binding?.list?.post { updateSpanCount() }
 	}
 
 	private fun updateSpanCount() {
-		val isLandscape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
-		val maxSpans = if (isLandscape) 6 else 4
-
+		val listWidthPx = binding.list.width
+		if (listWidthPx <= 0) return
+		
+		val minItemWidthPx = (minItemWidthDp * resources.displayMetrics.density).toInt()
 		val itemCount = binding.list.adapter?.itemCount ?: 0
-
-		val optimalSpans = maxOf(1, minOf(maxSpans, itemCount))
-
+		val widthBasedSpans = (listWidthPx / minItemWidthPx).coerceIn(1, 6)
+		val optimalSpans = minOf(widthBasedSpans, maxOf(1, itemCount))
+		
 		val layoutManager = binding.list.layoutManager as? GridLayoutManager
 		if (layoutManager != null && layoutManager.spanCount != optimalSpans) {
 			layoutManager.spanCount = optimalSpans
 		}
 	}

Also update the initial setup to use doOnLayout:

binding.list.layoutManager = gridLayoutManager
binding.list.doOnLayout { updateSpanCount() }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt`
around lines 99 - 111, The updateSpanCount currently bases spans on orientation
and item count only; change it to measure the actual available width of
binding.list (use binding.list.width after layout) and compute optimalSpans from
availableWidth divided by a target minimum column width (e.g.,
desiredItemMinWidth), clamped between 1 and maxSpans; update the
GridLayoutManager.spanCount accordingly in updateSpanCount; also ensure
updateSpanCount is invoked after layout by calling binding.list.doOnLayout {
updateSpanCount() } (and/or attach an OnLayoutChangeListener) where the layout
manager is set so width measurement is valid.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt`:
- Around line 99-111: The updateSpanCount currently bases spans on orientation
and item count only; change it to measure the actual available width of
binding.list (use binding.list.width after layout) and compute optimalSpans from
availableWidth divided by a target minimum column width (e.g.,
desiredItemMinWidth), clamped between 1 and maxSpans; update the
GridLayoutManager.spanCount accordingly in updateSpanCount; also ensure
updateSpanCount is invoked after layout by calling binding.list.doOnLayout {
updateSpanCount() } (and/or attach an OnLayoutChangeListener) where the layout
manager is set so width measurement is valid.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 46fe4dd9-d078-4c5b-9a0b-dd6e86b9cacd

📥 Commits

Reviewing files that changed from the base of the PR and between b66cbf0 and 290fe77.

📒 Files selected for processing (6)
  • app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
  • app/src/main/java/com/itsaky/androidide/adapters/TemplateListAdapter.kt
  • app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt
  • app/src/main/res/layout/content_editor.xml
  • app/src/main/res/layout/layout_template_list_item.xml
  • common/src/main/res/layout/project_actions_toolbar.xml
💤 Files with no reviewable changes (1)
  • app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/res/layout/layout_template_list_item.xml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src/main/res/layout-land/content_editor.xml (1)

41-47: Remove the unsupported layout_weight attribute from the Flexbox child.

FlexboxLayout does not honor android:layout_weight—that attribute is for LinearLayout only. This row uses FlexboxLayout and already declares app:layout_flexGrow="1" for expansion. Remove the redundant android:layout_weight on line 47.

♻️ Suggested cleanup
             <com.google.android.material.appbar.MaterialToolbar
                 android:id="@+id/title_toolbar"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 app:layout_flexGrow="1"
                 app:layout_flexShrink="0"
-                android:layout_weight="1"
                 android:minHeight="0dp"
                 android:padding="0dp"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/res/layout-land/content_editor.xml` around lines 41 - 47, Remove
the unsupported android:layout_weight attribute from the MaterialToolbar element
(id "@+id/title_toolbar") because FlexboxLayout uses
app:layout_flexGrow/app:layout_flexShrink for sizing; delete the
android:layout_weight="1" attribute so the toolbar relies on
app:layout_flexGrow="1" for expansion and avoid redundant/ignored attributes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/main/res/layout-land/content_editor.xml`:
- Around line 41-47: Remove the unsupported android:layout_weight attribute from
the MaterialToolbar element (id "@+id/title_toolbar") because FlexboxLayout uses
app:layout_flexGrow/app:layout_flexShrink for sizing; delete the
android:layout_weight="1" attribute so the toolbar relies on
app:layout_flexGrow="1" for expansion and avoid redundant/ignored attributes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 662f729e-a10f-45e8-bfb0-db44154c60c0

📥 Commits

Reviewing files that changed from the base of the PR and between 5dfa3e2 and 5853d51.

📒 Files selected for processing (2)
  • app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
  • app/src/main/res/layout-land/content_editor.xml

@jatezzz
Copy link
Collaborator Author

jatezzz commented Mar 11, 2026

Fixed for DeX mode

document_5012592404868368195.mp4

@jatezzz jatezzz requested a review from Daniel-ADFA March 11, 2026 17:31
@jatezzz jatezzz force-pushed the feat/ADFA-3123-adaptive-navigation-patterns branch from 0730f9d to 2f409c0 Compare March 11, 2026 17:53
@jatezzz jatezzz requested a review from Daniel-ADFA March 11, 2026 17:54
@jatezzz jatezzz marked this pull request as draft March 11, 2026 21:32
@jatezzz jatezzz marked this pull request as ready for review March 11, 2026 21:33
@jatezzz jatezzz merged commit 26b4268 into stage Mar 11, 2026
2 checks passed
@jatezzz jatezzz deleted the feat/ADFA-3123-adaptive-navigation-patterns branch March 11, 2026 22:14
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.

2 participants