如何在 Android 中退出侦听器

How to exit from a listener in Android

我用 Google 搜索了很多,但仍然没有找到解决我问题的方法。我是 Android 的新手,很抱歉提出了一个愚蠢的问题。 这是我的代码:

final Intent myIntent = new Intent(this.getBaseContext(), ShowActivity.class);
webView.setOnTouchListener(new SwipeListener(this)
{
    @Override
    public void onSwipeLeft()
    {
        articleID--;
        //System.out.println("SWIPE_LEFT");
        myIntent.putExtra("id", articleID);
        System.out.println(myIntent.toString());
        Swiped = true;
    }
    @Override
    public void onSwipeRight()
    {
        articleID++;
        //System.out.println("SWIPE_RIGHT");
        myIntent.putExtra("id", articleID);
        System.out.println(myIntent.toString());
        Swiped = true;
    }
});
if (Swiped == true)
    mContext.startActivity(myIntent);

所以,问题是:为什么我的新 activity 没有启动?我的意思是它甚至没有进入 if 条件。似乎是因为监听器而忽略了下面的任何代码,不是吗?如何退出侦听器?顺便说一句,我正在尝试在 Swipe 上开始新的 activity。也许我需要重新设计架构?但是我真的不想 =(

这是我的 SwipeListener class:

public class SwipeListener implements View.OnTouchListener {
// Gesture Detector which has onTouchEvent action
// Gesture detector requires custom gesture listener (Which declared below)
private GestureDetector gestureDetector;
// Basic Construction
public SwipeListener(Context c) {
    gestureDetector = new GestureDetector(c, new GestureListener());
}
// onTouch action. Returns ANY (click and release) event thanks to onTouchEvent of gestureDetector
public boolean onTouch(final View view, final MotionEvent motionEvent) {
    return gestureDetector.onTouchEvent(motionEvent);
}

// GestureListener for GestureDetector declaration.
private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

    private static final int SWIPE_MIN_DISTANCE = 100; // Swipe minimal distance
    private static final int SWIPE_MIN_VELOCITY = 100; // swipe minimal speed

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }

    // Determines the fling velocity and then fires the appropriate swipe event accordingly
    // onFling MUST return false so don't touch it.
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        try {
            float diffY = e2.getY() - e1.getY(); // Y(vertical) Difference between release and press coordinates
            float diffX = e2.getX() - e1.getX(); // X(horizontal) Difference between release and press coordinates
            // Determine if swipe was in horizontal or in vertical align
            // Horizontal (left-right)
            if (Math.abs(diffX) > Math.abs(diffY)) {
                // Check if speed and distance are big enough
                if (Math.abs(diffX) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_MIN_VELOCITY) {
                    if (diffX > 0) {
                        onSwipeRight();
                    } else {
                        onSwipeLeft();
                    }
                }
            // Vertical (up-down)
            } else {
                if (Math.abs(diffY) > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_MIN_VELOCITY) {
                    if (diffY > 0) {
                        onSwipeDown();
                    } else {
                        onSwipeUp();
                    }
                }
            }
        } catch (Exception exception) {
            System.out.println("YOU SHALL NOT SWIPE");
        }
        return false;
    }
}

public void onSwipeRight() {
    // U need to override this
}

public void onSwipeLeft() {
    // and this
}

public void onSwipeUp() {
    // and this one too
}

public void onSwipeDown() {
    // U know what to do
}

}

这是一个日志:

01-09 19:21:36.564    7758-7758/com.weel.ur W/System.err﹕ java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getFlags()' on a null object reference
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.app.ContextImpl.startActivity(ContextImpl.java:1231)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.app.ContextImpl.startActivity(ContextImpl.java:1219)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.weel.ur.ShowActivity.startAct(ShowActivity.java:755)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.weel.ur.ShowActivity.onSwipeLeft(ShowActivity.java:347)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.weel.ur.calligraphy.SwipeListener$GestureListener.onFling(SwipeListener.java:51)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.GestureDetector.onTouchEvent(GestureDetector.java:610)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.weel.ur.calligraphy.SwipeListener.onTouch(SwipeListener.java:22)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.View.dispatchTouchEvent(View.java:8382)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2424)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2158)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2314)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1692)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.app.Activity.dispatchTouchEvent(Activity.java:2739)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:268)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2275)
01-09 19:21:36.565    7758-7758/com.weel.ur W/System.err﹕ at android.view.View.dispatchPointerEvent(View.java:8578)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4021)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3887)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5701)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5675)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5646)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5791)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.os.MessageQueue.nativePollOnce(Native Method)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.os.MessageQueue.next(MessageQueue.java:143)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.os.Looper.loop(Looper.java:122)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5221)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
01-09 19:21:36.566    7758-7758/com.weel.ur W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
01-09 19:21:36.567    7758-7758/com.weel.ur W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-09 19:21:36.567    7758-7758/com.weel.ur W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

