自定义view移动整个view

时间比较短,直接上代码了:



import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.PointF
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.ViewConfiguration
import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import me.frame.mvvm.utils.DisplayUtils
import kotlin.math.abs

class MyConstraintLayout(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {
    private var children: CardView? = null
    private var lastX = 0
    private var lastY = 0
    private var mOntuch = 0
    private var scale = 0f
    private var oldTop = 0
    private var oldButtom = 0
    private var isTopOrBottom = false
    private var isHide = false
    private var screenHeight = 0

    fun layouts(l: Int, t: Int, r: Int, b: Int) {
        layout(l, t, r, b)
    }

//这个是绘制完执行的
    override fun onFinishInflate() {
        super.onFinishInflate()
        mOntuch = ViewConfiguration.get(context).scaledTouchSlop
        children = getChildAt(0) as CardView?
        Log.e("mlt", "......mOntuch............" + mOntuch)//24
        Log.e("mlt", "......DisplayUtils............" + DisplayUtils.displayPix(context))//1298
        Log.e("mlt", "......displayheightPix............" + DisplayUtils.displayheightPix(context))//1298
        scale = DisplayUtils.displayPix(context)
        screenHeight = DisplayUtils.displayheightPix(context)
//这里用了200毫秒的时间,不然会获取不到下面的值
        postDelayed(Runnable {
            oldTop = top - default.toInt()
            oldButtom = bottom - default.toInt()
            Log.e("mlt", "......top............" + top)//1848
            Log.e("mlt", "......bottom............" + bottom)//3648
            Log.e("mlt", "......height............" + height)//1800
            Log.e("mlt", "......width............" + width)//1080
        }, durationDefault)
    }

    /**
     * new 这里是第一种,根据view的translationY方法来上下移动整个view,而不是里面的内容
scrollTo 和scrollby 是移动view里面的内容
     * */
    private var lastNewY = 0f
    private var isNewTopOrBottom = false
    private var isNewHide = false
    private var transY = 0f
    private var transX= 0f
    private var downPoint = PointF()
    private var midden = 0f
    private var defaultNegative = -550f
    private var default = 550f
    private var durationDefault = 200L

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        midden = measuredHeight / scale
        return if (children == null) {
            super.onTouchEvent(event)
        } else {
            when (event?.action) {
                MotionEvent.ACTION_DOWN -> {
                    lastNewY = event.rawY
                    downPoint.x = event.rawX
                    downPoint.y = event.rawY
                    return true
                }
                MotionEvent.ACTION_MOVE -> {
                    onActionMove(event)
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    if (isNewTopOrBottom) {
                        if (isNewHide) {
                            val anmi = ObjectAnimator.ofFloat(this, "translationY", 0f)
                            anmi.duration = durationDefault
                            anmi.start()
//                            translationY = 0f
                        } else {
                            val anmi = ObjectAnimator.ofFloat(this, "translationY", defaultNegative)
                            anmi.duration = durationDefault
                            anmi.start()
//                            translationY = -550f
                        }
                    } else {
                        val anmi = ObjectAnimator.ofFloat(this, "translationY", -(default+midden))
                        anmi.duration = durationDefault
                        anmi.start()
//                        translationY = -(550 + midden)
                    }
                }
            }
            super.onTouchEvent(event)
        }
    }

    private fun onActionMove(event: MotionEvent) {
        val moveY = event.rawY
        val moveX = event.rawX
        transY = moveY - downPoint.y
        transX = moveX - downPoint.x
        if (transY <= 0) {//上
            if (translationY <= defaultNegative && translationY > -(midden + default) ) {
                translationY += transY
                isNewTopOrBottom = false
                isNewHide = false
            }
        } else {
            if (translationY > defaultNegative) {
                translationY += transY
                isNewHide = true
            } else {
                translationY += transY
                isNewTopOrBottom = true
                isNewHide = false
            }
        }
        downPoint.y = event.rawY
        downPoint.x = event.rawX
    }

//这个方法也可行,但是比较生硬没有动画,因为是直接绘制,用的是layou 方法也可以实现,

//    override fun onTouchEvent(event: MotionEvent?): Boolean {
//        Log.e("mlt", "......measuredHeight............" + measuredHeight)//1500
//        Log.e("mlt", "......top............" + top)//1298
//        Log.e("mlt", "......bottom............" + bottom)//2798
        Log.e("mlt","......children............"+children?.top)//0
        Log.e("mlt","......children............"+children?.bottom)//1500
//        return if (children == null) {
//            super.onTouchEvent(event)
//        } else {
//            var x = event?.x
//            val y = event?.y
//            val tv = children?.getChildAt(0)
//            val childtop = tv?.top
//            val childbottom = tv?.bottom
//            val childLeft = tv?.left
//            val childRight = tv?.right
//            var title = 0f
//            when (event?.action) {
//                MotionEvent.ACTION_DOWN -> {
//                    if (y != null) {
//                        if (y > childtop!! && y < childbottom!!) {
//                            lastX = event.rawX.toInt()
//                            lastY = event.rawY.toInt()
//                            title = lastY - y
                            Log.e("mlt", "...........ACTION_DOWN......childtop........." + childtop)//0
                            Log.e("mlt", "...........ACTION_DOWN......childbottom........." + childbottom)//133
                            Log.e("mlt", "...........ACTION_DOWN......childLeft........." + childLeft)//0
                            Log.e("mlt", "...........ACTION_DOWN......childRight........." + childRight)/1080
//                            Log.e("mlt", "...........ACTION_DOWN......lastX........." + lastX)
//                            Log.e("mlt", "...........ACTION_DOWN.......lastY........" + lastY)
                            Log.e("mlt", "...........ACTION_DOWN.......title........" + title)//1370
//                            return true
//                        }
//                    }
//                }
//                MotionEvent.ACTION_MOVE -> {
//                    val dy = event.rawY - lastY
//                    Log.e("mlt", "...........ACTION_MOVE.........dy......" + dy)
//                    if (dy < 0) {//想上 measuredHeight 1500
//                        Log.e("mlt", ",,,,,,,,,dy < 0,,,,,,,,,,,,," + abs(dy))
//                        if (top >= (oldTop - measuredHeight / scale)) {
//                            layout(left, top - abs(dy).toInt(), right, bottom - abs(dy).toInt())
//                        }
//                        isTopOrBottom = false
//                    } else {
//                        if (top >= oldTop) {
//                            isHide = true
//                        }
//                        layout(left, top + abs(dy).toInt(), right, bottom + abs(dy).toInt())
//                        isTopOrBottom = true
//                    }
//                    lastY = event.rawY.toInt()
//                }
//                MotionEvent.ACTION_CANCEL -> {
//
//                }
//                MotionEvent.ACTION_UP -> {
//                    if (isTopOrBottom) {
//                        if (isHide) {
//                            val height = screenHeight - oldTop
//                            layout(left, screenHeight, right, bottom + height)
//                        } else {
//                            layout(left, oldTop, right, oldButtom)
//                        }
//                        isHide = false
//                    } else {
//                        isHide = false
//                        layout(left, oldTop - measuredHeight / scale.toInt(), right, oldButtom - measuredHeight / scale.toInt())
//                    }
//                }
//            }
//            super.onTouchEvent(event)
//        }
//    }
}

就这点代码也花了很长的时间,主要的是对自定义view非常的不熟悉导致,以后还要多加熟悉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值