Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.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
Java 安卓-如何在屏幕上检测触摸是一个难题;卷轴;触摸?_Java_Android_Android Scrollview_Android Touch Event - Fatal编程技术网

Java 安卓-如何在屏幕上检测触摸是一个难题;卷轴;触摸?

Java 安卓-如何在屏幕上检测触摸是一个难题;卷轴;触摸?,java,android,android-scrollview,android-touch-event,Java,Android,Android Scrollview,Android Touch Event,我正在用Java创建一个android应用程序,在这个应用程序中,我在屏幕上有很多,所有这些都定义了onTouchListeners。它们被包装在中,因为它们占用的空间超过了屏幕上的可用空间 我的问题是:当我通过触摸屏幕并上下移动手指向上/向下滚动应用程序时,滚动按预期工作,但触摸的的onTouchListener也被触发(这可能也是预期的)-我不希望发生这种情况。我希望在触摸屏幕滚动时忽略onTouchListener 我怎样才能做到这一点?我不希望在用户滚动并“意外”在某个上触发onTouc

我正在用Java创建一个android应用程序,在这个应用程序中,我在屏幕上有很多
,所有这些都定义了onTouchListeners。它们被包装在
中,因为它们占用的空间超过了屏幕上的可用空间

我的问题是:当我通过触摸屏幕并上下移动手指向上/向下滚动应用程序时,滚动按预期工作,但触摸的
的onTouchListener也被触发(这可能也是预期的)-我不希望发生这种情况。我希望在触摸屏幕滚动时忽略onTouchListener


我怎样才能做到这一点?我不希望在用户滚动并“意外”在某个

上触发onTouchListener时运行我的函数。您可以识别如下移动操作:

view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if(event.getAction() == MotionEvent.ACTION_MOVE)
            {

            }

            return false;
        }
    });

在搜索了更多之后,我找到了Stimsoni。这样做的目的是检查
ACTION\u DOWN
ACTION\u UP
事件之间的时间是否低于或高于
ViewConfiguration.getTapTimeout()
给出的值

从文件中:

[返回]我们将等待的持续时间(毫秒),以查看触摸事件是点击还是滚动。如果用户未在此间隔内移动,则视为轻触

代码:

