Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在android中处于放大模式时,滚动到二维滚动视图中不工作的边_Android_Android Layout_Drag And Drop_Android Scrollview_Pinchzoom - Fatal编程技术网

在android中处于放大模式时,滚动到二维滚动视图中不工作的边

在android中处于放大模式时,滚动到二维滚动视图中不工作的边,android,android-layout,drag-and-drop,android-scrollview,pinchzoom,Android,Android Layout,Drag And Drop,Android Scrollview,Pinchzoom,这很难解释,但我正在努力 在我的例子中,有一个线性布局(使用滚动到边缘功能放大)和多个recyclerView(用于拖放功能)。下面是缩放时滚动到边的问题。我尝试了一种解决方案,比如使用2个滚动视图1个水平视图1个垂直视图,但在这种情况下,它一次只能将视图移动一个方向 我从林克那里得到了这门课的参考资料 这里我附上我的二维滚动视图类 package com.app.xyz import android.annotation.SuppressLint import android.content

这很难解释,但我正在努力

在我的例子中,有一个线性布局(使用滚动到边缘功能放大)和多个recyclerView(用于拖放功能)。下面是缩放时滚动到边的问题。我尝试了一种解决方案,比如使用2个滚动视图1个水平视图1个垂直视图,但在这种情况下,它一次只能将视图移动一个方向

我从林克那里得到了这门课的参考资料

这里我附上我的二维滚动视图类

package com.app.xyz

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.*
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.view.animation.ScaleAnimation
import android.widget.LinearLayout
import android.widget.Scroller
import timber.log.Timber
import java.lang.String
import java.util.*


class TwoDScrollView : LinearLayout {
    val ANIMATED_SCROLL_GAP = 250
    val TWO_DSCROLL_VIEW_CAN_HOST_ONLY_ONE_DIRECT_CHILD =
        "TwoDScrollView can host only one direct child"

    private var mLastScroll: Long = 0
    private var mScroller: Scroller? = null

    /**
     * Position of the last motion event.
     */
    private var mLastMotionY = 0f
    private var mLastMotionX = 0f

    /**
     * True if the user is currently dragging this TwoDScrollView around. This is
     * not the same as 'is being flinged', which can be checked by
     * mScroller.isFinished() (flinging begins when the user lifts his finger).
     */
    private var mIsBeingDragged = false

    /**
     * Determines speed during touch scrolling
     */
    private var mVelocityTracker: VelocityTracker? = null

    /**
     * Whether arrow scrolling is animated.
     */
    private var mTouchSlop = 0
    private var mMinimumVelocity = 0

    private var mScale = 1f
    private var mScaleDetector: ScaleGestureDetector? = null
    private var gestureDetector: GestureDetector? = null
    private val mEnableScaling =
        true // scaling is buggy when you click on child views

