feat(deck-picker): edge to edge support#20964
Conversation
For activities with 'Theme_Dark.Launcher', android:windowBackground is set, but was never removed. On views with transparent backgrounds (such as the Card Browser column headers), this leaked through when edge to edge was enabled Part of issue 17334 - Edge to Edge Assisted-by: Claude Opus 4.7 - diagnostics + fix
Prep for edge-to-edge work. Scrolling tests were attempted, but Roborazzi did not scroll the RecyclerView correctly Issue 17334 Assisted-by: Claude Opus 4.7 - much of the initial implementation
In order to support edge to edge, we needed to move the RecyclerView underneath the nav + "Studied X in Y" TextView. The bottom nav on many Android phones will fade the content underneath it, but different phones have different implementations, using private colors. So we define our own 'BottomFadeFrameLayout' to handle this. Roughly equivalent to the fade on an API 33 emulator ---- The screenshot test did not place the FAB in the correct place vertically. Therefore adjustmnets were made behind an isRobolectric wrapper The last row of the RecyclerView is moved by a few pixels to be directly in-line with the top of the FAB The padding cannot be lower, otherwise the FAB would obscure the counts I attempted to make tests in Roborazzi which scrolled to the bottom of the list, but they were flaky (1px of padding made a huge difference in scroll position) Issue 17334
| SystemBarStyle.auto( | ||
| lightScrim = Color.TRANSPARENT, | ||
| darkScrim = Color.TRANSPARENT, | ||
| ) |
There was a problem hiding this comment.
This should have { Themes.isNightTheme } to handle a user selecting a theme manually
There was a problem hiding this comment.
Sorry, I don't understand; what's the meaning of this comment?
ericli3690
left a comment
There was a problem hiding this comment.
Code-wise, looks fantastic! Only nits.
I tested on a Lenovo Tab M11 and it looks good. However, when I tested on my phone (Samsung S23, API 34), there were issues with overlapping icons in landscape mode on the left and right hand sides, did you forget to apply left and right insets? Note the overlapping "show tabs" and "back" icons on the left and right edges in the screenshots here:
This doesn't look intended.
|
|
||
| plugins { | ||
| id("org.jetbrains.kotlin.jvm") | ||
| /** Wrapper around the `IntArray` returned by [View.getLocationOnScreen]. */ |
| * A container which emulates the 'fade' effect which is applied to content when underneath the | ||
| * button navigation. | ||
| * | ||
| * Extends the button nav bar's visual effect to our components. |
There was a problem hiding this comment.
nit: I notice in your PR description that you have a brief explanation of why this is necessary:
Furthermore, some Android versions have a 'transparent nav', which applied a transparency filter to elements underneath it. Different Android versions did this differently, and the colors were non-public(with API <= 25 not supporting dark navigation buttons), so I rolled my own (BottomFadeFrameLayout): using a DST_OUT filter.
Perhaps insert it inline in this docstring? In my opinion it's not immediately clear from reading this file as to why this BottomFadeFrameLayout is necessary.
| SystemBarStyle.auto( | ||
| lightScrim = Color.TRANSPARENT, | ||
| darkScrim = Color.TRANSPARENT, | ||
| ) |
There was a problem hiding this comment.
Sorry, I don't understand; what's the meaning of this comment?
| ) | ||
| deckPickerBinding.reviewSummaryTextView.updatePadding(bottom = bars.bottom) | ||
|
|
||
| val fabBottomOffset = if (isRobolectric) 12.dp.toPx(this) else -12.dp.toPx(this) |
There was a problem hiding this comment.
nit: add inline comment here explaining that this is a quick fix for Robolectric as you've explained in your PR description?
| } | ||
|
|
||
| context(test: RobolectricTest) | ||
| fun withDeckPicker( |
There was a problem hiding this comment.
nit: maybe move this to a shared file rather than putting it a the bottom of DeckPickerScreenshotTest, since it's also used in DeckPickerTabletScreenshotTest?
| setRecyclerViewBottomPaddingAbove(floatingActionButtonBinding.fabMain) | ||
| insets | ||
| } | ||
| floatingActionButtonBinding.fabMain.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ -> |
There was a problem hiding this comment.
Holy moly so many underscores
Good job Google
Note
Assisted-by: Claude Opus 4.7 - lots of discussion, wasn't too helpful here
Purpose / Description
This PR enables edge to edge support for the Deck Picker. The DeckPicker currently uses an opaque toolbar, so we only need to focus on edge-to-edge for the bottom bar & side panels (for example: if there's a camera cutout on a tablet).
Fixes
Approach
This was difficult and there was a lot of trial and error.
Deck List & "Studied X cards in Y seconds"
The deck list needs to be at the bottom of the screen.
- android:layout_above="@id/review_summary_text_view"Due to this, the deck list appears under the review summary. Before this change, the
review_summarybackground was effectively opaque, and now needs to handle overlap with the deck name, without obscuring the content.Furthermore, some Android versions have a 'transparent nav', which applied a transparency filter to elements underneath it. Different Android versions did this differently, and the colors were non-public(with API <= 25 not supporting dark navigation buttons), so I rolled my own (
BottomFadeFrameLayout): using aDST_OUTfilter.FAB
The floating action bar is surprisingly complex: it uses a
ScrollViewto handle smaller screens, and this means we need a margin for the shadow to display properly, rather than removing its clipping behavior.I extracted some of the bottom padding to try and remove 'fabBottomOffset', but due to the shadow requirements, this did not seem feasible.
isRobolectric: due to an undetermined bug, the FAB was ~24dp too low on the screenshot after edge to edge was implemented. This fixes it manuallyHow Has This Been Tested?
tools/compare-screenshot-test.sh 8f35410 "com.ichi2.anki.Deck**ScreenshotTest"
Details
Overlap with selected deck - same style as the standard Android bottom nav
Learning (optional, can help others)
https://developer.android.com/develop/ui/views/layout/edge-to-edge
Checklist