Browse Source

fix: implement sophisticated touch event handling for nested NestedScrollView

- Added custom NestedScrollView with proper touch event interception
- Implemented smart touch gesture detection using ViewConfiguration.scaledTouchSlop
- Added parent touch event blocking to prevent RecyclerView interference
- Enhanced scroll event handling for ACTION_DOWN, ACTION_MOVE, ACTION_UP states
- Added visual scrollbar indicators to confirm scrollable content (non-fading)
- Improved nested scrolling conflict resolution between RecyclerView and NestedScrollView

Key improvements:
1. Touch events properly routed to NestedScrollView when scrolling vertically
2. Parent RecyclerView prevented from intercepting scroll gestures in expanded content
3. Scrollbar always visible for visual debugging and user feedback
4. Proper cleanup of touch event ownership on gesture completion

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
feature/pgh-1-results-display-history
Quildra 5 months ago
parent
commit
50514d5272
  1. 43
      app/src/main/java/com/quillstudios/pokegoalshelper/ui/HistoryAdapter.kt

43
app/src/main/java/com/quillstudios/pokegoalshelper/ui/HistoryAdapter.kt

@ -192,7 +192,45 @@ class HistoryAdapter(
private fun createPopulatedExpandedContent(context: Context, result: DetectionResult): View private fun createPopulatedExpandedContent(context: Context, result: DetectionResult): View
{ {
return androidx.core.widget.NestedScrollView(context).apply { return object : androidx.core.widget.NestedScrollView(context) {
private var initialTouchY = 0f
private var touchSlop = android.view.ViewConfiguration.get(context).scaledTouchSlop
override fun onInterceptTouchEvent(ev: android.view.MotionEvent): Boolean {
when (ev.action) {
android.view.MotionEvent.ACTION_DOWN -> {
initialTouchY = ev.y
// Always request to handle touch events initially
parent?.requestDisallowInterceptTouchEvent(true)
}
android.view.MotionEvent.ACTION_MOVE -> {
val deltaY = kotlin.math.abs(ev.y - initialTouchY)
if (deltaY > touchSlop) {
// This is a scroll gesture - keep intercepting
parent?.requestDisallowInterceptTouchEvent(true)
}
}
android.view.MotionEvent.ACTION_UP, android.view.MotionEvent.ACTION_CANCEL -> {
// Allow parent to handle other gestures
parent?.requestDisallowInterceptTouchEvent(false)
}
}
return super.onInterceptTouchEvent(ev)
}
override fun onTouchEvent(ev: android.view.MotionEvent): Boolean {
// Maintain control during active scrolling
when (ev.action) {
android.view.MotionEvent.ACTION_DOWN, android.view.MotionEvent.ACTION_MOVE -> {
parent?.requestDisallowInterceptTouchEvent(true)
}
android.view.MotionEvent.ACTION_UP, android.view.MotionEvent.ACTION_CANCEL -> {
parent?.requestDisallowInterceptTouchEvent(false)
}
}
return super.onTouchEvent(ev)
}
}.apply {
// Set a reasonable fixed height for the scrollable area // Set a reasonable fixed height for the scrollable area
layoutParams = LinearLayout.LayoutParams( layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT,
@ -202,6 +240,9 @@ class HistoryAdapter(
// Configure scrolling behavior optimized for nested scrolling // Configure scrolling behavior optimized for nested scrolling
isFillViewport = false isFillViewport = false
isNestedScrollingEnabled = true isNestedScrollingEnabled = true
isVerticalScrollBarEnabled = true // Show scrollbar for visual confirmation
scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
isScrollbarFadingEnabled = false // Keep scrollbar visible
tag = "expanded_content" tag = "expanded_content"
val contentContainer = LinearLayout(context).apply { val contentContainer = LinearLayout(context).apply {

Loading…
Cancel
Save