Hi all,
In Today’s tutorial we will see how we can do a shared element transition between activities in android.
What we will do.
- We have two activities
- First activity has a TextView and two images.
- Second activity with two images.
- We will animation between corresponding images.
Check out the video below to see what we are going to do
Transitions to corresponding element is done by using the “transitionName” property mentioned in the views.
Lets look at the first activity layout
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:onClick="onClick" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="demo1.coderzheaven.com.animationdemo1.MainActivity"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_gravity="center" android:id="@+id/tv" android:text="Add a new Button with default transition" /> <LinearLayout android:id="@+id/l1" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> </LinearLayout> <ImageView android:id="@+id/sharedimage1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:transitionName="android_shared_1" android:src="@drawable/and1" /> <ImageView android:id="@+id/sharedimage2" android:layout_weight="1" android:src="@drawable/and2" android:transitionName="android_shared_2" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
activity_second.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:background="@color/colorAccent" tools:context="demo1.coderzheaven.com.animationdemo1.SecondActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <RelativeLayout android:id="@+id/content_second" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical"> <ImageView android:id="@+id/sharedimage1" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="match_parent" android:transitionName="android_shared_1" android:src="@drawable/and1" /> <ImageView android:id="@+id/sharedimage2" android:src="@drawable/and2" android:layout_alignParentTop="true" android:transitionName="android_shared_2" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>
Note that the two imageviews for which we want the transition will have same “android:transitionName” value.
for eg : android:transitionName=”android_shared_1″.
For all these animations to happen we need to specify transiton item in the XML or in java code for styles.
In XML
<item name="android:windowContentTransitions">true</item>
In Java
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
MainActivity.java
import android.animation.LayoutTransition; import android.app.ActivityOptions; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Simple Layout animation LayoutTransition l = new LayoutTransition(); l.enableTransitionType(LayoutTransition.CHANGING); ((ViewGroup) findViewById(R.id.l1)).setLayoutTransition(l); } findViewById(R.id.tv).setOnClickListener(this); findViewById(R.id.sharedimage1).setOnClickListener(this); findViewById(R.id.sharedimage2).setOnClickListener(this); } private void startNewActivityWithSharedTransition(View sharedImage) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { ActivityOptions options = ActivityOptions. makeSceneTransitionAnimation(MainActivity.this, sharedImage, sharedImage.getTransitionName()); intent.putExtra("TransName", sharedImage.getTransitionName()); startActivity(intent, options.toBundle()); } else { startActivity(intent); } } @Override public void onClick(View view) { if (view instanceof TextView) { if (((ViewGroup) findViewById(R.id.l1)).getChildCount() == 2) ((ViewGroup) findViewById(R.id.l1)).removeAllViews(); ((ViewGroup) findViewById(R.id.l1)).addView(new Button(this)); } else { startNewActivityWithSharedTransition(view); } } }
SecondActivity.java
import android.os.Build; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.ImageView; public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); Bundle b = getIntent().getExtras(); if (null != b) { String transName = getIntent().getExtras().getString("TransName"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { ImageView sharedImg1 = (ImageView) findViewById(R.id.sharedimage1); sharedImg1.setVisibility((transName.contentEquals(sharedImg1.getTransitionName()) ? View.VISIBLE : View.GONE)); ImageView sharedImg2 = (ImageView) findViewById(R.id.sharedimage2); sharedImg2.setVisibility((transName.contentEquals(sharedImg2.getTransitionName()) ? View.VISIBLE : View.GONE)); } } } @Override public void onBackPressed() { super.onBackPressed(); supportFinishAfterTransition(); } }
Now for reversing the transition you need to call “supportFinishAfterTransition()” instead of “finish” in the closing Activity.