Sunday, June 14, 2015

Android Activity and Fragment Transition

Its very obvious to have a question "What is a Transition?"

Transition(s) is(are) is a new feature in android development which provide convenient APIs for animating between different UI states in application. This feature  was introduced in KitKat.

This framework is built around two key features-
  1. Scene  - A Scene defines a state of an application's UI.
  2. Transition - Transition basically is animated changes between two screens.
When Scene changes, a transition has to do two main works -
  1. Capture the state of each view in both start and end scene.
  2. Create an animation based on the differences that will animate views from old scene to new scene.
For Demo just consider an Screen which fades its views in or out when user interact with screen.
this can be achieved by below code easily.

public class FadeActivity extends Activity implements View.OnClickListener {
       
       private ViewGroup mGroupColor;
       private View mColor1View, mColor2View, mColor3View, m4View;
      
      @Override
       protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState); 
             setContentView(R.layout.activity_main);

             mGroupColor= (ViewGroup) findViewById(R.id.group_color_layout);
             mColor1View = findViewById(R.id.color_one);
             mColor2View = findViewById(R.id.color_two);
             mColor3View = findViewById(R.id.color_three);
             mColor4View = findViewById(R.id.color_four);

             mRootView.setOnClickListener(this);
      }
     
      @Override
       public void onClick(View v) { 
              TransitionManager.beginDelayedTransition(mGroupView, new Fade()); 
               toggleVisibility(mColor1View, mColor2View, mColor3View, mColor4View);
       }

       private static void toggleVisibility(View... views) {
              for (View view : views) {
                     boolean isVisible;
                     if(view.getVisibility() == View.VISIBLE)
                             isVisible=true;
                     if(isVisible)
                             view.setVisibility(View.INVISIBLE);
                     else  view.setVisibility(View.VISIBLE);
             }
       }
}


If I click  beginDelayedTransition() method got called in which scene root and a Fade transition passed as the arguments. And imminently captureStartValues() method got called for each view in the scene and the transition records each view's visibility.When the call returns, each view's visibility in the scene is changing from VISIBLE to INVISIBLE.
On the next display frame, captureEndValues() method got called for each view in the scene and the transition records each view's new updated visibility.
Then createAnimator() method will be called. And the transition observes start and end values of each view and notices a difference(views are VISIBLE in the start scene but INVISIBLE in the end).
The Fade transition uses this information to create and return an AnimatorSet that will fade each view's alpha property to 0f.
Returned animator will be run by framework and all views to gradually fade out of the screen.


Now we will see how this can be done using Lollipop's new Activity and Fragment transition APIs.


Activity & Fragment Transitions in Lollipop

In Android 5.0 and above transitions can  while switching between Activities or Fragments.

Lets Discuss the procedure to implement transition between activities(fragments).


FirstActivity is starting SecondActivity by startActivity() method.

Since Activity transition APIs provide exit, enter, return, and reenter transitions.
In Our case we can describe it as below:
  1. FirstActivity's exit transition determines how views in FristActivity are animated when FristActivity calls SecondActivity.
  2. SecondActivity's enter transition determines how views in SecondActivty are animated when FristActivity calls SecondActivity.
  3. SecondActivity's return transition determines how views in SecondActivity are animated when SecondActivity returns to fristActivity.
  4. FirstActiivty's reenter transition determines how views in fristActivity are animated when SecondActivty returns to FristActivity. 

At last transition framework apply APIs for these above two activities.
Two types of transition will be applied on this process
  1. Content Transition  - it determines how non shared views (transitioning views) enter and exit the Actvity Scene.
  2. Shared Element Transition -  it determines   how shared views (hero views) are animated between activities.

The exit and reenter content transitions for FirstActivity (the calling activity) are both null.
We can tell because the non-shared views in FirstActivty are not animated when the user exits and reenters the activity.
The enter content transition for SecondActivity(the called activity) uses a custom slide-in transition that shuffles the list items into place from the bottom of the screen.
The return content transition for SecondActivity is a TransitionSet that plays two child transitions in parallel: a Slide(Gravity.TOP) transition targeting the views in the top half of the activity and a Slide(Gravity.BOTTOM) transition targeting the views in the bottom half of the activity. The result is that the activity appears to "break in half" when the user clicks the back button and returns to FristrActivity.
The enter and return shared element transitions both use a ChangeImageTransform, causing the ImageView to be animated seamlessly between the two activities.

Creating a basic Activity transition is relatively easy using the new Lollipop APIs. Summarized below are the steps you must take in order to implement one in your application. In the posts that follow, we will go through much more advanced use-cases and examples, but for now the next two sections will serve as a good introduction:
Enable the new transition APIs by requesting the Window.FEATURE_ACTIVITY_TRANSITIONS window feature in your called and calling Activities, either programmatically or in your theme's XML.
Material-themed applications have this flag enabled by default.

To start an Activity transition with content transitions and shared elements, call the startActivity(Context, Bundle) method and pass the following Bundle as the second argument:

ActivityOptions.makeSceneTransitionAnimation(activity, pairs).toBundle();

where pairs is an array of Pair<View, String> objects listing the shared element views and names that you'd like to share between activities.

Don't forget to give your shared elements unique transition names, either programatically or in XML. Otherwise, the transition will not work properly!


To programatically trigger a return transition, call finishAfterTransition() instead of finish().


By default, material-themed applications have their enter/return content transitions started a tiny bit before their exit/reenter content transitions complete, creating a small overlap that makes the overall effect more seamless and dramatic. If you wish to explicitly disable this behavior, you can do so by calling the setWindowAllowEnterTransitionOverlap() and setWindowAllowReturnTransitionOverlap() methods or by setting the corresponding attributes in your theme's XML.

Same way the Fragment Transition API

If we are working with Fragment transitions, the API is similar with a few small differences:

Content exit, enter, reenter, and return transitions should be set by calling the corresponding methods in the Fragment class or as attributes in your Fragment's XML tag.
Shared element enter and return transitions should be set by calling the corresponding methods in the Fragment class or as attributes in your Fragment's XML.
Whereas Activity transitions are triggered by explicit calls to startActivity() and finishAfterTransition(), Fragment transitions are triggered automatically when a fragment is added, removed, attached, detached, shown, or hidden by a FragmentTransaction.
Shared elements should be specified as part of the FragmentTransaction by calling the addSharedElement(View, String) method before the transaction is committed.

Lots of thanks for reading.. Hope its helpful!

No comments:

Post a Comment