0

I'm working on a project that calls for the navigation bar to be implemented in a fashion similar to how the Zazzle application does their navigation bar. Animations are not my expertise so I would like to get some ideas from the dev community on how such an animation can be implemented.

This is an image of the navigation drawer, notice how the previous fragment stays in view on the left.

Zazzle_navigation_Drawer

This is a screen shot of the nav transition when the menu button is pressed. It turns and tucks its self away in the right hand side of the screen and when the menu is dismissed it reverses that process.

Zazzle_nav_transition

I'm looking for a suggestion on how this might be implemented and maybe some resources I should look into using or information to learn in order to have a good shot of replicating this effect.

What I've done so far.

I have watched and took notes on the Sliding Animations DevBytes video. So my strategy thus far is to make the navigation a fragment along with all my other screens and try and implement some sliding animations between them. I think this should give me the basic foundation.

Therefore I am more asking about how the animation would be constructed. I've never done animations before so I am asking for some help in the regards of how custom animations are implemented in android generally and a suggestion on how animation would be done in this case specifically

feilong
  • 1,564
  • 3
  • 16
  • 22

1 Answers1

0

If anyone stumbles upon this...

I figured this out by using the sample project from the Android developer training website. I created an anim folder in res and adding xml set files with the Object animator tag. I didnt understand how to manipulate the values correctly to get the desired animation but after some poking around i realized the following

 <objectAnimator
    android:valueFrom=
    android:valueTo=
    android:propertyName="
    android:interpolator=
    android:duration= />

The valueFrom tag and the valueTo tag define the points the animation runs between and android fills in the rest. The property name is used to describe what kind of motion is being manipulated (translationX, translationY, rotationX, translationY, scaleX and scaleY). The interpolator sets the rate of change of the animation and finally duration specifies how long the animation should take.

Once the animation files are made the following code can be used to set the animations on the fragments during a transaction.

 getFragmentManager()
                    .beginTransaction()        
                    .setCustomAnimations(
                            R.animator.exampleOut, R.animator.exampleIn,
                            R.animator.exampleOut, R.animator.exampleIn, 
                    ).add(R.id.container, new mFragment()).addToBackStack(null).commit();\

the first two parameters of setCustomAnimations() set the motion of the two fragments when the transaction is initiated and the last two parameters set the motion of the two fragments when the transaction is reversed, i.e., the back button is pressed.

This can be used to achieve the desired animation however I found that the outbound fragment would disappear from view for some reason. There fore I had to use AnimatorListener as follows:

Animator.AnimatorListener listener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator arg0) {
            getFragmentManager()
                    .beginTransaction()        
                    .setCustomAnimations(
                            R.animator.exampleOut, 0,
                            0, R.animator.exampleIn
                    )


                    .add(R.id.container, new mFragment())

                    .addToBackStack(null)

                    .commit();
        }
    };
    slideback(listener);

    mHandler.post(new Runnable() {
        @Override
        public void run() {
            invalidateOptionsMenu();
        }
    });
}

private void slideback(Animator.AnimatorListener listener) {
    View movingFragmentView = cardFrontFragment.getView();

    PropertyValuesHolder rotateY =  PropertyValuesHolder.ofFloat("rotationY", 15f);
    PropertyValuesHolder scaleX =  PropertyValuesHolder.ofFloat("scaleX", 0.8f);
    PropertyValuesHolder scaleY =  PropertyValuesHolder.ofFloat("scaleY", 0.8f);
    PropertyValuesHolder translateX = PropertyValuesHolder.ofFloat("translationX", 500f);
    ObjectAnimator movingFragmentAnimator = ObjectAnimator.
            ofPropertyValuesHolder(movingFragmentView, rotateY, scaleX, scaleY, translateX);



    ObjectAnimator movingFragmentRotator = ObjectAnimator.
            ofFloat(movingFragmentView, "rotationY",15f, 0f);
    movingFragmentAnimator.setDuration(DURATION_TIME);
    movingFragmentRotator.setStartDelay(DELAY_TIME);


    AnimatorSet s = new AnimatorSet();
    s.playTogether(movingFragmentAnimator, movingFragmentRotator);
    s.addListener(listener);
    s.start();
}
private void slideForward (Animator.AnimatorListener listener) {
    View movingFragmentView = cardFrontFragment.getView();

    PropertyValuesHolder rotateY =  PropertyValuesHolder.ofFloat("rotationY", 15f);
    PropertyValuesHolder scaleX =  PropertyValuesHolder.ofFloat("scaleX", 1.0f);
    PropertyValuesHolder scaleY =  PropertyValuesHolder.ofFloat("scaleY", 1.0f);
    PropertyValuesHolder translateX = PropertyValuesHolder.ofFloat("translationX", 0f);
    ObjectAnimator movingFragmentAnimator = ObjectAnimator.
            ofPropertyValuesHolder(movingFragmentView, rotateY, scaleX, scaleY, translateX);



    ObjectAnimator movingFragmentRotator = ObjectAnimator.
            ofFloat(movingFragmentView, "rotationY",15f, 0f);
    movingFragmentAnimator.setDuration(DURATION_TIME);
    movingFragmentRotator.setStartDelay(DELAY_TIME);
    movingFragmentRotator.setDuration(DURATION_TIME);


    AnimatorSet s = new AnimatorSet();
    s.playTogether(movingFragmentAnimator, movingFragmentRotator);
    s.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
           mShowingBack = false;
        }
    });
    s.start();
}

This allows you to set the properties for the outbound fragment dynamically during runtime and for some reason allows the fragment to remain in view.

feilong
  • 1,564
  • 3
  • 16
  • 22