使用GestureDetector时出现空指针异常

3
以下是在不同事件发生时为两个不同图像加载帧动画的代码。第一个事件是活动开始。其他事件是我使用GestureDetector的onDown()和onScroll()。问题是,当它在OnScroll()中时,我会得到NullPointerException。我发现它没有得到Y坐标,可能是什么问题。
package com.example.animationtry;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.widget.ImageView;

public class MainActivity extends Activity
{
    ImageView img,img1;
    AnimationDrawable animation;
    private GestureDetector gestureDetector;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        img=(ImageView)findViewById(R.id.image);
        img.post(new Runnable()
        {
            public void run()
            {
                img.setBackgroundResource(R.anim.frameanimation);
                AnimationDrawable frameAnimation =  (AnimationDrawable) img .getBackground();
                frameAnimation.setVisible(false, true);
                frameAnimation.start();
            }
        });
        img.setOnTouchListener(new View.OnTouchListener() 
        {
            public boolean onTouch(View v, MotionEvent event) 
            {
                String img="img";
                gestureDetector = new GestureDetector(new MyGestureDetector(img));
                if (gestureDetector.onTouchEvent(event)) 
                {
                    return true;
                }   
                return false;
            }
        });

        img1=(ImageView)findViewById(R.id.image1);
        img.post(new Runnable()
        {
            public void run()
            {
                img1.setBackgroundResource(R.anim.frameanimation);
                AnimationDrawable frameAnimation =  (AnimationDrawable) img1.getBackground();
                frameAnimation.setVisible(false, true);
                frameAnimation.start();
            }
        });
        img1.setOnTouchListener(new View.OnTouchListener() 
        {
            public boolean onTouch(View v, MotionEvent event) 
            {
                String img1="img1";
                gestureDetector = new GestureDetector(new MyGestureDetector(img1));
                if (gestureDetector.onTouchEvent(event)) 
                {
                    return true;
                }   
                return false;
            }
        });
    }

    class MyGestureDetector extends SimpleOnGestureListener
    {
        private static final int SWIPE_MAX_OFF_PATH = 40;
        private static final int SWIPE_THRESHOLD_VELOCITY = 30;
        String viewname;
        public MyGestureDetector(String view)
        {
            viewname=view;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) 
        {
            return true;
        }
        @Override
        public boolean onDown(MotionEvent e) 
        {
            Log.i("View Name",viewname);
            if(viewname.equalsIgnoreCase("img"))
            {
                img.setBackgroundResource(R.anim.clickanimation);
                animation = (AnimationDrawable)img.getBackground();
                animation.setVisible(false, true);
                animation.start();
            }
            else if(viewname.equalsIgnoreCase("img1"))
            {
                img1.setBackgroundResource(R.anim.clickanimation);
                animation = (AnimationDrawable)img1.getBackground();
                animation.setVisible(false, true);
                animation.start();
            }
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) 
        {
            Log.i("y1",Float.toString(e1.getY()));
            Log.i("y2",Float.toString(e2.getY()));
            Log.i("Drag View Name",viewname);
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH && Math.abs(distanceY) > SWIPE_THRESHOLD_VELOCITY) 
            {
                if(viewname.equalsIgnoreCase("img"))
                {
                    img.setBackgroundResource(R.anim.draganimaton);
                    animation = (AnimationDrawable)img.getBackground();
                    animation.setVisible(false, true);
                    animation.start();
                }
                else if(viewname.equalsIgnoreCase("img1"))
                {
                    img1.setBackgroundResource(R.anim.draganimaton);
                    animation = (AnimationDrawable)img1.getBackground();
                    animation.setVisible(false, true);
                    animation.start();
                }
                return true;
            }
            return true;
        }
    }
}

以下是logcat:

01-12 06:12:22.637: E/AndroidRuntime(1062): FATAL EXCEPTION: main
01-12 06:12:22.637: E/AndroidRuntime(1062): java.lang.NullPointerException
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.example.animationtry.MainActivity$MyGestureDetector.onScroll(MainActivity.java:117)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.GestureDetector.onTouchEvent(GestureDetector.java:541)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.example.animationtry.MainActivity$4.onTouch(MainActivity.java:69)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.View.dispatchTouchEvent(View.java:3881)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1878)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.os.Looper.loop(Looper.java:123)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at android.app.ActivityThread.main(ActivityThread.java:3683)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at java.lang.reflect.Method.invokeNative(Native Method)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at java.lang.reflect.Method.invoke(Method.java:507)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-12 06:12:22.637: E/AndroidRuntime(1062):     at dalvik.system.NativeStart.main(Native Method)

