├── .gitignore ├── README.md ├── app ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── test │ │ └── com │ │ └── activitysharedelementtransition │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── test │ │ └── com │ │ └── activitysharedelementtransition │ │ ├── ComposedActivity.java │ │ ├── HomeActivity.java │ │ ├── SharedElementTransitionActivity.java │ │ ├── SingleImageActivity.java │ │ ├── adapters │ │ ├── ComposedAdapter.java │ │ ├── DogAdapter.java │ │ └── SingleImageAdapter.java │ │ ├── fragments │ │ └── DogFragment.java │ │ └── intents │ │ ├── ComposedIntent.java │ │ ├── SharedElementTransitionIntent.java │ │ └── SingleImageIntent.java │ └── res │ ├── animator │ ├── fade_in.xml │ ├── fade_out.xml │ ├── slide_in_bottom_to_top.xml │ ├── slide_in_left_to_right.xml │ ├── slide_in_right_to_left.xml │ ├── slide_out_left_to_right.xml │ ├── slide_out_right_to_left.xml │ └── slide_out_top_to_bottom.xml │ ├── drawable │ ├── chiot1.jpg │ ├── chiot2.jpg │ ├── chiot3.jpg │ ├── chiot4.jpg │ ├── chiot5.jpg │ ├── chiot6.jpg │ ├── chiot7.jpg │ ├── chiot8.jpg │ ├── dog1.jpg │ ├── dog2.jpg │ └── dog3.jpg │ ├── layout │ ├── activity_composed.xml │ ├── activity_home.xml │ ├── activity_single_image.xml │ ├── activity_transition.xml │ ├── fragment_dog.xml │ ├── gridview_element.xml │ ├── gridview_element_composed.xml │ └── gridview_element_dog.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── transition │ ├── auto_transition.xml │ ├── change_bounds.xml │ ├── change_clip_bounds.xml │ ├── change_image_transform.xml │ ├── change_transform.xml │ ├── explode.xml │ ├── fade.xml │ ├── slide.xml │ ├── slide_bottom.xml │ ├── slide_left.xml │ ├── slide_right.xml │ └── slide_top.xml │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── color.xml │ ├── dimens.xml │ └── strings.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── githubactivitysharedtransitioncustom.gif ├── githubactivitysharedtransitioncustomfragment.gif ├── githubactivitysharedtransitionscale.gif ├── githubactivitysharedtransitionslide.gif ├── githubactivitysharedtransitionslidefragment.gif └── githubactivitysharedtransitionsscalefragment.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | .idea 30 | *.*~ 31 | *.iml 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ActivitySharedElementTransition 2 | Examples of shared element transitions between activities (minimum version : Lollipop) 3 | 4 | All examples are done with the explode activity transition. More details about activity transitions [here](https://github.com/lcwgg/ActivityTransition). 5 | 6 | More about shared elements transition on [Android developers website](https://developer.android.com/training/material/animations.html#Transitions). 7 | 8 | 9 | All examples can be done in xml or in java code. However, if you decide to define the transitions in java, all code concerning the transition must be present in both parent activity and target activity. To enabled the transition, add: 10 | 11 | ```xml 12 | true 13 | true 14 | ``` 15 | Or programmatically in both parent activity and target activity : 16 | 17 | ```java 18 | getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 19 | getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); 20 | ``` 21 | 22 | To set up a transition, Android provides these shared element transition: 23 | 24 | * `changeBounds` - Animates the changes in layout bounds of target views. 25 | * `changeClipBounds` - Animates the changes in clip bounds of target views. 26 | * `changeTransform` - Animates the changes in scale and rotation of target views. 27 | * `changeImageTransform` - Animates changes in size and scale of target images. 28 | 29 | When using xml, all these transition must be added in a *transition* folder created inside the *res* folder. 30 | Example of `changeBound` 31 | ```xml 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 46 | 47 | 48 | ``` 49 | 50 | ## Scaling transition 51 | This transition is the default one. you don't need to define anything. 52 | This transition can also be achieved by combining `changeBound` and `changeImageTransform` effect : 53 | ```xml 54 | 55 | 56 | ``` 57 | Simple image | With a fragment 58 | ------------ | ------------- 59 | ![Demo](images/githubactivitysharedtransitionscale.gif) | ![Demo](images/githubactivitysharedtransitionsscalefragment.gif) 60 | 61 | `changeImageTransform` is coupled with `changeBound` to have the correct bound animation or all animation starts from top left corner of the screen, which is not wanted in a list. Of course, `changeBound` is not needed if the transition is a single animation that needs to start from the top left cornerof the screen. 62 | 63 | ## Sliding transition 64 | This effect can be achieved like that: 65 | ```xml 66 | 67 | 68 | ``` 69 | or by defining the `autoTransition`: 70 | ```xml 71 | 72 | ``` 73 | Simple image | With a fragment 74 | ------------ | ------------- 75 | ![Demo](images/githubactivitysharedtransitionslide.gif) | ![Demo](images/githubactivitysharedtransitionslidefragment.gif) 76 | 77 | `changeTransform` is coupled with `changeBound` to have the correct bound animation or the image only appears as if it was a mere fade transition. 78 | 79 | ## Custom transition 80 | You can customized the transition with all the predefined option like `arcMotion`, `pathMotion`, `recolor`. 81 | Here is an example with `arcMotion` 82 | 83 | Simple image | With a fragment 84 | ------------ | ------------- 85 | ![Demo](images/githubactivitysharedtransitioncustom.gif) | ![Demo](images/githubactivitysharedtransitioncustomfragment.gif) 86 | 87 | ## Unknown bug 88 | I was forced to set the fragment transaction inside a `postDelayed()` method, it seems the transacion timing is not right which prevent the fragment entre transition not to appear correctly. 89 | 90 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "23.0.0 rc3" 6 | 7 | defaultConfig { 8 | applicationId "test.com.activitysharedelementtransition" 9 | minSdkVersion 21 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.jakewharton:butterknife:4.0.1' 25 | compile 'com.android.support:recyclerview-v7:22.2.1' 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/laetitia/Programs/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/test/com/activitysharedelementtransition/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/ComposedActivity.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition; 2 | 3 | import android.app.Activity; 4 | import android.app.Fragment; 5 | import android.os.Bundle; 6 | import android.transition.Explode; 7 | import android.transition.Fade; 8 | import android.transition.Slide; 9 | import android.transition.TransitionInflater; 10 | import android.transition.TransitionSet; 11 | import android.view.View; 12 | import android.view.Window; 13 | import android.widget.ImageView; 14 | import android.widget.TextView; 15 | 16 | import butterknife.ButterKnife; 17 | import butterknife.InjectView; 18 | import test.com.activitysharedelementtransition.fragments.DogFragment; 19 | import test.com.activitysharedelementtransition.intents.ComposedIntent; 20 | 21 | /** 22 | * Created by laetitia on 4/30/15. 23 | */ 24 | public class ComposedActivity extends Activity { 25 | 26 | @InjectView(R.id.view_imageview) 27 | ImageView mImageView; 28 | 29 | @InjectView(R.id.view_name) 30 | TextView mTextView; 31 | 32 | private DogFragment mDogFragment; 33 | 34 | @Override 35 | public void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | 38 | // enable the transition (only if theme different from Theme.Material) 39 | // getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); 40 | // getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 41 | 42 | // getWindow().setEnterTransition(new Fade()); 43 | // getWindow().setExitTransition(new Fade()); 44 | 45 | ComposedIntent intent = new ComposedIntent(getIntent()); 46 | 47 | setContentView(R.layout.activity_composed); 48 | ButterKnife.inject(this); 49 | 50 | mImageView.setImageResource(intent.getImageId()); 51 | mTextView.setText(intent.getTextViewContent()); 52 | 53 | mTextView.setTransitionName(intent.getTextViewContent()); 54 | mImageView.setTransitionName(intent.getTransitionName()); 55 | 56 | mDogFragment = new DogFragment(); 57 | 58 | mImageView.postDelayed(new Runnable() { 59 | @Override 60 | public void run() { 61 | mDogFragment.setEnterTransition(TransitionInflater.from(ComposedActivity.this).inflateTransition(R.transition.slide_bottom)); 62 | mDogFragment.setExitTransition(new Slide()); 63 | 64 | getFragmentManager().beginTransaction() 65 | .add(R.id.container, mDogFragment, DogFragment.TAG) 66 | .commit(); 67 | 68 | } 69 | }, 400); 70 | 71 | 72 | 73 | } 74 | 75 | 76 | @Override 77 | public void onBackPressed() { 78 | if (mDogFragment.isVisible()) { 79 | getFragmentManager().beginTransaction() 80 | .replace(R.id.container, new Fragment()) 81 | .commit(); 82 | } 83 | super.onBackPressed(); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/HomeActivity.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import butterknife.ButterKnife; 7 | import butterknife.OnClick; 8 | import test.com.activitysharedelementtransition.intents.SharedElementTransitionIntent; 9 | 10 | /** 11 | * Created by laetitia on 8/19/15. 12 | */ 13 | public class HomeActivity extends Activity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_home); 19 | ButterKnife.inject(this); 20 | } 21 | 22 | @OnClick(R.id.single_image) 23 | public void onSingleImageClick(){ 24 | SharedElementTransitionIntent intent = new SharedElementTransitionIntent(this, SharedElementTransitionActivity.Choice.SINGLE); 25 | startActivity(intent); 26 | } 27 | 28 | 29 | @OnClick(R.id.fragment) 30 | public void onFargmentClick(){ 31 | SharedElementTransitionIntent intent = new SharedElementTransitionIntent(this, SharedElementTransitionActivity.Choice.FRAGMENT); 32 | startActivity(intent); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/SharedElementTransitionActivity.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition; 2 | 3 | import android.app.Activity; 4 | import android.app.ActivityOptions; 5 | import android.os.Bundle; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.transition.AutoTransition; 9 | import android.transition.ChangeBounds; 10 | import android.transition.ChangeClipBounds; 11 | import android.transition.ChangeImageTransform; 12 | import android.transition.ChangeTransform; 13 | import android.transition.Explode; 14 | import android.transition.Fade; 15 | import android.transition.Slide; 16 | import android.transition.Transition; 17 | import android.util.Pair; 18 | import android.view.Gravity; 19 | import android.view.View; 20 | import android.view.Window; 21 | import android.widget.TextView; 22 | 23 | import java.util.ArrayList; 24 | 25 | import butterknife.ButterKnife; 26 | import butterknife.InjectView; 27 | import test.com.activitysharedelementtransition.adapters.ComposedAdapter; 28 | import test.com.activitysharedelementtransition.adapters.SingleImageAdapter; 29 | import test.com.activitysharedelementtransition.intents.ComposedIntent; 30 | import test.com.activitysharedelementtransition.intents.SharedElementTransitionIntent; 31 | import test.com.activitysharedelementtransition.intents.SingleImageIntent; 32 | 33 | public class SharedElementTransitionActivity extends Activity 34 | implements SingleImageAdapter.OnItemCLickListener, 35 | ComposedAdapter.OnItemCLickListener { 36 | 37 | @InjectView(test.com.activitysharedelementtransition.R.id.recyclerview) 38 | RecyclerView mRecyclerView; 39 | 40 | public enum Choice {SINGLE, FRAGMENT} 41 | 42 | @Override 43 | protected void onCreate(Bundle savedInstanceState) { 44 | super.onCreate(savedInstanceState); 45 | 46 | // enable the shared element transition (only if theme different from Theme.Material) 47 | // getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); 48 | // getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 49 | 50 | // getWindow().setEnterTransition(new Fade()); 51 | // getWindow().setExitTransition(new Fade()); 52 | 53 | setContentView(R.layout.activity_transition); 54 | ButterKnife.inject(this); 55 | 56 | ArrayList images = new ArrayList<>(); 57 | images.add(R.drawable.chiot1); 58 | images.add(R.drawable.chiot2); 59 | images.add(R.drawable.chiot3); 60 | images.add(R.drawable.chiot4); 61 | images.add(R.drawable.chiot5); 62 | images.add(R.drawable.chiot6); 63 | images.add(R.drawable.chiot7); 64 | images.add(R.drawable.chiot8); 65 | 66 | final RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this, 2); 67 | mRecyclerView.setLayoutManager(layoutManager); 68 | SharedElementTransitionIntent intent = new SharedElementTransitionIntent(getIntent()); 69 | 70 | final Choice choice = intent.getChoice(); 71 | 72 | if (choice == Choice.SINGLE) { 73 | final SingleImageAdapter adapter = new SingleImageAdapter(images); 74 | mRecyclerView.setAdapter(adapter); 75 | adapter.setOnItemClickListener(this); 76 | } else { 77 | final ComposedAdapter adapter = new ComposedAdapter(images); 78 | mRecyclerView.setAdapter(adapter); 79 | adapter.setOnItemClickListener(this); 80 | } 81 | 82 | } 83 | 84 | @Override 85 | public void onItemClick(View imageView, int imageRefId, String imageTransitionName) { 86 | final SingleImageIntent intent = new SingleImageIntent(this, imageRefId, imageTransitionName); 87 | final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, imageView, imageTransitionName); 88 | 89 | // Examples of transition 90 | // getWindow().setSharedElementEnterTransition(new ChangeBounds()); 91 | // getWindow().setSharedElementExitTransition(new ChangeBounds()); 92 | 93 | // getWindow().setSharedElementEnterTransition(new ChangeClipBounds()); 94 | // getWindow().setSharedElementExitTransition(new ChangeClipBounds()); 95 | 96 | // getWindow().setSharedElementEnterTransition(new ChangeTransform()); 97 | // getWindow().setSharedElementExitTransition(new ChangeTransform()); 98 | 99 | // getWindow().setSharedElementEnterTransition(new ChangeImageTransform()); 100 | // getWindow().setSharedElementExitTransition(new ChangeImageTransform()); 101 | 102 | // getWindow().setSharedElementEnterTransition(new AutoTransition()); 103 | // getWindow().setSharedElementExitTransition(new AutoTransition()); 104 | 105 | startActivity(intent, options.toBundle()); 106 | 107 | } 108 | 109 | @Override 110 | public void onItemClick(View imageView, View textView, int imageRefId, String imageTransitionName) { 111 | final String textViewContent = ((TextView)textView).getText().toString(); 112 | final ComposedIntent intent = new ComposedIntent(this, imageRefId, imageTransitionName, textViewContent); 113 | 114 | final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 115 | new Pair<>(imageView, imageTransitionName), 116 | new Pair<>(textView, textViewContent) 117 | ); 118 | startActivity(intent, options.toBundle()); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/SingleImageActivity.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.transition.AutoTransition; 6 | import android.transition.ChangeBounds; 7 | import android.transition.ChangeClipBounds; 8 | import android.transition.ChangeImageTransform; 9 | import android.transition.ChangeTransform; 10 | import android.transition.Explode; 11 | import android.transition.Transition; 12 | import android.view.Window; 13 | import android.widget.ImageView; 14 | 15 | import butterknife.ButterKnife; 16 | import butterknife.InjectView; 17 | import test.com.activitysharedelementtransition.intents.SingleImageIntent; 18 | 19 | /** 20 | * Created by laetitia on 4/30/15. 21 | */ 22 | public class SingleImageActivity extends Activity { 23 | 24 | @InjectView(test.com.activitysharedelementtransition.R.id.view_dog_imageview) 25 | ImageView mImageView; 26 | 27 | @Override 28 | public void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | 31 | // enable the shared element transition (only if theme different from Theme.Material) 32 | // getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); 33 | // getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 34 | 35 | // Examples of transition 36 | // getWindow().setSharedElementEnterTransition(new ChangeBounds()); 37 | // getWindow().setSharedElementExitTransition(new ChangeBounds()); 38 | 39 | // getWindow().setSharedElementEnterTransition(new ChangeClipBounds()); 40 | // getWindow().setSharedElementExitTransition(new ChangeClipBounds()); 41 | 42 | // getWindow().setSharedElementEnterTransition(new ChangeTransform()); 43 | // getWindow().setSharedElementExitTransition(new ChangeTransform()); 44 | 45 | // getWindow().setSharedElementEnterTransition(new ChangeImageTransform()); 46 | // getWindow().setSharedElementExitTransition(new ChangeImageTransform()); 47 | 48 | // getWindow().setSharedElementEnterTransition(new AutoTransition()); 49 | // getWindow().setSharedElementExitTransition(new AutoTransition()); 50 | 51 | setContentView(R.layout.activity_single_image); 52 | ButterKnife.inject(this); 53 | 54 | SingleImageIntent intent = new SingleImageIntent(getIntent()); 55 | // the image is originally from a listview, with no unique transition name specifically defined 56 | // Here, the transition names are generated on the fly 57 | // The transition name must be applied to the ImageView 58 | mImageView.setTransitionName(intent.getTransitionName()); 59 | mImageView.setImageResource(intent.getImageId()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/adapters/ComposedAdapter.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.adapters; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | 11 | import java.util.List; 12 | 13 | import butterknife.ButterKnife; 14 | import butterknife.InjectView; 15 | import test.com.activitysharedelementtransition.R; 16 | 17 | /** 18 | * Created by laetitia on 4/30/15. 19 | */ 20 | public class ComposedAdapter extends RecyclerView.Adapter { 21 | 22 | private OnItemCLickListener mItemClickListener; 23 | private List mImages; 24 | 25 | public ComposedAdapter(List images) { 26 | mImages = images; 27 | } 28 | 29 | public int getItem(int position) { 30 | return mImages.get(position); 31 | } 32 | 33 | @Override 34 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 35 | View v = LayoutInflater.from(viewGroup.getContext()) 36 | .inflate(R.layout.gridview_element_composed, viewGroup, false); 37 | 38 | return new ViewHolder(v); 39 | } 40 | 41 | public String getImageTransitionName(Context context, int position) { 42 | return context.getString(R.string.transition_name) + position; 43 | } 44 | 45 | @Override 46 | public void onBindViewHolder(ViewHolder viewHolder, int i) { 47 | viewHolder.mImageView.setImageResource(getItem(i)); 48 | viewHolder.mTextView.setText(String.format("Dog # %1$d", i)); 49 | viewHolder.mImageView.setTransitionName( 50 | getImageTransitionName(viewHolder.mImageView.getContext(), i) 51 | ); 52 | } 53 | 54 | @Override 55 | public int getItemCount() { 56 | return mImages.size(); 57 | } 58 | 59 | public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 60 | 61 | @InjectView(R.id.imageview) 62 | ImageView mImageView; 63 | @InjectView(R.id.textview) 64 | TextView mTextView; 65 | 66 | public ViewHolder(final View view) { 67 | super(view); 68 | ButterKnife.inject(this, view); 69 | view.setOnClickListener(this); 70 | } 71 | 72 | @Override 73 | public void onClick(View v) { 74 | if (mItemClickListener != null) { 75 | 76 | mItemClickListener.onItemClick( 77 | mImageView, 78 | mTextView, 79 | getItem(getLayoutPosition()), 80 | getImageTransitionName(mImageView.getContext(), getLayoutPosition()) 81 | ); 82 | } 83 | } 84 | } 85 | 86 | public interface OnItemCLickListener { 87 | void onItemClick(View imageView, View textView, int imageRefId, String imageTransitionName); 88 | } 89 | 90 | public void setOnItemClickListener(final OnItemCLickListener itemClickListener) { 91 | mItemClickListener = itemClickListener; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/adapters/DogAdapter.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.adapters; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | 9 | import java.util.List; 10 | 11 | import butterknife.ButterKnife; 12 | import butterknife.InjectView; 13 | import test.com.activitysharedelementtransition.R; 14 | 15 | /** 16 | * Created by laetitia on 4/30/15. 17 | */ 18 | public class DogAdapter extends RecyclerView.Adapter { 19 | 20 | private List mImages; 21 | 22 | public DogAdapter(List images) { 23 | mImages = images; 24 | } 25 | 26 | public int getItem(int position) { 27 | return mImages.get(position); 28 | } 29 | 30 | @Override 31 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 32 | View v = LayoutInflater.from(viewGroup.getContext()) 33 | .inflate(R.layout.gridview_element_dog, viewGroup, false); 34 | 35 | return new ViewHolder(v); 36 | } 37 | 38 | @Override 39 | public void onBindViewHolder(ViewHolder viewHolder, int i) { 40 | viewHolder.mImageView.setImageResource(getItem(i)); 41 | } 42 | 43 | @Override 44 | public int getItemCount() { 45 | return mImages.size(); 46 | } 47 | 48 | public class ViewHolder extends RecyclerView.ViewHolder { 49 | 50 | @InjectView(R.id.imageview) 51 | ImageView mImageView; 52 | 53 | public ViewHolder(final View view) { 54 | super(view); 55 | ButterKnife.inject(this, view); 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/adapters/SingleImageAdapter.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.adapters; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ImageView; 9 | 10 | import java.util.List; 11 | 12 | import butterknife.ButterKnife; 13 | import butterknife.InjectView; 14 | import test.com.activitysharedelementtransition.R; 15 | 16 | /** 17 | * Created by laetitia on 4/30/15. 18 | */ 19 | public class SingleImageAdapter extends RecyclerView.Adapter { 20 | 21 | private OnItemCLickListener mItemClickListener; 22 | private List mImages; 23 | 24 | public SingleImageAdapter(List images) { 25 | mImages = images; 26 | } 27 | 28 | public int getItem(int position) { 29 | return mImages.get(position); 30 | } 31 | 32 | @Override 33 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 34 | View v = LayoutInflater.from(viewGroup.getContext()) 35 | .inflate(R.layout.gridview_element, viewGroup, false); 36 | 37 | return new ViewHolder(v); 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(ViewHolder viewHolder, int i) { 42 | viewHolder.mImageView.setImageResource(getItem(i)); 43 | viewHolder.mImageView.setTransitionName( 44 | getImageTransitionName(viewHolder.mImageView.getContext(), i) 45 | ); 46 | } 47 | 48 | public String getImageTransitionName(Context context, int position) { 49 | return context.getString(R.string.transition_name) + position; 50 | } 51 | 52 | @Override 53 | public int getItemCount() { 54 | return mImages.size(); 55 | } 56 | 57 | public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 58 | 59 | @InjectView(R.id.imageview) 60 | ImageView mImageView; 61 | 62 | public ViewHolder(final View view) { 63 | super(view); 64 | ButterKnife.inject(this, view); 65 | view.setOnClickListener(this); 66 | } 67 | 68 | @Override 69 | public void onClick(View v) { 70 | if (mItemClickListener != null) { 71 | 72 | mItemClickListener.onItemClick( 73 | mImageView, 74 | getItem(getLayoutPosition()), 75 | getImageTransitionName(mImageView.getContext(), getLayoutPosition()) 76 | ); 77 | } 78 | } 79 | } 80 | 81 | public interface OnItemCLickListener { 82 | void onItemClick(View imageView, int imageRefId, String imageTransitionName); 83 | } 84 | 85 | public void setOnItemClickListener(final OnItemCLickListener itemClickListener) { 86 | mItemClickListener = itemClickListener; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/fragments/DogFragment.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.fragments; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.support.v7.widget.GridLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import butterknife.ButterKnife; 15 | import butterknife.InjectView; 16 | import test.com.activitysharedelementtransition.R; 17 | import test.com.activitysharedelementtransition.adapters.DogAdapter; 18 | 19 | /** 20 | * Created by laetitia on 4/30/15. 21 | */ 22 | public class DogFragment extends Fragment { 23 | 24 | public static final String TAG = DogFragment.class.getSimpleName(); 25 | 26 | @InjectView(R.id.recyclerview_dog) 27 | RecyclerView mRecyclerView; 28 | 29 | @Override 30 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 31 | super.onCreateView(inflater, container, savedInstanceState); 32 | final View v = inflater.inflate(R.layout.fragment_dog, container, false); 33 | ButterKnife.inject(this, v); 34 | return v; 35 | } 36 | 37 | @Override 38 | public void onActivityCreated(Bundle savedInstanceState) { 39 | super.onActivityCreated(savedInstanceState); 40 | 41 | final List images = new ArrayList<>(); 42 | images.add(R.drawable.dog1); 43 | images.add(R.drawable.dog2); 44 | images.add(R.drawable.dog3); 45 | 46 | final RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 1); 47 | final DogAdapter dogAdapter = new DogAdapter(images); 48 | mRecyclerView.setLayoutManager(layoutManager); 49 | mRecyclerView.setAdapter(dogAdapter); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/intents/ComposedIntent.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.intents; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import test.com.activitysharedelementtransition.ComposedActivity; 7 | 8 | /** 9 | * Created by laetitia on 4/30/15. 10 | */ 11 | public class ComposedIntent extends Intent { 12 | 13 | public static final String ARG_IMAGE_ID = "ARG_IMAGE_ID"; 14 | public static final String ARG_IMAGE_TRANSITION_NAME = "ARG_IMAGE_TRANSITION_NAME"; 15 | public static final String ARG_TEXTVIEW_CONTENT = "ARG_TEXTVIEW_CONTENT"; 16 | 17 | public ComposedIntent(Intent o) { 18 | super(o); 19 | } 20 | 21 | public ComposedIntent(Context packageContext, int imageId, String transitionName, String textViewContent) { 22 | super(packageContext, ComposedActivity.class); 23 | putExtra(ARG_IMAGE_ID, imageId); 24 | putExtra(ARG_IMAGE_TRANSITION_NAME, transitionName); 25 | putExtra(ARG_TEXTVIEW_CONTENT, textViewContent); 26 | } 27 | 28 | public int getImageId() { 29 | return getIntExtra(ARG_IMAGE_ID, -1); 30 | } 31 | 32 | public String getTransitionName() { 33 | return getStringExtra(ARG_IMAGE_TRANSITION_NAME); 34 | } 35 | 36 | public String getTextViewContent(){ 37 | return getStringExtra(ARG_TEXTVIEW_CONTENT); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/intents/SharedElementTransitionIntent.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.intents; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import test.com.activitysharedelementtransition.SharedElementTransitionActivity; 7 | 8 | /** 9 | * Created by laetitia on 8/19/15. 10 | */ 11 | public class SharedElementTransitionIntent extends Intent { 12 | 13 | public static final String ARG_CHOICE = "ARG_CHOICE"; 14 | 15 | public SharedElementTransitionIntent(Context context, SharedElementTransitionActivity.Choice choice) { 16 | super(context, SharedElementTransitionActivity.class); 17 | putExtra(ARG_CHOICE, choice); 18 | } 19 | 20 | public SharedElementTransitionIntent(Intent o) { 21 | super(o); 22 | } 23 | 24 | public SharedElementTransitionActivity.Choice getChoice() { 25 | return (SharedElementTransitionActivity.Choice) getExtras().get(ARG_CHOICE); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/test/com/activitysharedelementtransition/intents/SingleImageIntent.java: -------------------------------------------------------------------------------- 1 | package test.com.activitysharedelementtransition.intents; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import test.com.activitysharedelementtransition.SingleImageActivity; 7 | 8 | /** 9 | * Created by laetitia on 4/30/15. 10 | */ 11 | public class SingleImageIntent extends Intent { 12 | 13 | public static final String ARG_IMAGE_ID = "ARG_IMAGE_ID"; 14 | public static final String ARG_TRANSITION_IMAGE = "ARG_TRANSITION_IMAGE"; 15 | 16 | public SingleImageIntent(Intent o) { 17 | super(o); 18 | } 19 | 20 | public SingleImageIntent(Context packageContext, int imageId, String transitionName) { 21 | super(packageContext, SingleImageActivity.class); 22 | putExtra(ARG_IMAGE_ID, imageId); 23 | putExtra(ARG_TRANSITION_IMAGE, transitionName); 24 | } 25 | 26 | public int getImageId() { 27 | return getIntExtra(ARG_IMAGE_ID, -1); 28 | } 29 | 30 | public String getTransitionName() { 31 | return getStringExtra(ARG_TRANSITION_IMAGE); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/res/animator/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/animator/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/animator/slide_in_bottom_to_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/slide_in_left_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/slide_in_right_to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/slide_out_left_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/slide_out_right_to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/slide_out_top_to_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot3.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot4.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot6.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot7.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/chiot8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/chiot8.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/dog1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/dog1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/dog2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/dog2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/dog3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcwgg/ActivitySharedElementTransition/f98f68d440465e5267c7e54cf17ddae7ba985ff0/app/src/main/res/drawable/dog3.jpg -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_composed.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 13 | 22 | 23 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |