Android 拖转改变视图高度

复制代码
class DraggableBottomView(
    context: Context,
    attrs: AttributeSet? = null,
) :LinearLayout(context, attrs, 0) {

    private var gestureDetector: GestureDetectorCompat
    private var initialY = 0f
    private var initialX = 0f
    private var initialHeight = 0
    private val minHeight: Int
    private val maxHeight: Int
    private val touchSlop: Int //触摸滑动距离
    private var isDragging = false // 是否正在拖动
    private var isUpOrDown = "up" // up向上  down 向下

    init {
        minHeight = CommonUtil.dpToPx(context,200)
        maxHeight = CommonUtil.dpToPx(context,500)
        touchSlop = ViewConfiguration.get(context).scaledTouchSlop
        gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onDown(e: MotionEvent): Boolean {
                initialY = e.rawY
                initialX = e.rawX
                initialHeight = height
                return true
            }
        })

    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        gestureDetector.onTouchEvent(event)
        when (event.action) {
            MotionEvent.ACTION_MOVE -> {
                val dy = event.rawY - initialY
                val dx = event.rawX - initialX
                if (Math.abs(dy) > touchSlop && Math.abs(dy)>Math.abs(dx)){
                    isUpOrDown = if (dy < 0f) "up" else "down"
                    isDragging = true
                }else{
                    isDragging = false
                }
                // 设置跟随手指滑动
                val newHeight = (initialHeight - dy).toInt()
                val clampedHeight = newHeight.coerceIn(minHeight, maxHeight)
                val params = layoutParams as ViewGroup.LayoutParams
                params.height = clampedHeight
                layoutParams = params
                requestLayout()

            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (isDragging) {
                    // 滑动松手后的逻辑
                    if (isUpOrDown == "up") {
                        animateHeightChange(maxHeight)
                    } else {
                        // 固定到初始位置位置
                        animateHeightChange(minHeight)
                    }
                    isDragging = false
                } else {

                }
            }
        }
        return true
    }

    private fun animateHeightChange(targetHeight: Int) {
        val valueAnimator = ValueAnimator.ofInt(height, targetHeight)
        valueAnimator.duration = 200 // 动画持续时间,可根据需要调整
        valueAnimator.addUpdateListener { animator ->
            val animatedValue = animator.animatedValue as Int
            val params = layoutParams as ViewGroup.LayoutParams
            params.height = animatedValue
            layoutParams = params
            requestLayout()
        }
        valueAnimator.start()
    }
}
相关推荐
幻雨様1 小时前
UE5多人MOBA+GAS 45、制作冲刺技能
android·ue5
Jerry说前后端3 小时前
Android 数据可视化开发:从技术选型到性能优化
android·信息可视化·性能优化
Meteors.3 小时前
Android约束布局(ConstraintLayout)常用属性
android
alexhilton4 小时前
玩转Shader之学会如何变形画布
android·kotlin·android jetpack
whysqwhw8 小时前
安卓图片性能优化技巧
android
风往哪边走8 小时前
自定义底部筛选弹框
android
Yyyy4829 小时前
MyCAT基础概念
android
Android轮子哥9 小时前
尝试解决 Android 适配最后一公里
android
雨白10 小时前
OkHttp 源码解析:enqueue 非同步流程与 Dispatcher 调度
android
风往哪边走11 小时前
自定义仿日历组件弹框
android