Skip to content

Commit 1656477

Browse files
committed
Hide FAB on scroll + 168dp list padding so it never overlaps cards
- Add a RecyclerView scroll listener on the profile list: hide the docked FAB on downward scroll, show it on upward scroll or when the list settles (idle). Only acts in stable Stopped/Connected states so it doesn't fight the FAB's connect/disconnect animation. - Bump profile + route list bottom padding to 168dp (FAB occupies ~157dp at 440dpi) so the last card always rests above the docked FAB and the pinned stats bar, in both connected and disconnected states. Verified on Android (Dracula-M3, connected): last card clears the FAB at the scroll extent; FAB tucks away while scrolling.
1 parent f18ad9a commit 1656477

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

app/src/main/java/io/nekohasekai/sagernet/ui/ConfigurationFragment.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,29 @@ class ConfigurationFragment @JvmOverloads constructor(
13961396
configurationListView.adapter = adapter
13971397
configurationListView.setItemViewCacheSize(20)
13981398

1399+
// Hide the docked FAB while scrolling down (so it never overlaps the
1400+
// bottom card) and bring it back on upward scroll or when the list
1401+
// settles. Mirrors the stats bar's hideOnScroll behavior. Only act in
1402+
// stable states (Stopped/Connected) so we don't fight the FAB's own
1403+
// show/hide animation during Connecting/Stopping.
1404+
configurationListView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
1405+
private fun stableState(): Boolean = DataStore.serviceState.let {
1406+
it == BaseService.State.Stopped || it == BaseService.State.Connected
1407+
}
1408+
1409+
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
1410+
if (!stableState()) return
1411+
val fab = (activity as? MainActivity)?.binding?.fab ?: return
1412+
if (dy > 4) fab.hide() else if (dy < -4) fab.show()
1413+
}
1414+
1415+
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
1416+
if (newState == RecyclerView.SCROLL_STATE_IDLE && stableState()) {
1417+
(activity as? MainActivity)?.binding?.fab?.show()
1418+
}
1419+
}
1420+
})
1421+
13991422
if (!select) {
14001423
undoManager = UndoSnackbarManager(activity as MainActivity, adapter!!)
14011424
setupItemTouchHelper()

app/src/main/res/layout/layout_profile_list.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
android:paddingLeft="4dp"
1111
android:paddingTop="4dp"
1212
android:paddingRight="4dp"
13-
android:paddingBottom="150dp"
13+
android:paddingBottom="168dp"
1414
android:scrollbarSize="0dp"
1515
app:fastScrollAutoHide="true"
1616
app:fastScrollThumbColor="?colorPrimary"

app/src/main/res/layout/layout_route.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
android:paddingLeft="4dp"
2323
android:paddingTop="4dp"
2424
android:paddingRight="4dp"
25-
android:paddingBottom="150dp"
25+
android:paddingBottom="168dp"
2626
android:scrollbarSize="0dp"
2727
app:fastScrollAutoHide="true"
2828
app:fastScrollThumbColor="?colorPrimary"

0 commit comments

Comments
 (0)