9

I'm working on Gesture activity in android I used class to detect the swipe action is

public class ActivitySwipeDetector  implements View.OnTouchListener {

    static final String logTag = "ActivitySwipeDetector";
    private Activity activity;
    static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;

    public ActivitySwipeDetector(Activity activity){
        this.activity = activity;
    }

    public void onRightToLeftSwipe(){
        Log.i(logTag, "RightToLeftSwipe!");
        Toast.makeText(activity, "RightToLeftSwipe", Toast.LENGTH_SHORT).show();
        //activity.doSomething();
    }

    public void onLeftToRightSwipe(){
        Log.i(logTag, "LeftToRightSwipe!");
        Toast.makeText(activity, "LeftToRightSwipe", Toast.LENGTH_SHORT).show();
        //activity.doSomething();
    }

    public void onTopToBottomSwipe(){
        Log.i(logTag, "onTopToBottomSwipe!");
        //Toast.makeText(activity, "onTopToBottomSwipe", Toast.LENGTH_SHORT).show();
        //activity.doSomething();
    }

    public void onBottomToTopSwipe(){
        Log.i(logTag, "onBottomToTopSwipe!");
        //Toast.makeText(activity, "onBottomToTopSwipe", Toast.LENGTH_SHORT).show();
        //activity.doSomething();
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // swipe horizontal?
                    if(Math.abs(deltaX) > MIN_DISTANCE){
                        // left or right
                        if(deltaX < 0) { this.onLeftToRightSwipe(); return true; }
                        if(deltaX > 0) { this.onRightToLeftSwipe(); return true; }
                    }
                    else {
                        Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                        return false; // We don't consume the event
                    }

                    // swipe vertical?
                    if(Math.abs(deltaY) > MIN_DISTANCE){
                        // top or down
                        if(deltaY < 0) { this.onTopToBottomSwipe(); return true; }
                        if(deltaY > 0) { this.onBottomToTopSwipe(); return true; }
                    }
                    else {
                        Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                        return false; // We don't consume the event
                    }

                    return true;
        }
        }
        return false;
    }

}

my xml file is

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/action_settings"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>

And in My activity I calling like this

ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
        LinearLayout lowestLayout = (LinearLayout)this.findViewById(R.id.action_settings);
        lowestLayout.setOnTouchListener(activitySwipeDetector);

I called ActivitySwipeDetector(this); so Its working fine with full activity. But how can I apply Swipe detector only to LinearLayout not to the Whole Activity. Please help me out.

Android learner
  • 1,871
  • 4
  • 24
  • 36
  • You're attaching the touch listener for a particular view. Decide what view you want to detect swipes on, and attach it to that proper view. If you attach it to the top level view in the activity like you did here, it will work on the whole activity. – Gabe Sechan Jul 27 '13 at 22:56
  • But if I attach child view its not works... – Android learner Jul 28 '13 at 07:05

2 Answers2

23

Needed for me and best was your code, so I fixed a bit, need more fix, see the comment

public class RelativeLayoutTouchListener implements OnTouchListener {

    static final String logTag = "ActivitySwipeDetector";
    private Activity activity;
    static final int MIN_DISTANCE = 100;// TODO change this runtime based on screen resolution. for 1920x1080 is to small the 100 distance
    private float downX, downY, upX, upY;

    // private MainActivity mMainActivity;

    public RelativeLayoutTouchListener(MainActivity mainActivity) {
        activity = mainActivity;
    }

    public void onRightToLeftSwipe() {
        Log.i(logTag, "RightToLeftSwipe!");
        Toast.makeText(activity, "RightToLeftSwipe", Toast.LENGTH_SHORT).show();
        // activity.doSomething();
    }

    public void onLeftToRightSwipe() {
        Log.i(logTag, "LeftToRightSwipe!");
        Toast.makeText(activity, "LeftToRightSwipe", Toast.LENGTH_SHORT).show();
        // activity.doSomething();
    }

    public void onTopToBottomSwipe() {
        Log.i(logTag, "onTopToBottomSwipe!");
        Toast.makeText(activity, "onTopToBottomSwipe", Toast.LENGTH_SHORT).show();
        // activity.doSomething();
    }

    public void onBottomToTopSwipe() {
        Log.i(logTag, "onBottomToTopSwipe!");
        Toast.makeText(activity, "onBottomToTopSwipe", Toast.LENGTH_SHORT).show();
        // activity.doSomething();
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // swipe horizontal?
            if (Math.abs(deltaX) > MIN_DISTANCE) {
                // left or right
                if (deltaX < 0) {
                    this.onLeftToRightSwipe();
                    return true;
                }
                if (deltaX > 0) {
                    this.onRightToLeftSwipe();
                    return true;
                }
            } else {
                Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long horizontally, need at least " + MIN_DISTANCE);
                // return false; // We don't consume the event
            }

            // swipe vertical?
            if (Math.abs(deltaY) > MIN_DISTANCE) {
                // top or down
                if (deltaY < 0) {
                    this.onTopToBottomSwipe();
                    return true;
                }
                if (deltaY > 0) {
                    this.onBottomToTopSwipe();
                    return true;
                }
            } else {
                Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long vertically, need at least " + MIN_DISTANCE);
                // return false; // We don't consume the event
            }

            return false; // no swipe horizontally and no swipe vertically
        }// case MotionEvent.ACTION_UP:
        }
        return false;
    }

}

Usage:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    rlTop = (RelativeLayout) findViewById(R.id.rlTop);      
    rlTop.setOnTouchListener(new RelativeLayoutTouchListener(this));
}
0

I have had good results with the original code. But the listener needs to be added to a view, not a layout. We are extending View.OnTouchListener, after all.

R Earle Harris
  • 985
  • 9
  • 17
  • 1
    LinearLayout extends ViewGroup which extends View. I fail to see why a listener couldn't be added to a layout. – mhenry Dec 30 '14 at 17:07