Why Transition Framework:
We have already a very good api for Animation, why should U use it?
The transitions API is that it does an awful lot of the work for us.
Transition Framework
The transition framework provides a convenient API for animating between different UI states in an application. The framework is built around two key concepts: scenes and transitions.
Keep this always in mind: the view is not really moving from one layout to another. They are two independent views.
We have already a very good api for Animation, why should U use it?
The transitions API is that it does an awful lot of the work for us.
Transition Framework
The transition framework provides a convenient API for animating between different UI states in an application. The framework is built around two key concepts: scenes and transitions.
Scene
A scene defines a given state of an application's UI
Transition
A transition defines the animated change between two scenes.
When a scene changes, a
Transition
has two main responsibilities:
1. Capture the state of each view in both the start and end scenes, and
2. Create an
Animator
based on the differences that will animate the views from one scene to the other.
Q1 As Activity and Fragments already using animation
Activity#overridePendingTransition()
and FragmentTransaction#setCustomAnimation()
methods, , Why should I use Transition Framework?
That animation animate the entire Activity/Fragment container as a whole. The new Lollipop APIs making it possible to animate individual views as they enter or exit their containers and even allowing us to animate shared views from one Activity/Fragment container to the other.
Android Transition Framework can be used for three main things:
- Animate View elements in transitions between activites (or fragments)
- Animate shared elements (hero views) in transitions between activities (or fragments)
- Animate View elements from one activity scene to another.
1. Transitions between Activities
Animate existing activity layout content (non-hero views)
You can define these transitions declarative using XML or programatically.
Declarative
res/transition/activity_explode.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<explode android:duration="2000"/>
</transitionSet>
res/values/style.xml
<item name="android:windowEnterTransition">@transition/activity_explode.xml</item>
To inflate specific xml defined transition:
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupWindowAnimations();
}
private void setupWindowAnimations() {
Explode explode = TransitionInflater.from(this).inflateTransition(R.transition.activity_explode);
explode.setDuration(2000);
getWindow().setExitTransition(explode);
}
Programatically
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupWindowAnimations();
}
private void setupWindowAnimations() {
Explode explode = new Explode();
explode.setDuration(2000);
getWindow().setExitTransition(explode);
}
DetailActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupWindowAnimations();
}
private void setupWindowAnimations() {
Explode explode = new Explode();
explode.setDuration(2000);
getWindow().setEnterTransition(explode);
}
What is happening step by step:
- Activity A starts Activity B
- Transition Framework finds A Exit Transition (explode) and apply it to all visible views.
- Transition Framework finds B Enter Transition (explode) and apply it to all visible views.
- On Back Pressed Transition Framework executes Enter and Exit reverse animations respectively (because it cannot find
returnTransition
andreenterTransition
)
ReturnTransition & ReenterTransition
These two methods define the reverse animations for
enter
and exit
respectively.MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupWindowAnimations();
}
private void setupWindowAnimations() {
Explode explode = new Explode();
explode.setDuration(2000);
getWindow().setExitTransition(explode);
Fade fade = new Fade();
fade.setDuration(2000);
getWindow().setReenterTransition(fade);
}
DetailActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupWindowAnimations();
}
private void setupWindowAnimations() {
Explode explode = new Explode();
expl.setDuration(2000);
getWindow().setEnterTransition(explode);
Fade fade = new Fade();
fade.setDuration(2000);
getWindow().setReturnTransition(fade);
}
2. Shared elements between Activities
The idea behind this is having two different views in two different layouts and link them somehow with an animation.
Transition framework will then do whatever animations it consider necessary to show the user a transition from one view to another.
Keep this always in mind: the view is not really moving from one layout to another. They are two independent views.
As you can see there are two views with ids 'smallSquare' and 'bigSquare'. But they have the same'transitionName'.
This way the Transition Framework knows it needs to create an animation from one view to the other.
MainActivity.java
squareBlue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, DetailActivity2.class);
View sharedView = squareBlue;
String transitionName = getString(R.string.square_blue_name);
ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, sharedView, transitionName);
startActivity(i, transitionActivityOptions.toBundle());
}
});
layout/main_activity.xml
<View
android:layout_margin="10dp"
android:id="@+id/square_blue"
android:layout_width="50dp"
android:background="@android:color/holo_blue_light"
android:transitionName="@string/square_blue_name"
android:layout_height="50dp"/>
layou/details_activity2.xml
<View
android:layout_width="150dp"
android:id="@+id/big_square_blue"
android:layout_margin="10dp"
android:transitionName="@string/square_blue_name"
android:layout_centerInParent="true"
android:background="@android:color/holo_blue_light"
android:layout_height="150dp" />
As you can see, Transition framework is creating and executing an animation to create the illusion that the view is moving and changing shape.
To proof the blue square view is not really moving we can do this quick exercise: change transitioName in DetailsActivity from Big Blue Square to the Title Text above it.
<TextView
android:layout_width="wrap_content"
android:text="Activity Detail 2"
style="@style/Base.TextAppearance.AppCompat.Large"
android:layout_centerHorizontal="true"
android:transitionName="@string/square_blue_name"
android:layout_above="@+id/big_square_blue"
android:layout_height="wrap_content" />
If we now execute the app we have the same behaviour but targeting a different view:
3. Animate view layout elements
Transition framework can also be used to animate element changes within current activity layout.
Transitions happen between scenes. An scene defines a static state of our UI. You can do complex things regarding scenes but I want to keep this example as simple as possible.
If you want to know more about scenes I recomend you check this video by Chet Hasse
In this example I'm going to use the easier way to animate layout changes inside an Activity layout:
TransitionManager.beginDelayedTransition(sceneRoot);
With just this line of code we are telling the framework we are going to perform some UI changes that it will need to animate.
After that we made the changes on our UI elements:
setViewWidth(squareRed, 500);
setViewWidth(squareBlue, 500);
setViewWidth(squareGreen, 500);
setViewWidth(squareYellow, 500);
This will change those views width attribute to make it larger. That will trigger a
layoutMeasure
. At that point the Transition framework will record start and ending values and will create an animation to transition from one to another. squareGreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TransitionManager.beginDelayedTransition(sceneRoot);
setViewWidth(squareRed, 500);
setViewWidth(squareBlue, 500);
setViewWidth(squareGreen, 500);
setViewWidth(squareYellow, 500);
}
});
}
private void setViewWidth(View view, int x) {
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = x;
view.setLayoutParams(params);
}
No comments:
Post a Comment