您必须将 Swiped 的默认值设置为 false。因为您是在侦听器之外开始 activity,所以它甚至在您有机会触摸屏幕之前就被调用了。当 onTouchListener 被调用时 Swiped 的值被改变但你没有启动 activity。

    webView.setOnTouchListener(new SwipeListener(this)
    {
        @Override
        public void onSwipeLeft()
        {
            articleID--;
            //System.out.println("SWIPE_LEFT");
            Intent myIntent = new Intent(ShowActivity.this, ShowActivity.class);
            myIntent.putExtra("id", articleID);
            System.out.println(myIntent.toString());
            ShowActivity.this.startActivity(myIntent);
        }
        @Override
        public void onSwipeRight()
        {
            articleID++;
            //System.out.println("SWIPE_RIGHT");
            Intent myIntent = new Intent(ShowActivity.this, ShowActivity.class);
            myIntent.putExtra("id", articleID);
            System.out.println(myIntent.toString());
            Swiped = true;
            ShowActivity.this.startActivity(myIntent);
        }
    });

此外,您可能想在 articleID--articleID++ 之前添加一个条件。当您到达队列中的第一篇和最后一篇文章时,这将对您有所帮助。如果是这样,Swiped 应该设置为 false 或者您可以重置 articleID

您混淆了程序的流程。设置侦听器不会暂停程序,结束侦听器中的方法不会 return 到创建侦听器的方法。设置侦听器时,您 仅设置侦听器 ,而没有 运行。然后你的程序继续。

你的程序是这样的:

  1. 它为 webView 设置 SwipeListener。
  2. 它询问if (Swiped == true)。但是 Swiped 是假的,因为在设置时永远不会自动调用监听器,所以 activity 没有启动。
  3. 它继续前进。

当滑动发生时,您的程序仅运行监听器中定义的内容。 mContext.startActivity(myIntent); 不存在于 onSwipeLeft()onSwipeRight() 方法中。他们只是 putExtra,然后 println,然后将 Swipe 设置为 true。然后它继续使用用户界面,该界面刚刚调用了您的 onSwipe 方法之一。您必须在两个侦听器方法中插入 mContext.startActivity(myIntent);

您应该将代码更改为:

webView.setOnTouchListener(new SwipeListener(this)
{
    @Override
    public void onSwipeLeft()
    {
        articleID--;
        //System.out.println("SWIPE_LEFT");
        myIntent.putExtra("id", articleID);
        System.out.println(myIntent.toString());
        mContext.startActivity(myIntent);
    }
    @Override
    public void onSwipeRight()
    {
        articleID++;
        //System.out.println("SWIPE_RIGHT");
        myIntent.putExtra("id", articleID);
        System.out.println(myIntent.toString());
        mContext.startActivity(myIntent);
    }
});

更新:

关于新问题,您的 myIntent 似乎不知何故为空。这可能是因为在尝试修复它时更改了代码。无论如何,此更新可能不会让您失望。确保你完全按照我的描述去做。

webView.setOnTouchListener(new SwipeListener(this)
{
    @Override
    public void onSwipeLeft()
    {
        Intent myIntent = new Intent(mContext.getBaseContext(), ShowActivity.class);
        articleID--;
        myIntent.putExtra("id", articleID);
        System.out.println(myIntent.toString());
        mContext.startActivity(myIntent);
    }
    @Override
    public void onSwipeRight()
    {
        Intent myIntent = new Intent(mContext.getBaseContext(), ShowActivity.class);
        articleID++;
        myIntent.putExtra("id", articleID);
        System.out.println(myIntent.toString());
        mContext.startActivity(myIntent);
    }
});