user2815899
user2815899

Reputation: 253

How to properly implement onFling method?

Okay,In this piece of code I get that your creating instance variables of type gesture detector which will call the FlingGestureListener.class.I'm getting the error a super interface must be an interface but I have created it as of type "interface".The id gives an error also when I refer it to my xml layout name.Implementing FlingGestureListner so my studentGallery class looks like this now and implements the FlingGestureListener:

public class GalleryStudent extends Activity implements FlingGestureLitener {

     private static final int MAJOR_MOVE = 0;


    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_galery_student);

            final GestureDetector gdt = new GestureDetector(getActivity(),
            FlingGestureListener.getInstance(tabSwipeListener));
            final ImageView peopleTab = (ImageView)getActivity().findViewById(R.id.activity_galery_student);

            peopleTab.setOnTouchListener(new View.OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return gdt.onTouchEvent(event);
                }
            });
            Gallery g = (Gallery) findViewById(R.id.gallery);
            g.setAdapter(new ImageAdapter(this));

            g.setOnItemClickListener(new OnItemClickListener() {
                public void onItemClick(@SuppressWarnings("rawtypes") AdapterView parent, View v, int position, long id) {
                    Toast.makeText(GalleryStudent.this, "" + position, Toast.LENGTH_SHORT).show();
                }
            });
        }

I'm confused here as you are using this to naviagate to the class : tabSwipeListener.onTabSwipe(true, PLACES_FRAGMENT); In this case you are taking a fragment as its parameter whereas my classes aren't fragments.Is there a simple way to change my classes to fragments to accommadate this?Also the onTabSwiperListener cannot be resolved to a type in this case.This is the FlingGestureListener I used from your explanation which I have created as an Interface:

public class FlingGestureListener extends SimpleOnGestureListener {

private static final int SWIPE_MIN_DISTANCE = 80;
private static final int SWIPE_THRESHOLD_VELOCITY = 50;
private static final int PEOPLE_FRAGMENT = 0;
private static final int PLACES_FRAGMENT = 2;
private OnTabSwipedListener tabSwipeListener;

private FlingGestureListener(OnTabSwipedListener tabSwipeListener){
    this.tabSwipeListener = tabSwipeListener;

}

/**
 * Static factory
 * @param listener called when tab swiped
 * @return
 */
public static FlingGestureListener getInstance(OnTabSwipedListener listener){
    return new FlingGestureListener(listener);
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
    if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        Log.d("SWIPE", "right to left");
        tabSwipeListener.onTabSwipe(true, PLACES_FRAGMENT); //sent int to fragment container to switch pager to that view 
        return true; //Right to left
    } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        Log.d("SWIPE", "left to right");
        tabSwipeListener.onTabSwipe(true, PEOPLE_FRAGMENT);
        return true; //Left to right 
    }

    //This will test for up and down movement. 
    if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        return false; //Bottom to top
    } else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        return false; //Top to bottom 
    }

    return false;
    }

}

Thanks for the help so far.

Upvotes: 1

Views: 2825

Answers (1)

Rarw
Rarw

Reputation: 7663

onFling is a method available to members of the SimpleOnGestureListener class. To override this method you either need to (1) create a class that extends SimpleOnGestureListener or (2) implement a gesture listener within your existing class. Then you can override onFling.

Update

Sorry for the delay. Here's my implementation. In the activity that you want to use the onFling you need to set up a GestureDetector that uses your custom onFling listener. You can see I'm using a FlingGestureListener the code for which is below. I'm listening for touch on a specific image, peopleTab, but you should be able to substitute any view.

    final GestureDetector gdt = new GestureDetector(getActivity(),    FlingGestureListener.getInstance(tabSwipeListener));
    final ImageView peopleTab = (ImageView)getActivity().findViewById(R.id.peopleFlag);

    peopleTab.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gdt.onTouchEvent(event);
        }
    });

Then for FlingGestureListener I use a separate class that extends SimpleOnGestureListener so I can choose to only implement onFling

public class FlingGestureListener extends SimpleOnGestureListener {

private static final int SWIPE_MIN_DISTANCE = 80;
private static final int SWIPE_THRESHOLD_VELOCITY = 50;
private static final int PEOPLE_FRAGMENT = 0;
private static final int PLACES_FRAGMENT = 2;
private OnTabSwipedListener tabSwipeListener;

private FlingGestureListener(OnTabSwipedListener tabSwipeListener){
    this.tabSwipeListener = tabSwipeListener;
}

/**
 * Static factory
 * @param listener called when tab swiped
 * @return
 */
public static FlingGestureListener getInstance(OnTabSwipedListener listener){
    return new FlingGestureListener(listener);
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
    if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        Log.d("SWIPE", "right to left");
        tabSwipeListener.onTabSwipe(true, PLACES_FRAGMENT); //sent int to fragment container to switch pager to that view 
        return true; //Right to left
    } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        Log.d("SWIPE", "left to right");
        tabSwipeListener.onTabSwipe(true, PEOPLE_FRAGMENT);
        return true; //Left to right 
    }

    //This will test for up and down movement. 
    if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        return false; //Bottom to top
    } else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
        return false; //Top to bottom 
    }

    return false;
}

}

I use a callback from this class to indicate when a swipe has occurred. The booleans that are returned are just to indicate whether the whole touch event has been handled. Hopefully this helps.

UPDATE 2

With the interfaces I am using something specific to my set up.

tabSwipeListener.onTabSwipe(true, PLACES_FRAGMENT); 

this indicates first that a swipe has occurred and in what direction. I use this in a 3 fragment ViewPager set up. From the middle page swiping right goes to a list of places and swiping left goes to a list of people. The PLACES_FRAGMENT constant for example is an integer that refers to the fragment id within the ViewPager. Passing back that integer I can then tell the ViewPager to change to display the fragment at position 2 which effectivtly moves the page.

I don't know how to give you a code example because I dont know that this is what you need to do. If you just need to detect a swipe then your interface need only pass back a boolean. If true you will know that the onFling method has been called and whatever threshold criteria you set have been met. You then need to handle that response appropritely within the context of your app. I don't think there is any more advice I can give you.

Upvotes: 1

Related Questions