实现ConstraintLayout上下滑动显隐及val无法重新赋值问题求助
Fixing "val cannot be reassigned" & Implementing Slide-to-Reveal/Hide for Your Gradient Layout
Hey there! Let's break down how to fix your immediate error and build the slide behavior you want.
1. Fixing the "val cannot be reassigned" Error
You can't directly set scopeLayout.height because height is a read-only property for views. Instead, you need to modify the view's LayoutParams to adjust its height. Here's how to fix that part:
val scopeLayout = inflaterView.findViewById<ConstraintLayout>(R.id.scope_layout) scopeLayout.setOnTouchListener { v, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { Toast.makeText(context, "you just touch the screen :-)", Toast.LENGTH_SHORT).show() // Update height via LayoutParams val params = scopeLayout.layoutParams as ConstraintLayout.LayoutParams params.height = 215 // Tip: Convert dp to px with TypedValue.applyDimension() for device consistency! scopeLayout.layoutParams = params } // We'll add sliding logic actions here next } true }
2. Implementing Slide-to-Reveal/Hide Behavior
To make the layout slide down to reveal and slide up to hide, you'll need to track the user's touch movement, calculate slide distance, and adjust the layout's height (or position) accordingly. Here's a complete implementation with smooth animation:
val scopeLayout = inflaterView.findViewById<ConstraintLayout>(R.id.scope_layout) var initialTouchY = 0f val fullVisibleHeight = 800 // Your desired full visible height (in pixels) val hiddenHeight = 100 // Height when the layout is hidden (in pixels) scopeLayout.setOnTouchListener { v, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { initialTouchY = event.rawY true } MotionEvent.ACTION_MOVE -> { val dragDelta = event.rawY - initialTouchY // Calculate new height, clamp it between hidden and full values var newHeight = scopeLayout.height + dragDelta.toInt() newHeight = newHeight.coerceIn(hiddenHeight, fullVisibleHeight) // Update layout height val params = scopeLayout.layoutParams as ConstraintLayout.LayoutParams params.height = newHeight scopeLayout.layoutParams = params // Reset initial touch position for smooth dragging initialTouchY = event.rawY true } MotionEvent.ACTION_UP -> { // Decide final state based on current height val targetHeight = if (scopeLayout.height > (fullVisibleHeight + hiddenHeight)/2) { fullVisibleHeight } else { hiddenHeight } // Animate to target state for polished finish ValueAnimator.ofInt(scopeLayout.height, targetHeight).apply { duration = 300 addUpdateListener { animator -> val params = scopeLayout.layoutParams as ConstraintLayout.LayoutParams params.height = animator.animatedValue as Int scopeLayout.layoutParams = params } start() } true } else -> false } }
Key Details:
- Track Initial Touch: We store the starting vertical position when the user first taps the layout.
- Drag to Adjust Height: As the user moves their finger, we adjust the layout's height based on drag distance, ensuring it never goes beyond your hidden/full limits.
- Smooth Release Animation: When the user lifts their finger, we animate the layout to either fully visible or hidden state based on its current position, making the interaction feel polished.
Extra Tips
- If you prefer sliding the entire layout (instead of adjusting height), modify
translationYinstead of layout params height. - For more complex touch interactions, consider using
ViewDragHelperinstead of a rawOnTouchListenerfor better gesture handling.
内容的提问来源于stack exchange,提问作者Kakashi
相关产品推荐
相关产品推荐