哦,我明白你想说什么了...你的意思是在onTouch()中返回true对吧。我已经这样做了,但还是出现了相同的错误。 - sankettt
@sankettt:问题是因为事件为空,是的,你是对的,你返回了true。那么尝试重写SimpleOnGestureListener的onTouchEvent方法。 - ρяσѕρєя K
它在onDown()事件中正常工作,但在onScroll()中不起作用。从logcat中可以看到它没有获取到X和Y的值。这个问题只出现在我改变构造函数时,因为我有多个图像,我需要每个图像的ID来知道要动画哪个图像。 - sankettt
1个回答

2

我遇到了一个问题,e1.getY()onScroll()中返回了空值,所以我去掉了这个检查部分,只用onScroll()distanceY来检查SWIPE_MAX_OFF_PATH,现在它完美地工作了。

package com.example.animationtry;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.widget.ImageView;

public class MainActivity extends Activity
{
    ImageView img,img1;
    AnimationDrawable animation;
    private GestureDetector gestureDetector;
    private static final int SWIPE_MAX_OFF_PATH = 40;
    private static final int SWIPE_THRESHOLD_VELOCITY = 30;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        img=(ImageView)findViewById(R.id.image);
        img.post(new Runnable()
        {
            public void run()
            {
                img.setBackgroundResource(R.anim.frameanimation);
                AnimationDrawable frameAnimation =  (AnimationDrawable) img .getBackground();
                frameAnimation.setVisible(false, true);
                frameAnimation.start();
            }
        });
        img.setOnTouchListener(new View.OnTouchListener() 
        {
            public boolean onTouch(View v, MotionEvent event) 
            {
                String img="img";
                gestureDetector = new GestureDetector(new MyGestureDetector(img));
                if (gestureDetector.onTouchEvent(event)) 
                {
                    return true;
                }   
                return false;
            }
        });

        img1=(ImageView)findViewById(R.id.image1);
        img.post(new Runnable()
        {
            public void run()
            {
                img1.setBackgroundResource(R.anim.frameanimation);
                AnimationDrawable frameAnimation =  (AnimationDrawable) img1.getBackground();
                frameAnimation.setVisible(false, true);
                frameAnimation.start();
            }
        });
        img1.setOnTouchListener(new View.OnTouchListener() 
        {
            public boolean onTouch(View v, MotionEvent event) 
            {
                String img1="img1";
                gestureDetector = new GestureDetector(new MyGestureDetector(img1));
                if (gestureDetector.onTouchEvent(event)) 
                {
                    return true;
                }   
                return false;
            }
        });
    }

    class MyGestureDetector extends SimpleOnGestureListener
    {
        String viewname;
        public MyGestureDetector(String view)
        {
            viewname=view;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) 
        {

            return true;
        }
        @Override
        public boolean onDown(MotionEvent e) 
        {
            Log.i("View Name",viewname);
            if(viewname.equalsIgnoreCase("img"))
            {
                img.setBackgroundResource(R.anim.clickanimation);
                animation = (AnimationDrawable)img.getBackground();
                animation.setVisible(false, true);
                animation.start();
            }
            else if(viewname.equalsIgnoreCase("img1"))
            {
                img1.setBackgroundResource(R.anim.clickanimation);
                animation = (AnimationDrawable)img1.getBackground();
                animation.setVisible(false, true);
                animation.start();
            }
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) 
        {           
            Log.i("Drag View Name",viewname);
            if (Math.abs(distanceY)>SWIPE_MAX_OFF_PATH) 
            {
                Log.i("inside","drag");
                if(viewname.equalsIgnoreCase("img"))
                {
                    img.setBackgroundResource(R.anim.draganimaton);
                    animation = (AnimationDrawable)img.getBackground();
                    animation.setVisible(false, true);
                    animation.start();
                }
                else if(viewname.equalsIgnoreCase("img1"))
                {
                    img1.setBackgroundResource(R.anim.draganimaton);
                    animation = (AnimationDrawable)img1.getBackground();
                    animation.setVisible(false, true);
                    animation.start();
                }
            }
            return true;
        }
    }
}

在我的情况下,距离不超过+-3。我正在使用ListView并处理其父视图上的手势。 - CoDe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接