Rick Rick - 2 months ago 24
Android Question

Close one activity by swiping from right to left with smooth animation to go to second activity

I'd like to have an activity that introduces the app and to be closed you have to swipe it from right to left (perhaps with a smooth animation if It's not too much work), then there's the other part of the app I already have, that is

ActionBar tabs + Swipe Views
. I've read some Android guides like implement Swipe Views but they weren't my case.
Could you help me please?
[With "smooth animation" I mean that the swipe has to follow the finger]

Answer

I normally achieve this using a gesture listener:

First, define translation animations within res/anim:

slide_in_left.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"
            android:duration="@android:integer/config_longAnimTime"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_in_right.xml:

    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_longAnimTime"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_out_left.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="-50%p"
            android:duration="@android:integer/config_longAnimTime"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_out_right.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="50%p"
            android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

Then within your current activity class:

class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            try {
                float slope = (e1.getY() - e2.getY()) / (e1.getX() - e2.getX());
                float angle = (float) Math.atan(slope);
                float angleInDegree = (float) Math.toDegrees(angle);
                // left to right
                if (e1.getX() - e2.getX() > 20 && Math.abs(velocityX) > 20) {
                    if ((angleInDegree < 45 && angleInDegree > -45)) {                      
        startActivity(new Intent(CurrentActivitiy.this, NextActivity.class); 
        CurrentActivity.this.overridePendingTransition(
            R.anim.slide_in_left, R.anim.slide_out_right);
         finish();
        }
                    // right to left fling
                } else if (e2.getX() - e1.getX() > 20
                        && Math.abs(velocityX) > 20) {
                    if ((angleInDegree < 45 && angleInDegree > -45)) {
        startActivity(new Intent(CurrentActivitiy.this, NextActivity.class); 
        CurrentActivity.this.overridePendingTransition(
            R.anim.slide_in_right, R.anim.slide_out_left);
         finish();

                    }
                }
                return true;
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }

You can then register any view to receive/listen for the gestures:

 final GestureDetector  gestureDetector = new GestureDetector(new MyGestureDetector());
         //the parent layout   
                findViewById(R.id.parent_layout).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
         //an image view
        findViewById(R.id.image_view).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
        // a text view
        findViewById(R.id.text_view).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
Comments