Question

I am getting a crash when I am implementing Touch events for my application. I would like to implement swipe functionality to my application. Here is my code:

GueturesImplementation:

package com.example.EventsView;

import android.app.Activity;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;

public class GuesterFilter extends SimpleOnGestureListener{

public final static int SWIPE_UP    = 1;
public final static int SWIPE_DOWN  = 2;
public final static int SWIPE_LEFT  = 3;
public final static int SWIPE_RIGHT = 4;

public final static int MODE_TRANSPARENT = 0;
public final static int MODE_SOLID       = 1;
public final static int MODE_DYNAMIC     = 2;

private final static int ACTION_FAKE = -13; //just an unlikely number
private int swipe_Min_Distance = 100;
private int swipe_Max_Distance = 350;
private int swipe_Min_Velocity = 100;

private int mode      = MODE_DYNAMIC;
private boolean running = true;
private boolean tapIndicator = false;

private Activity context;
private GestureDetector detector;
private SimpleGestureListener listener;


public GuesterFilter(Activity context,SimpleGestureListener sgl) {

 this.context = context;
 this.detector = new GestureDetector(context, this);
 this.listener = sgl; 
}

public void onTouchEvent(MotionEvent event){

  if(!this.running)
 return;  

  boolean result = this.detector.onTouchEvent(event); 

  if(this.mode == MODE_SOLID)
event.setAction(MotionEvent.ACTION_CANCEL);
  else if (this.mode == MODE_DYNAMIC) {

 if(event.getAction() == ACTION_FAKE) 
   event.setAction(MotionEvent.ACTION_UP);
    else if (result)
   event.setAction(MotionEvent.ACTION_CANCEL); 
 else if(this.tapIndicator){
  event.setAction(MotionEvent.ACTION_DOWN);
  this.tapIndicator = false;
 }

     }
          //else just do nothing, it's Transparent
     }

     public void setMode(int m){
      this.mode = m;
     }

     public int getMode(){
      return this.mode;
     }

     public void setEnabled(boolean status){
      this.running = status;
     }

  public void setSwipeMaxDistance(int distance){
   this.swipe_Max_Distance = distance;
  }

  public void setSwipeMinDistance(int distance){
   this.swipe_Min_Distance = distance;
  }

  public void setSwipeMinVelocity(int distance){
   this.swipe_Min_Velocity = distance;
  }

  public int getSwipeMaxDistance(){
   return this.swipe_Max_Distance;
  }

  public int getSwipeMinDistance(){
   return this.swipe_Min_Distance;
  }

  public int getSwipeMinVelocity(){
       return this.swipe_Min_Velocity;
  }


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

   final float xDistance = Math.abs(e1.getX() - e2.getX());
   final float yDistance = Math.abs(e1.getY() - e2.getY());

   if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)
    return false;

   velocityX = Math.abs(velocityX);
        velocityY = Math.abs(velocityY);
         boolean result = false;

   if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){
    if(e1.getX() > e2.getX()) // right to left
     this.listener.onSwipe(SWIPE_LEFT);
    else
     this.listener.onSwipe(SWIPE_RIGHT);

    result = true;
   }
   else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){
    if(e1.getY() > e2.getY()) // bottom to up 
     this.listener.onSwipe(SWIPE_UP);
    else
     this.listener.onSwipe(SWIPE_DOWN);

    result = true;
   }

    return result;
  }

      @Override
       public boolean onSingleTapUp(MotionEvent e) {
        this.tapIndicator = true;
        return false;
       }

       @Override
       public boolean onDoubleTap(MotionEvent arg0) {
        this.listener.onDoubleTap();;
        return true;
       }

       @Override
       public boolean onDoubleTapEvent(MotionEvent arg0) {
        return true;
      }

       @Override
  public boolean onSingleTapConfirmed(MotionEvent arg0) {

   if(this.mode == MODE_DYNAMIC){        // we owe an ACTION_UP, so we fake an       
      arg0.setAction(ACTION_FAKE);      //action which will be converted to an ACTION_UP      later.                                    
      this.context.dispatchTouchEvent(arg0);  
   }   
 
   return false;
  }


     static interface SimpleGestureListener{
      void onSwipe(int direction);
      void onDoubleTap();
  }

 }

View Activity Implementation:

package com.example.EventsView;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;  
import android.widget.Toast;

import com.example.mobilefit.GuesterFilter.SimpleGestureListener;

public class BeginYourWorkout  extends Activity implements SimpleGestureListener
{
    private GuesterFilter detector; 
    protected void onCreate(Bundle savedInstanceState)
    {
         requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.eventsView);
    }

     public boolean dispatchTouchEvent(MotionEvent me)
 
     { 
        this.detector.onTouchEvent(me);
      return super.dispatchTouchEvent(me); 
     
     
     }
 
    @Override
public void onSwipe(int direction) 
{
      String str = "";
      
      switch (direction) {
      
      case GuesterFilter.SWIPE_RIGHT : str = "Swipe Right";
                                               break;
      case GuesterFilter.SWIPE_LEFT :  str = "Swipe Left";
                                                     break;
      case GuesterFilter.SWIPE_DOWN :  str = "Swipe Down";
                                                     break;
      case GuesterFilter.SWIPE_UP :    str = "Swipe Up";
                                                     break;
                                               
      } 
       Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
     }
@Override
public void onDoubleTap()
{
    Toast.makeText(this, "Double Tap", Toast.LENGTH_SHORT).show(); 
}
 public boolean onSingleTapUp(MotionEvent e) 
 {
     Toast.makeText(this, "Double Tap", Toast.LENGTH_SHORT).show(); 
      return false;
}
}

Error on log:

FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.myPackage.EventsView.dispatchTouchEvent(EventsView.java:27)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
at android.view.View.dispatchPointerEvent(View.java:7419)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:125)
at android.os.Looper.loop(Looper.java:124)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Was it helpful?

Solution

public GuesterFilter(Activity context,SimpleGestureListener sgl) is probably never called.

It must be called to initialized this.context at least.

Try this code:

public class BeginYourWorkout  extends Activity implements SimpleGestureListener
{
    private GuesterFilter detector; 
    protected void onCreate(Bundle savedInstanceState)
    {
         requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.eventsView);

        this.detector = new GuesterFilter(this, this);
    }

    //...
}

OTHER TIPS

You never instantiate a detector with new.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top