使用onInterceptTouchEvent()时检测触摸事件

时间:2013-08-05 12:19:48

标签: android android-listview ontouchevent android-event

我在问这个相当复杂的问题,希望我能从你那里得到一个想法。

事情就是这样:我创建了一个自定义列表视图类,如上所示:

public class FolderListView extends ListView {

    private float xDistance, yDistance, lastX, lastY;
    private int folder_index;
    private FolderViewInterface openFolder;

    // private boolean swiping = false;

    // If built programmatically
    public FolderListView(Context context) {
        super(context);
    }

    // This example uses this method since being built from XML
    public FolderListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    // Build from XML layout
    public FolderListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

        case MotionEvent.ACTION_UP:
            // if (swiping == false) {

            //if (xDistance > yDistance)
            //  return false;
        //  else {
                folder_index = pointToPosition((int) lastX, (int) lastY);
            //  Toast.makeText(getContext(),
            //          "You pressed a folder with index: " + folder_index,
            //          Toast.LENGTH_SHORT).show();
        //  }
            HomeScreenFragment f = new HomeScreenFragment();
            openFolder = (FolderViewInterface) f;
            openFolder.onFolderOpened(folder_index);
            // }
            // swiping = false;
            break;

        case MotionEvent.ACTION_DOWN:
            // swiping = false;
            xDistance = yDistance = 0f;
            lastX = ev.getX();
            lastY = ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            // swiping = true;
            final float curX = ev.getX();
            final float curY = ev.getY();
            xDistance += Math.abs(curX - lastX);
            yDistance += Math.abs(curY - lastY);
            lastX = curX;
            lastY = curY;
            if (xDistance > yDistance)
                return false;
        }

        return super.onInterceptTouchEvent(ev);

    }

}

事情就在这里我正在寻找正确检测触摸事件。 我想要触摸打开另一个片段,但是现在片段在触摸和滑动时都会打开。

我使用了onInterceptTouchEvent,因为我列表中的元素是viewpage,滚动时它们的行为不正确。

我需要某种逻辑来检测滑动而不执行此部分:

HomeScreenFragment f = new HomeScreenFragment();
            openFolder = (FolderViewInterface) f;
            openFolder.onFolderOpened(folder_index);

仅当事件是触摸事件时,而不是滑动事件。

非常感谢任何建议/帮助,如果您需要更多详细信息,请与我们联系。

谢谢!

3 个答案:

答案 0 :(得分:2)

我正在根据PRESSED_STATE_DURATION

开始time 125

试试这个

//Declare as instance variables
int oldX,oldY,newX,newY;
//State the minimum distance of swipe that you forgive the user for ;)
int distance = 10;
int time = 125;
boolean cancel = false;
case MotionEvent.ACTION_DOWN:
cancel = false;
//Get x and y of touch
oldX = ev.getX();
oldY = ev.getY();
startActionTimer();

case MotionEvent.ACTION_MOVE:
//Get x and y of touch
newX = ev.getX();
newY = ev.getY();

case MotionEvent.ACTION_UP:
cancel = true;

private void startActionTimer(){
        //time is pressed state duration
          new CountDownTimer(time, time) {
             public void onTick(long millisUntilFinished) {}

             public void onFinish() {
                //Time to do our action!!!
                // please consider
                if((Math.abs(newX - oldX )< distance) && (Math.abs(newY - oldY ) <distance)){
                    if(cancel == false){
                    // Now its a touch so do your action
                    }
                }
             }
          }.start();
     }

注意:请将所有变量用作类变量(实例变量)以避免出现问题。因为有时我会得到价值没有正确更新的奇怪情况

OR

为什么不试试gesture detection

并覆盖onSingleTapUp方法

答案 1 :(得分:0)

如果您只是在触摸某个项目时需要执行某些操作,则不需要自定义ListView,您只需在listView的适配器.setOnItemClickListener()上设置一个侦听器。

答案 2 :(得分:0)

以下是我的问题的答案,我最终弄明白了。我只需要使用布尔变量来检查何时执行滑动,并在不滑动时执行相应的操作。它不是最好的解决方案,因为它非常敏感(甚至可以检测到最轻微的滑动尝试),但它仍然是它。

谢谢你们的帮助!

这是我更新的代码:

package ro.gebs.captoom.utils;

import ro.gebs.captoom.fragments.HomeScreenFragment;
import ro.gebs.captoom.interfaces.FolderViewInterface;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;

public class FolderListView extends ListView {

    private float xDistance, yDistance, lastX, lastY;
    private int folder_index;
    private FolderViewInterface openFolder;

    private boolean swiping = false;

    // If built programmatically
    public FolderListView(Context context) {
        super(context);
    }

    // This example uses this method since being built from XML
    public FolderListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    // Build from XML layout
    public FolderListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

        case MotionEvent.ACTION_UP:
            folder_index = pointToPosition((int) lastX, (int) lastY);
            if (!swiping) {
                HomeScreenFragment f = new HomeScreenFragment();
                openFolder = (FolderViewInterface) f;
                openFolder.onFolderOpened(folder_index);
            }
            swiping = false;
            break;

        case MotionEvent.ACTION_DOWN:
            xDistance = yDistance = 0f;
            lastX = ev.getX();
            lastY = ev.getY();

            break;
        case MotionEvent.ACTION_MOVE:
            final float curX = ev.getX();
            final float curY = ev.getY();
            xDistance += Math.abs(curX - lastX);
            yDistance += Math.abs(curY - lastY);
            lastX = curX;
            lastY = curY;
            if (xDistance > yDistance) {
                swiping = true;
                System.out.println("I AM HEREEEEEE");
                return false;
            }

        }

        return super.onInterceptTouchEvent(ev);

    }

}