【问题标题】:Detect touch event when onInterceptTouchEvent() used使用 onInterceptTouchEvent() 时检测触摸事件
【发布时间】:2013-08-05 12:19:48
【问题描述】:

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

事情是这样的:我创建了一个自定义列表视图类,上面的那个:

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,因为我的列表中的元素是 viewpagers,滚动时它们的行为不正常。

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

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

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

非常感谢任何形式的建议/帮助,如果您需要更多详细信息,请告诉我。

谢谢!

【问题讨论】:

  • 为什么不直接将onClickListener 添加到您的项目视图中?
  • 试过了,不行...
  • 你能发布你的尝试代码吗?
  • folder_list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { System.out.println("TOUCHED!"); } }); 但是没有打印出来。 folder_list 是一个 FolderListView 项目对象,不为空。
  • 请注意:stackoverflow.com/questions/2220547/…。另外,我们可以看看你正在使用的 xml 布局吗?

标签: android android-listview touch-event android-event


【解决方案1】:

我在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();
     }

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

你为什么不试试gesture detection

并覆盖onSingleTapUp 方法

【讨论】:

  • 对不起,这对我不起作用......我已经尝试过你的代码,但我正在以这种方式失去我的初始功能:这不是拦截与寻呼机滑动的列表滚动,所以现在滚动不允许寻呼机滑动...根据我已经写的内容,我需要一些东西...但是非常感谢您的提示,我会更多地研究您的建议。
  • 该代码不会以任何方式停止滚动,如果您删除上面的代码,它也会工作相同,代码所做的只是在处理请求之前等待几毫秒看看它是否有影响,无论如何,祝你好运,如果你找到解决方案,请发布它,以便其他人发现它有帮助:)
  • 滚动工作,问题是滚动阻止寻呼机滑动,这就是为什么首先使用 onInterceptTouchEvent :)
【解决方案2】:

如果你只需要在一个项目被触摸时做一些事情,你不需要自定义ListView,你只需要在listView的适配器上设置一个监听器,.setOnItemClickListener()

【讨论】:

  • 就是这样,我需要做两件事:一是滑动,一是触摸。滑动由 viewpager 处理,两个事件相互干扰,这是我的问题...
  • 好吧,点击将由那个监听器处理,如果您在滑动时遇到问题,那么您应该看看requestDisallowInterceptTouchEvent()
  • 所以事情是滑动被viewpager的实现所覆盖并且工作正常。问题在于,当我滑动和触摸时,新片段会打开,我只需要在简单触摸时打开它......
【解决方案3】:

这是我问题的答案,我最终想通了。我只需要使用一个布尔变量来检查何时执行刷卡并在不刷卡时执行适当的操作。这不是最好的解决方案,因为它非常敏感(即使是最轻微的滑动尝试也能检测到),但它仍然是。

感谢大家的帮助!

这是我更新的代码:

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);

    }

}

【讨论】:

    猜你喜欢
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多