美文网首页Android开发Android技术知识Kotlin编程
popwindow实现可拖动+滑到屏幕外+屏幕外回弹

popwindow实现可拖动+滑到屏幕外+屏幕外回弹

作者: iceIC | 来源:发表于2018-11-26 11:24 被阅读29次

可拖动效果

fun makeDraggable(popupWindow: PopupWindow) {
        popupWindow.contentView.setOnTouchListener(object : View.OnTouchListener {
            var lastX = 0f
            var lastY = 0f
            var isDragging = false
            override fun onTouch(v: View?, event: MotionEvent): Boolean {
                val touchSlop = ViewConfiguration.getTouchSlop() * 2

                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        lastX = event.rawX
                        lastY = event.rawY
                        isDragging = false
                        return isDragging
                    }
                    MotionEvent.ACTION_MOVE -> {
                        val dx = event.rawX - lastX
                        val dy = event.rawY - lastY

                        if (Math.abs(dx) > touchSlop || Math.abs(dy) > touchSlop) {
                            val decorView = popupWindow.contentView.parent as ViewGroup //popwindow的内部变量decorView
                            val lp = decorView.layoutParams as WindowManager.LayoutParams
                            lp.flags = lp.flags or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                            popupWindow.update(lp.x + dx.toInt(), lp.y + dy.toInt(), -1, -1)
                            lastX = event.rawX
                            lastY = event.rawY
                            isDragging = true
                        }
                        return isDragging
                    }
                    MotionEvent.ACTION_UP -> {
                        return isDragging
                    }
                }
                return true
            }

        })
    }

用法很简单,只需要调用
makeDraggable(yourPopupWindow)

支持滑到屏幕外

默认是不允许滑动屏幕外的,要想支持滑到屏幕外也很简单
popupWindow.isClippingEnabled = false

支持屏幕外回弹

当支持滑到屏幕外时候通常都需要有回弹效果,即松手时从屏幕外回弹到屏幕内。
只要在松手时使用属性动画即刻(处理MotionEvent.ACTION_UP 事件)

MotionEvent.ACTION_UP -> {
    ...
    ...

    val supportRollback = true
    if (supportRollback) {
        var tartgetX = 0
        var tartgetY = 0
        val decorView = popupWindow.contentView.parent as ViewGroup //popwindow的内部变量decorView
        val lp = decorView.layoutParams as WindowManager.LayoutParams
        tartgetX = Math.min(Math.max(lp.x, 0), ScreenUtils.getScreenWidth() - popupWindow.width)
        tartgetY = Math.min(Math.max(lp.y, 0), ScreenUtils.getScreenHeight() - popupWindow.height)
        if (tartgetX != lp.x || tartgetY != lp.y) {
            val ofObject = ValueAnimator.ofObject(TypeEvaluator<Point> { fraction, startValue, endValue ->
                Point((startValue.x + (endValue.x - startValue.x) * fraction).toInt(),
                        (startValue.y + (endValue.y - startValue.y) * fraction).toInt())
            }, Point(lp.x, lp.y), Point(tartgetX, tartgetY))
            ofObject.addUpdateListener {
                val value = it.animatedValue as Point
                popupWindow.update(value.x, value.y, -1, -1)
            }
            ofObject.interpolator = LinearInterpolator()
            ofObject.start()
        }
    }

   ...
   ...
}

当需要给回弹设置一个边界(默认是手机屏幕四边),只需要改下面两行代码

tartgetX = Math.min(Math.max(lp.x, 0), ScreenUtils.getScreenWidth() - popupWindow.width)//(0代表左边界,ScreenUtils.getScreenWidth()代表右边界)
tartgetY = Math.min(Math.max(lp.y, 0), ScreenUtils.getScreenHeight() - popupWindow.height)//(0代表上边界,ScreenUtils.getScreenWidth()代表下边界)

相关文章

  • popwindow实现可拖动+滑到屏幕外+屏幕外回弹

    可拖动效果 用法很简单,只需要调用makeDraggable(yourPopupWindow) 支持滑到屏幕外 默...

  • iOS-悬浮物(仿微信视频对话框,可拖动,加重力动画)

    首先添加拖动手势 在拖拽方法里面执行: 可实现在屏幕内部拖拽且不脱离屏幕外部。 下面实现类似微信两人视频对话时,对...

  • 图层性能

    1. 离屏渲染 当图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制时,屏幕外渲染就被唤起了。屏幕外渲染并...

  • iOS-对离屏渲染的理解

    什么是离屏渲染 当图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制时,屏幕外渲染就被唤起了。屏幕外渲染并...

  • 离屏渲染

    当图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制时,屏幕外渲染就被唤起了。屏幕外渲染并不意味着软件绘制...

  • 离屏渲染

    当图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制时,屏幕外渲染就被唤起了。屏幕外渲染并不意味着软件绘制...

  • 03UI开发-ListView

    ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕里面,同时屏幕上原有的数据则会滚动出屏幕 L...

  • RecyclerView缓存机制

    RecyclerView分为四级缓存 RecyclerView根据不同的状态可以分为:屏幕内缓存、屏幕外缓存、自定...

  • RecycleView缓存

    RecyclerView根据不同的状态可以分为:屏幕内缓存、屏幕外缓存、自定义缓存、缓存池。RecyclerVie...

  • Android应用内截取屏幕

    截取屏幕,包括屏幕外的(RecyclerView或者ScrollView嵌套里面的布局)查找资料后,找到了这样一段...

网友评论

  • iceIC:api23以下的popwindow是没有decorView这个变量的,所以获取decorView使用下列代码就能兼容api23以下的机器

    val decorView =
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
    popupWindow.contentView.parent as ViewGroup
    } else {
    popupWindow.contentView
    }

本文标题:popwindow实现可拖动+滑到屏幕外+屏幕外回弹

本文链接:https://www.haomeiwen.com/subject/klryqqtx.html