    constructor(context: Context?) : super(context!!) {
        initTwoDScrollView()
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(
        context!!,
        attrs
    ) {
        initTwoDScrollView()
    }

    override fun getTopFadingEdgeStrength(): Float {
        if (childCount == 0) {
            return 0.0f
        }
        val length = verticalFadingEdgeLength
        return if (scrollY < length) {
            scrollY / length.toFloat()
        } else 1.0f
    }

    override fun getBottomFadingEdgeStrength(): Float {
        if (childCount == 0) {
            return 0.0f
        }
        val length = verticalFadingEdgeLength
        val bottomEdge = height - paddingBottom
        val span = getChildAt(0).bottom - scrollY - bottomEdge
        return if (span < length) {
            span / length.toFloat()
        } else 1.0f
    }

    override fun getLeftFadingEdgeStrength(): Float {
        if (childCount == 0) {
            return 0.0f
        }
        val length = horizontalFadingEdgeLength
        return if (scrollX < length) {
            scrollX / length.toFloat()
        } else 1.0f
    }

    override fun getRightFadingEdgeStrength(): Float {
        if (childCount == 0) {
            return 0.0f
        }
        val length = horizontalFadingEdgeLength
        val rightEdge = width - paddingRight
        val span = getChildAt(0).right - scrollX - rightEdge
        return if (span < length) {
            span / length.toFloat()
        } else 1.0f
    }

    private fun initTwoDScrollView() {
        mScroller = Scroller(context)
        isFocusable = true
        descendantFocusability = ViewGroup.FOCUS_AFTER_DESCENDANTS
        setWillNotDraw(false)
        val configuration = ViewConfiguration.get(context)
        mTouchSlop = configuration.scaledTouchSlop
        mMinimumVelocity = configuration.scaledMinimumFlingVelocity
        if (mEnableScaling) {
            gestureDetector = GestureDetector(context, GestureListener())
        }
    }

    override fun addView(child: View) {
        check(childCount <= 0) { TWO_DSCROLL_VIEW_CAN_HOST_ONLY_ONE_DIRECT_CHILD }
        super.addView(child)
        if (mEnableScaling) {
            createScaleGestureDetector(child)
        }
    }

    override fun addView(child: View, index: Int) {
        check(childCount <= 0) { TWO_DSCROLL_VIEW_CAN_HOST_ONLY_ONE_DIRECT_CHILD }
        super.addView(child, index)
        if (mEnableScaling) {
            createScaleGestureDetector(child)
        }
    }

    override fun addView(child: View, params: ViewGroup.LayoutParams?) {
        check(childCount <= 0) { TWO_DSCROLL_VIEW_CAN_HOST_ONLY_ONE_DIRECT_CHILD }
        super.addView(child, params)
        if (mEnableScaling) {
            createScaleGestureDetector(child)
        }
    }

    override fun addView(child: View, index: Int, params: ViewGroup.LayoutParams?) {
        check(childCount <= 0) { TWO_DSCROLL_VIEW_CAN_HOST_ONLY_ONE_DIRECT_CHILD }
        super.addView(child, index, params)
        if (mEnableScaling) {
            createScaleGestureDetector(child)
        }
    }

    private fun createScaleGestureDetector(childLayout: View) {
        mScaleDetector =
            ScaleGestureDetector(context, object : SimpleOnScaleGestureListener() {
                override fun onScale(detector: ScaleGestureDetector): Boolean {
                    val scale = 1 - detector.scaleFactor
                    val prevScale = mScale
                    mScale += scale
                    if (mScale < 0.5f) // Minimum scale condition:
                        mScale = 0.5f
                    if (mScale > 2.5f) // Maximum scale condition:
                        mScale = 2.5f
                    val scaleAnimation = ScaleAnimation(
                        1f / prevScale, 1f / mScale,
                        1f / prevScale, 1f / mScale,
                        detector.focusX, detector.focusY
                    )
                    scaleAnimation.duration = 0
                    scaleAnimation.fillAfter = true
                    childLayout.startAnimation(scaleAnimation)
                    return true
                }
            })
    }

    /**
     * @return Returns true this TwoDScrollView can be scrolled
     */
    private fun canScroll(): Boolean {
        val child = getChildAt(0)
        if (child != null) {
            val childHeight = child.height
            val childWidth = child.width
            return height < childHeight + paddingTop + paddingBottom ||
                    width < childWidth + paddingLeft + paddingRight
        }
        return false
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        /*
         * This method JUST determines whether we want to intercept the motion.
         * If we return true, onMotionEvent will be called and we do the actual
         * scrolling there.
         */

        /*
        * Shortcut the most recurring case: the user is in the dragging
        * state and he is moving his finger.  We want to intercept this
        * motion.
        */
        val action = ev.action
        if (action == MotionEvent.ACTION_MOVE && mIsBeingDragged) {
            return true
        }
        if (!canScroll()) {
            mIsBeingDragged = false
            return false
        }
        val y = ev.y
        val x = ev.x
        when (action) {
            MotionEvent.ACTION_MOVE -> {
                /*
                 * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
                 * whether the user has moved far enough from his original down touch.
                 */

                /*
                * Locally do absolute value. mLastMotionY is set to the y value
                * of the down event.
                */
                val yDiff = Math.abs(y - mLastMotionY).toInt()
                val xDiff = Math.abs(x - mLastMotionX).toInt()
                if (yDiff > mTouchSlop || xDiff > mTouchSlop) {
                    mIsBeingDragged = true
                }
            }
            MotionEvent.ACTION_DOWN -> {
                /* Remember location of down touch */mLastMotionY = y
                mLastMotionX = x

                /*
                * If being flinged and user touches the screen, initiate drag...
                * otherwise don't.  mScroller.isFinished should be false when
                * being flinged.
                */mIsBeingDragged = false
            }
            MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP ->                 /* Release the drag */mIsBeingDragged =
                false
        }

        /*
        * The only time we want to intercept motion events is if we are in the
        * drag mode.
        */return mIsBeingDragged
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN && ev.edgeFlags != 0) {
            // Don't handle edge touches immediately -- they may actually belong to one of our
            // descendants.
            return false
        }
        if (!canScroll()) {
            return false
        }
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain()
        }
        mVelocityTracker!!.addMovement(ev)
        val action = ev.action
        val y = ev.y
        val x = ev.x
        when (action) {
            MotionEvent.ACTION_DOWN -> {
                /*
                * If being flinged and user touches, stop the fling. isFinished
                * will be false if being flinged.
                */if (!mScroller!!.isFinished) {
                    mScroller!!.abortAnimation()
                }

                // Remember where the motion event started
                mLastMotionY = y
                mLastMotionX = x
            }
            MotionEvent.ACTION_MOVE -> {
                // Scroll to follow the motion event
                var deltaX = (mLastMotionX - x).toInt()
                var deltaY = (mLastMotionY - y).toInt()
                mLastMotionX = x
                mLastMotionY = y
                if (deltaX < 0) {
                    if (scrollX < 0) {
                        deltaX = 0
                    }
                } else if (deltaX > 0) {
                    val rightEdge = width - paddingRight
                    val availableToScroll = getChildAt(0).right - scrollX - rightEdge
                    deltaX = if (availableToScroll > 0) {
                        Math.min(availableToScroll, deltaX)
                    } else {
                        0
                    }
                }
                if (deltaY < 0) {
                    if (scrollY < 0) {
                        deltaY = 0
                    }
                } else if (deltaY > 0) {
                    val bottomEdge = height - paddingBottom
                    val availableToScroll =
                        getChildAt(0).bottom - scrollY - bottomEdge
                    deltaY = if (availableToScroll > 0) {
                        Math.min(availableToScroll, deltaY)
                    } else {
                        0
                    }
                }
                if (deltaY != 0 || deltaX != 0) scrollBy(deltaX, deltaY)
            }
            MotionEvent.ACTION_UP -> {
                val velocityTracker = mVelocityTracker
                velocityTracker!!.computeCurrentVelocity(1000)
                val initialXVelocity = velocityTracker.xVelocity.toInt()
                val initialYVelocity = velocityTracker.yVelocity.toInt()
                if (Math.abs(initialXVelocity) + Math.abs(initialYVelocity) > mMinimumVelocity && childCount > 0) {
                    fling(-initialXVelocity, -initialYVelocity)
                }
                if (mVelocityTracker != null) {
                    mVelocityTracker!!.recycle()
                    mVelocityTracker = null
                }
            }
        }
        return true
    }

    @SuppressLint("StringFormatInTimber")
    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        return if (mEnableScaling) {
            super.dispatchTouchEvent(event)
            mScaleDetector?.onTouchEvent(event)

            // scale event positions according to scale before passing them to children
            Timber.d(
                TwoDScrollView::class.java.simpleName,
                String.format(
                    Locale.getDefault(), "Position (%.2f,%.2f) ScrollOffset (%d,%d) Scale %.2f",
                    event.x, event.y, scrollX, scrollY, mScale
                )
            )
            event.setLocation(
                (scrollX + event.x) * mScale,
                (scrollY + event.y) * mScale
            )
            gestureDetector!!.onTouchEvent(event)
        } else {
            super.dispatchTouchEvent(event)
        }
    }

    /**
     *
     * Handles scrolling in response to a "home/end" shortcut press.
     *
     * @param directionVert the scroll direction: [android.view.View.FOCUS_UP]
     * to go the top of the view or
     * [android.view.View.FOCUS_DOWN] to go the bottom
     * @param directionHorz the scroll direction: [android.view.View.FOCUS_RIGHT]
     * to go the right of the view or
     * [android.view.View.FOCUS_LEFT] to go the left
     * @return true if the key event is consumed by this method, false otherwise
     */
    fun fullScroll(directionVert: Int, directionHorz: Int): Boolean {
        var scrollAmountY = 0
        var scrollAmountX = 0
        when (directionVert) {
            View.FOCUS_UP -> scrollAmountY = -scrollY
            View.FOCUS_DOWN -> {
                val count = childCount
                if (count > 0) {
                    val view = getChildAt(count - 1)
                    scrollAmountY = view.bottom - height - scrollY
                }
            }
        }
        when (directionHorz) {
            View.FOCUS_LEFT -> scrollAmountX = -scrollX
            View.FOCUS_RIGHT -> {
                val count = childCount
                if (count > 0) {
                    val view = getChildAt(count - 1)
                    scrollAmountX = view.right - width - scrollX
                }
            }
        }
        val handled = scrollAmountX != 0 || scrollAmountY != 0
        if (handled) doScroll(scrollAmountX, scrollAmountY)
        return handled
    }

    /**
     * Smooth scroll by a Y delta
     *
     * @param deltaX the number of pixels to scroll by on the X axis
     * @param deltaY the number of pixels to scroll by on the Y axis
     */
    private fun doScroll(deltaX: Int, deltaY: Int) {
        if (deltaX != 0 || deltaY != 0) {
            smoothScrollBy(deltaX, deltaY)
        }
    }

    /**
     * Like [View.scrollBy], but scroll smoothly instead of immediately.
     *
     * @param dx the number of pixels to scroll by on the X axis
     * @param dy the number of pixels to scroll by on the Y axis
     */
    fun smoothScrollBy(dx: Int, dy: Int) {
        val duration =
            AnimationUtils.currentAnimationTimeMillis() - mLastScroll
        if (duration > ANIMATED_SCROLL_GAP) {
            mScroller!!.startScroll(scrollX, scrollY, dx, dy)
            awakenScrollBars(mScroller!!.duration)
            invalidate()
        } else {
            if (!mScroller!!.isFinished) {
                mScroller!!.abortAnimation()
            }
            scrollBy(dx, dy)
        }
        mLastScroll = AnimationUtils.currentAnimationTimeMillis()
    }

    /**
     * Like [.scrollTo], but scroll smoothly instead of immediately.
     *
     * @param x the position where to scroll on the X axis
     * @param y the position where to scroll on the Y axis
     */
    fun smoothScrollTo(x: Int, y: Int) {
        smoothScrollBy(x - scrollX, y - scrollY)
    }

    /**
     *
     * The scroll range of a scroll view is the overall height of all of its
     * children.
     */
    override fun computeVerticalScrollRange(): Int {
        val count = childCount
        return if (count == 0) height else getChildAt(0).bottom
    }

    override fun computeHorizontalScrollRange(): Int {
        val count = childCount
        return if (count == 0) width else getChildAt(0).right
    }

    override fun measureChild(
        child: View,
        parentWidthMeasureSpec: Int,
        parentHeightMeasureSpec: Int
    ) {
        val lp = child.layoutParams
        val childWidthMeasureSpec: Int
        val childHeightMeasureSpec: Int
        childWidthMeasureSpec = ViewGroup.getChildMeasureSpec(
            parentWidthMeasureSpec,
            paddingLeft + paddingRight,
            lp.width
        )
        childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
        child.measure(childWidthMeasureSpec, childHeightMeasureSpec)
    }

    override fun measureChildWithMargins(
        child: View,
        parentWidthMeasureSpec: Int,
        widthUsed: Int,
        parentHeightMeasureSpec: Int,
        heightUsed: Int
    ) {
        val lp = child.layoutParams as MarginLayoutParams
        val childWidthMeasureSpec =
            MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED)
        val childHeightMeasureSpec =
            MeasureSpec.makeMeasureSpec(lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED)
        child.measure(childWidthMeasureSpec, childHeightMeasureSpec)
    }

    override fun computeScroll() {
        if (mScroller!!.computeScrollOffset()) {
            // This is called at drawing time by ViewGroup.  We don't want to
            // re-show the scrollbars at this point, which scrollTo will do,
            // so we replicate most of scrollTo here.
            //
            //         It's a little odd to call onScrollChanged from inside the drawing.
            //
            //         It is, except when you remember that computeScroll() is used to
            //         animate scrolling. So unless we want to defer the onScrollChanged()
            //         until the end of the animated scrolling, we don't really have a
            //         choice here.
            //
            //         I agree.  The alternative, which I think would be worse, is to post
            //         something and tell the subclasses later.  This is bad because there
            //         will be a window where mScrollX/Y is different from what the app
            //         thinks it is.
            //
            val oldX = scrollX
            val oldY = scrollY
            val x = mScroller!!.currX
            val y = mScroller!!.currY
            if (childCount > 0) {
                val child = getChildAt(0)
                scrollTo(
                    clamp(x, width - paddingRight - paddingLeft, child.width),
                    clamp(y, height - paddingBottom - paddingTop, child.height)
                )
            } else {
                scrollTo(x, y)
            }
            if (oldX != scrollX || oldY != scrollY) {
                onScrollChanged(scrollX, scrollY, oldX, oldY)
            }

            // Keep on drawing until the animation has finished.
            postInvalidate()
        }
    }

    override fun onLayout(
        changed: Boolean,
        l: Int,
        t: Int,
        r: Int,
        b: Int
    ) {
        super.onLayout(changed, l, t, r, b)
        // Calling this with the present values causes it to re-clam them
        scrollTo(scrollX, scrollY)
    }

    /**
     * Fling the scroll view
     *
     * @param velocityY The initial velocity in the Y direction. Positive
     * numbers mean that the finger/curor is moving down the screen,
     * which means we want to scroll towards the top.
     */
    fun fling(velocityX: Int, velocityY: Int) {
        if (childCount > 0) {
            val height = height - paddingBottom - paddingTop
            val bottom = getChildAt(0).height
            val width = width - paddingRight - paddingLeft
            val right = getChildAt(0).width
            mScroller!!.fling(
                scrollX,
                scrollY,
                velocityX,
                velocityY,
                0,
                right - width,
                0,
                bottom - height
            )
            awakenScrollBars(mScroller!!.duration)
            invalidate()
        }
    }

    /**
     * {@inheritDoc}
     *
     *
     * This version also clamps the scrolling to the bounds of our child.
     */
    override fun scrollTo(x: Int, y: Int) {
        // we rely on the fact the View.scrollBy calls scrollTo.
        var x = x
        var y = y
        if (childCount > 0) {
            val child = getChildAt(0)
            x = clamp(x, width - paddingRight - paddingLeft, child.width)
            y = clamp(y, height - paddingBottom - paddingTop, child.height)
            if (x != scrollX || y != scrollY) {
                super.scrollTo(x, y)
            }
        }
    }

    private fun clamp(n: Int, my: Int, child: Int): Int {
        if (my >= child || n < 0) {
            /* my >= child is this case:
             *                    |--------------- me ---------------|
             *     |------ child ------|
             * or
             *     |--------------- me ---------------|
             *            |------ child ------|
             * or
             *     |--------------- me ---------------|
             *                                  |------ child ------|
             *
             * n < 0 is this case:
             *     |------ me ------|
             *                    |-------- child --------|
             *     |-- mScrollX --|
             */
            return 0
        }
        return if (my + n > child) {
            /* this case:
                 *                    |------ me ------|
                 *     |------ child ------|
                 *     |-- mScrollX --|
                 */
            child - my
        } else n
    }


    private class GestureListener : SimpleOnGestureListener() {
        override fun onDown(e: MotionEvent): Boolean {
            return true
        }

        // event when double tap occurs
        override fun onDoubleTap(e: MotionEvent): Boolean {
            // double tap fired.
            return true
        }
    }
}
package com.app.xyz
导入android.annotation.SuppressLint
导入android.content.Context
导入android.util.AttributeSet
导入android.view*
导入android.view.GestureDetector.SimpleOnGestureListener
导入android.view.scalegestruedetector.SimpleOnScalegestrueListener
导入android.view.ViewGroup
导入android.view.animation.AnimationUtils
导入android.view.animation.ScaleAnimation
导入android.widget.LinearLayout
导入android.widget.Scroller
进口木材
导入java.lang.String
导入java.util*
第二类CrollView:线性布局{
val动画_滚动_间隙=250
val TWO\u DSCROLL\u VIEW\u CAN\u HOST\u ONLY\u ONE\u DIRECT\u CHILD=
“TwoDScrollView只能承载一个直接子级”
私有变量MLASTCROLL:Long=0
专用滚动条:滚动条?=null
/**
*最后一个运动事件的位置。
*/
专用变量mLastMotionY=0f
专用变量mLastMotionX=0f
/**
*如果用户当前正在拖动此TwoDScrollView,则为True。这是
*与“正在被扔”不同,可以通过
*mScroller.isFinished()。
*/
private var misbeingdraugd=false
/**
*确定触摸滚动期间的速度
*/
私有变量mVelocityTracker:VelocityTracker?=null
/**
*箭头滚动是否已设置动画。
*/
私有变量mTouchSlop=0
私有变量mMinimumVelocity=0
专用变量mScale=1f
专用变量mScaleDetector:ScaleGetStureDetector?=null
私有变量gestureDetector:gestureDetector?=null
私有val mEnableScaling=
true//单击子视图时缩放有问题
构造函数(上下文:上下文?):超级(上下文!!){
initTwoDScrollView()
}
构造函数(上下文:context?,属性集?):super(
上下文
属性
) {
initTwoDScrollView()
}
覆盖乐趣getTopFadingEdgeStrength():浮点{
if(childCount==0){
返回0.0f
}
val长度=垂直渐变边长度
返回if(滚动<长度){
scrollY/length.toFloat()
}其他1.0f
}
覆盖有趣的getBottomFadingEdgeStrength():Float{
if(childCount==0){
返回0.0f
}
val长度=垂直渐变边长度
val bottomEdge=高度-填充底部
val span=getChildAt(0).底部-滚动-底部边缘
返回if(跨度<长度){
span/length.toFloat()
}其他1.0f
}
覆盖有趣的getLeftFadingEdgeStrength():Float{
if(childCount==0){
返回0.0f
}
val长度=水平渐变边长度
返回if(scrollX{
/*记住下触的位置*/mLastMotionY=y
mLastMotionX=x
/*
*如果被投掷,用户触摸屏幕,启动拖动。。。
*否则,当
*被抛弃。
*/错误被拖动=错误
}
MotionEvent.ACTION\u取消,MotionEvent.ACTION\u向上->/*释放拖动*/misbeingdraugd=
假的
}
/*
*我们想要截取运动事件的唯一时间是在
*拖动模式。
*/返回错误被拖动
}
覆盖事件(ev:MotionEvent):布尔值{
如果(ev.action==MotionEvent.action\u DOWN&&ev.edgeFlags!=0){
//不要立即处理边缘接触——它们实际上可能属于我们的一个团队
//后代。
返回错误
}
如果(!canScroll()){
返回错误
}
if(mVelocityTracker==null){
mVelocityTracker=VelocityTracker.get()
}
mVelocityTracker!!.addMovement(ev)
val动作=ev动作
valy=ev.y
val x=ev.x
何时(行动){
MotionEvent.ACTION\u向下->{
/*
*如果被投掷并且用户触摸,停止投掷。isFinished
*将会失败