From dccf1a17722f93f8688daa89ca01808c7d048c3d Mon Sep 17 00:00:00 2001 From: Quildra Date: Fri, 1 Aug 2025 14:26:04 +0100 Subject: [PATCH] feat: add vertical bounds checking to prevent menu overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Calculate actual menu height using measure() for precise bounds checking - Add 32dp safety margin to account for navigation bar and system UI - Automatically adjust menu Y position when it would extend off bottom - Prevent menu from going off top of screen with maxOf(0, adjustedY) - Add comprehensive debug logging for position calculations This ensures the floating menu is always fully visible regardless of FAB position, with the menu intelligently shifting upward when the FAB is positioned near the bottom of the screen. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../pokegoalshelper/ui/EnhancedFloatingFAB.kt | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/quillstudios/pokegoalshelper/ui/EnhancedFloatingFAB.kt b/app/src/main/java/com/quillstudios/pokegoalshelper/ui/EnhancedFloatingFAB.kt index 12c17f9..735fb43 100644 --- a/app/src/main/java/com/quillstudios/pokegoalshelper/ui/EnhancedFloatingFAB.kt +++ b/app/src/main/java/com/quillstudios/pokegoalshelper/ui/EnhancedFloatingFAB.kt @@ -416,17 +416,20 @@ class EnhancedFloatingFAB( private fun updateMenuPosition() { menuContainer?.let { menu -> menuParams?.let { params -> - // Calculate actual menu width by measuring the container + // Calculate actual menu dimensions by measuring the container menu.measure( View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) ) val menuWidth = menu.measuredWidth + val menuHeight = menu.measuredHeight val padding = dpToPx(8) // 8dp padding between menu and FAB - val screenWidth = getScreenSize().first + val screenSize = getScreenSize() + val screenWidth = screenSize.first + val screenHeight = screenSize.second val fabCenterX = currentX + dpToPx(FAB_SIZE_DP) / 2 - // Determine if FAB is on left or right side of screen + // Determine horizontal positioning (left or right side) val isOnLeftSide = fabCenterX < screenWidth / 2 if (isOnLeftSide) { @@ -440,9 +443,24 @@ class EnhancedFloatingFAB( Log.d(TAG, "FAB on right side - menu to left at x=${params.x}") } - params.y = currentY // Same vertical position as FAB (top alignment) + // Determine vertical positioning with bounds checking + val desiredY = currentY // Ideally align with FAB top + val safetyMargin = dpToPx(32) // 32dp safety margin from bottom (accounts for nav bar + buffer) + val menuBottomY = desiredY + menuHeight + val safeScreenHeight = screenHeight - safetyMargin - Log.d(TAG, "Menu position: x=${params.x}, y=${params.y}, measured width=${menuWidth}, FAB center: x=$fabCenterX, screen width: $screenWidth") + if (menuBottomY > safeScreenHeight) { + // Menu would go off bottom - adjust upward with safety margin + val adjustedY = safeScreenHeight - menuHeight + params.y = maxOf(0, adjustedY) // Ensure we don't go off top either + Log.d(TAG, "Menu adjusted up: desired Y=$desiredY, adjusted Y=${params.y} (menu height=$menuHeight, safe screen height=$safeScreenHeight)") + } else { + // Menu fits normally - align with FAB top + params.y = desiredY + Log.d(TAG, "Menu positioned normally at Y=${params.y}") + } + + Log.d(TAG, "Final menu position: x=${params.x}, y=${params.y}, size=${menuWidth}x${menuHeight}, FAB at: x=$currentX, y=$currentY") try { windowManager?.updateViewLayout(menu, params) } catch (e: Exception) {