view.setOnTouchListener(新的OnTouchListener(){
私人长启动时间;
@凌驾
公共布尔onTouch(视图、运动事件){
if(event.getAction()==MotionEvent.ACTION\u向下){
startClickTime=System.currentTimeMillis();
}else if(event.getAction()==MotionEvent.ACTION\u UP){
if(System.currentTimeMillis()-startClickTime
我遇到了与您相同的问题,我通过
操作\u取消
解决了这个问题

motionEvent.getActionMasked()
等于
ACTION\u CANCEL
当以前感知到的动作(如您的情况下的
ACTION\u DOWN
)现在被滚动等其他手势“取消”时。您的代码可能如下:

view.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent e) {
        if (e.getActionMasked() == MotionEvent.ACTION_DOWN) {
            // perceive a touch action.
        } else if(e.getActionMasked() == MotionEvent.ACTION_UP ||
                e.getActionMasked() == MotionEvent.ACTION_CANCEL) {
            // ignore the perceived action.      
        }
    }

我希望这能有所帮助。

我也遇到过类似的问题,但通过一个文本视图,搜索将我带到了这里。文本内容可能会占用比屏幕上更多的空间。 简单的工作示例:(Kotlin)

class MainActivity:AppCompatActivity(){
内部类GestureTap:GestureDetector.SimpleOnGestureListener(){
覆盖有趣的onSingleTapUp(e:MotionEvent?):布尔值{
//点击这里。任何滚动动作都将被忽略
返回真值
}
}
@SuppressLint(“ClickableViewAccessibility”)
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView=findViewById(R.id.textView)
textView.movementMethod=ScrollingMovementMethod()
val gesturedector=gesturedector(此,GestureTap())
textView.setOnTouchListener{{,事件->gestureDetector.onTouchEvent(事件)}
}
}
1方法:

我发现最好的方法是检测第一次触摸,保存x点和y点,然后用第二次触摸来对抗它。如果第一次点击和第二次点击之间的距离非常近(我将10%作为近似值),那么简单点击的触摸则是滚动运动

 /**
 * determine whether two numbers are "approximately equal" by seeing if they
 * are within a certain "tolerance percentage," with `tolerancePercentage` given
 * as a percentage (such as 10.0 meaning "10%").
 *
 * @param tolerancePercentage 1 = 1%, 2.5 = 2.5%, etc.
 */
fun approximatelyEqual(desiredValue: Float, actualValue: Float, tolerancePercentage: Float): Boolean {
    val diff = Math.abs(desiredValue - actualValue) //  1000 - 950  = 50
    val tolerance = tolerancePercentage / 100 * desiredValue //  20/100*1000 = 200
    return diff < tolerance //  50<200      = true
}

var xPoint = 0f
var yPoint = 0f
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
    when(event.action) {

        MotionEvent.ACTION_DOWN -> {
            xPoint = event.x
            yPoint = event.y
            return true
        }

        MotionEvent.ACTION_UP -> {
            if (!approximatelyEqual(xPoint, event.x, 10f) || !approximatelyEqual(yPoint, event.y, 10f)) {
                //scrolling
            } else {
                //simple click
            }
        }
    }
    return false
}
最后,将其与您的视图绑定:

val mGestureDetector = GestureDetector(context, MyGestureDetector(object : GestureInterface {
                override fun setOnScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float) {
                    //handle the scroll
                }

                override fun onClick(e: MotionEvent) {
                    //handle the single click
                }

            }))


            view.setOnTouchListener(OnTouchListener { v, event -> mGestureDetector.onTouchEvent(event) })
为我工作:

View.OnTouchListener() {

@Override

public boolean onTouch(View v,MotionEvent event)
{
        if(event.getAction()!=MotionEvent.ACTION_DOWN)
        {
                     // Before touch
        }
        else {
                      // When touched
             }

  return true
});

看看这个,它可能会帮助你可以参考这个解决方案,谢谢;虽然没有真正解决我的问题,但它给了我更多搜索的想法,我能够解决问题。非常感谢。@Chris623谢谢!很高兴这有帮助。我想这也有道理。是否有一个原因,目前接受的答案对你来说不够好?旁注:你不应该在你的第一种方法中使用百分比,而应该使用固定的公差值。否则,如果x=100,公差为10px;如果x=1000,公差为100px;如果x=10,公差为1px。您不希望屏幕左侧的容忍度低于屏幕右侧:)
   interface GestureInterface {
    fun setOnScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float)
    fun onClick(e: MotionEvent)
}

class MyGestureDetector(val gestureInterfacePar: GestureInterface) : SimpleOnGestureListener() {

    override fun onSingleTapUp(e: MotionEvent): Boolean { 
        gestureInterfacePar.onClick(e)
        return false
    }

    override fun onLongPress(e: MotionEvent) {}
    override fun onDoubleTap(e: MotionEvent): Boolean {
        return false
    }

    override fun onDoubleTapEvent(e: MotionEvent): Boolean {
        return false
    }

    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
        return false
    }

    override fun onShowPress(e: MotionEvent) {
    }

    override fun onDown(e: MotionEvent): Boolean { 
        return true
    }

    override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
        gestureInterfacePar.setOnScroll(e1, e2, distanceX, distanceY)
        return false
    }

    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { 
        return super.onFling(e1, e2, velocityX, velocityY)
    }
}
val mGestureDetector = GestureDetector(context, MyGestureDetector(object : GestureInterface {
                override fun setOnScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float) {
                    //handle the scroll
                }

                override fun onClick(e: MotionEvent) {
                    //handle the single click
                }

            }))


            view.setOnTouchListener(OnTouchListener { v, event -> mGestureDetector.onTouchEvent(event) })
View.OnTouchListener() {

@Override

public boolean onTouch(View v,MotionEvent event)
{
        if(event.getAction()!=MotionEvent.ACTION_DOWN)
        {
                     // Before touch
        }
        else {
                      // When touched
             }

  return true
});