Alejandro Casanova
Alejandro Casanova

Reputation: 3681

How to animate android fragment in and out of the screen with support library

I'm trying to show a fragment inside my activity wich contains a menu and it is supposed to slide in from the right side of the screen until the user dismisses it pressing the button again or pressing back button, then it should slide out to where it came from, both actions with an animation of course. The problem is that the fragment slides in, but I can't make it to slide out with the animation, it just pops out dissapearing. I've readed some similar posts but a haven't found any working solution for my situation.

Here is the code that should get the job done:

private void showMenuFragment() {

    if (this.frMenu == null) {
        this.frMenu = new MenuFragment();               
        FragmentTransaction transaction = this.getSupportFragmentManager()
                .beginTransaction();                    
        transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right);
        transaction.replace(R.id.fr_side_menu, this.frMenu);
        transaction.addToBackStack(MenuFragment.class.getName());
        transaction.commit();
    }
    else {
        this.frMenu = null;
        this.onBackPressed();
    }       
}

Animations:

File slide_in_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:duration="500"
        android:fromXDelta="100%"
        android:toXDelta="0%" >
    </translate>

</set>

File slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromXDelta="0%"
        android:toXDelta="100%" >
    </translate>

</set>

Please help!

Thanks in advance.

Upvotes: 3

Views: 2167

Answers (2)

Alejandro Casanova
Alejandro Casanova

Reputation: 3681

After some research I've found a very simple solution using a complete different approach, hope it helps somebody.

The things is animate in and out a layout containing the information formerly inside the fragment but without a fragment. Initially the layout visibility is set to "GONE" and it is showed in respnd to a user's action like swipe or pressing a button.

Here is the complete example:

1 - The activity handling user actions:

public class MainActivity extends Activity {

    private LinearLayout ll;
    private float startX;
    private Animation animLeft;
    private Animation animRight;

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

        ll = (LinearLayout) findViewById(R.id.slider);
        ll.setVisibility(View.GONE);

        animLeft = AnimationUtils.loadAnimation(this, R.anim.anim_left);
        animRight = AnimationUtils.loadAnimation(this, R.anim.anim_right);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            startX = event.getX();
            break;
        }
        case MotionEvent.ACTION_UP: {
            float endX = event.getX();

            if (endX < startX) {
                System.out.println("Move left");
                ll.setVisibility(View.VISIBLE);
                ll.startAnimation(animLeft);
            } 
            else {
                ll.startAnimation(animRight);
                ll.setVisibility(View.GONE);
            }
        }

        }
        return true;
    }

}

2 - The layout containing the sliding "menu":

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_bright" >

    <LinearLayout
        android:id="@+id/slider"
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="@android:color/darker_gray"
        android:content="@+id/content"
        android:gravity="bottom|center_horizontal"
        android:orientation="vertical" >

        <TextView
            android:id="@id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Surviving with android" />
    </LinearLayout>

</RelativeLayout>

Upvotes: 2

Sam Dozor
Sam Dozor

Reputation: 40744

The Android docs explain, for setCustomAnimations(int enter, int exit)

These animations will not be played when popping the back stack.

So, you must use the longer form, which has additional parameters for popEnter, and popExit:

transaction.setCustomAnimations(R.anim.slide_in_right, 
                                R.anim.slide_out_right, 
                                R.anim.slide_in_left, 
                                R.anim.slide_out_left);

To make this look right, you may want to define slide_in_left and slide_out_left, but that depends what you're going for...

Upvotes: 4

Related Questions