scoller 和惯性滑动view(二)

继续scoller 和惯性滑动view,上一篇是用GestureListener来进行监听,这里我们使用原生的onTouch事件来获取手势的操作。
不同如下

  • 1.手势获取监听不同。
  • 2.重新绘制的机制不同,前面是使用的postAnimation()来运行runbale实现滚动重绘,这里使用computeScroll()方法来实现重新绘制。这个方法会在view进行重新绘制时候被进行调用。
    贴代码:

import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.View
import android.view.animation.DecelerateInterpolator
import android.view.animation.Interpolator
import android.view.animation.LinearInterpolator
import android.widget.ScrollView
import android.widget.Scroller
import view.NaughtyChild.myview.R
import kotlin.math.abs
import kotlin.math.max


class CustomTouchView : View {
    val bitmap = BitmapFactory.decodeResource(resources, R.mipmap.mountain)
    val velocityTracker = VelocityTracker.obtain()

    private val sQuinticInterpolator = Interpolator { t ->
        var tempT = t
        tempT -= 1.0f
        tempT * tempT * tempT * tempT * tempT + 1.0f
    }
    val decelerateInterpolator: DecelerateInterpolator = DecelerateInterpolator(1f)

    val scroller = Scroller(context, decelerateInterpolator)
    var downX = 0
    var downY = 0
    var isFling = false
    var oldMoveX = 0
    var oldMoveY = 0
    var oldScrollX = 0
    var oldScrollY = 0
    val maxSpeed = 800
    var upX = 0
    var upY = 0

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val action = event!!.actionMasked
        velocityTracker.addMovement(event)
        when (action) {
            MotionEvent.ACTION_DOWN -> {
                downX = event.x.toInt()
                downY = event.y.toInt()
                oldMoveX = event.x.toInt()
                oldMoveY = event.y.toInt()
                Log.d("CustomTouchView", "ACTION_DOWN: downx=$downX,downy=$downY");
            }
            MotionEvent.ACTION_UP -> {
                upX = event.x.toInt()
                upY = event.y.toInt()
                downY = 0
                downX = 0
                velocityTracker.computeCurrentVelocity(1000, maxSpeed.toFloat())//每秒像素数
                var xSpeed = velocityTracker.xVelocity
                var ySpeed = velocityTracker.yVelocity
                Log.d("CustomTouchView", "ACTION_UP: $xSpeed,$ySpeed");
                if (abs(xSpeed) > 400 || abs(ySpeed) > 400) {
                    isFling = true
                    this.doFling(oldMoveX, oldMoveY, -xSpeed.toInt(), -ySpeed.toInt())
                }
                oldMoveY = 0
                oldMoveX = 0
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d("CustomTouchView", " ACTION_MOVE: movex=${event.x},moveY=${event.y}");
                Log.d("CustomTouchView", " ACTION_MOVE: downx=$downX,downy=$downY");
                val dx = event.x.toInt() - oldMoveX
                val dy = event.y.toInt() - oldMoveY
                scrollBy(-dx, -dy)
                Log.d("CustomTouchView", "ACTION_MOVE: dx=$dx,dy=$dy");
                oldMoveX = event.x.toInt()
                oldMoveY = event.y.toInt()
            }
        }
        return true
    }

    private fun doFling(oldx: Int, oldY: Int, xspeed: Int, yseed: Int) {
        Log.d("CustomTouchView", "doFling:xspeed${xspeed},yspeed=${yseed} ");
        scroller.fling(0, 0, xspeed, yseed, Int.MIN_VALUE, Int.MAX_VALUE, Int.MIN_VALUE, Int.MAX_VALUE)
        invalidate()
    }

    override fun draw(canvas: Canvas) {
        super.draw(canvas)
        canvas.drawBitmap(bitmap, 0f, 0f, null)
    }

    override fun computeScroll() {//本方法在进行重新绘制时候被调用,所以只要我们在这里方法里面使用重绘,就会被重新调用。使用isFling作为是否重新绘制的开关。
        if (!isFling) return
        val scrolling = scroller.computeScrollOffset()
        Log.d("CustomTouchView", "computeScroll:$scrolling ");
        if (scrolling) {
            Log.d("CustomTouchView", "computeScroll: getCurrX=${scroller.getCurrX()},getCurrY=${scroller.getCurrY()}");
            Log.d("CustomTouchView", "computeScroll: ${scroller.getCurrX() - upX},${scroller.getCurrY() - upY}");
            scrollBy(scroller.getCurrX(), scroller.getCurrY());
            invalidate();
        } else {
            isFling = false
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值