{"id":13694894,"url":"https://github.com/lgvalle/Material-Animations","last_synced_at":"2025-05-03T04:31:18.570Z","repository":{"id":28351485,"uuid":"31865176","full_name":"lgvalle/Material-Animations","owner":"lgvalle","description":"Android Transition animations explanation with examples.","archived":false,"fork":false,"pushed_at":"2019-04-02T15:42:38.000Z","size":8692,"stargazers_count":13518,"open_issues_count":20,"forks_count":2471,"subscribers_count":520,"default_branch":"master","last_synced_at":"2025-04-10T16:44:18.205Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lgvalle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-08T20:54:00.000Z","updated_at":"2025-04-10T12:17:46.000Z","dependencies_parsed_at":"2022-06-26T08:31:30.140Z","dependency_job_id":null,"html_url":"https://github.com/lgvalle/Material-Animations","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgvalle%2FMaterial-Animations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgvalle%2FMaterial-Animations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgvalle%2FMaterial-Animations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgvalle%2FMaterial-Animations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lgvalle","download_url":"https://codeload.github.com/lgvalle/Material-Animations/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252144558,"owners_count":21701434,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T17:01:47.160Z","updated_at":"2025-05-03T04:31:13.560Z","avatar_url":"https://github.com/lgvalle.png","language":"Java","readme":"# UNMAINTAINED\nNo maintainance is intended. \nThe content is still valid as a reference but it won't contain the latest new stuff\n\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Material--Animations-brightgreen.svg?style=flat)](http://android-arsenal.com/details/3/1880)\n\n[Android Transition Framework][transition-framework] can be used for **three** main things:\n\n1. Animate activity layout content when transitioning from one activity to another.\n2. Animate shared elements (Hero views) in transitions between activities.\n3. Animate view changes within same activity.\n\n\n## 1. Transitions between Activities\n\nAnimate existing activity layout **content**\n\n![A Start B][transition_a_to_b]\n\nWhen transitioning from `Activity A` to `Activity B` content layout is animated according to defined transition. There are three predefined transitions available on `android.transition.Transition` you can use: **Explode**, **Slide** and **Fade**. \nAll these transitions track changes to the visibility of target views in activity layout and animate those views to follow transition rules.\n\n[Explode][explode_link] | [Slide][slide_link] | [Fade][fade_link]\n--- | --- | ---\n![transition_explode] | ![transition_slide] | ![transition_fade]\n\n\nYou can define these transitions **declarative** using XML or **programmatically**. For the Fade Transition sample, it would look like this:\n\n### Declarative\nTransitions are defined on XML files in `res/transition`\n\n\u003e res/transition/activity_fade.xml\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cfade xmlns:android=\"http://schemas.android.com/apk/res/\"\n    android:duration=\"1000\"/\u003e\n\n```\n\n\u003e res/transition/activity_slide.xml\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cslide xmlns:android=\"http://schemas.android.com/apk/res/\"\n    android:duration=\"1000\"/\u003e\n\n```\n\nTo use these transitions you need to inflate them using `TransitionInflater`\n\n\u003e MainActivity.java\n \n```java\n\t@Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_transition);\n        setupWindowAnimations();\n    }\n\n    private void setupWindowAnimations() {\n        Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);\n        getWindow().setExitTransition(slide);\n    }\n\n```\n\n\u003e TransitionActivity.java\n \n```java\n\t@Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_transition);\n        setupWindowAnimations();\n    }\n\n    private void setupWindowAnimations() {\n        Fade fade = TransitionInflater.from(this).inflateTransition(R.transition.activity_fade);\n        getWindow().setEnterTransition(fade);\n    }\n\n```\n\n### Programmatically \n\n\u003e MainActivity.java\n \n```java\n\t@Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_transition);\n        setupWindowAnimations();\n    }\n\n    private void setupWindowAnimations() {\n        Slide slide = new Slide();\n        slide.setDuration(1000);\n        getWindow().setExitTransition(slide);\n    }\n\n```\n\n\u003e TransitionActivity.java\n \n```java\n\t@Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_transition);\n        setupWindowAnimations();\n    }\n\n    private void setupWindowAnimations() {\n        Fade fade = new Fade();\n        fade.setDuration(1000);\n        getWindow().setEnterTransition(fade);\n    }\n\n```\n\n#### Any of those produce this result:\n\n![transition_fade]\n\n\n### What is happening step by step:\n\n1. Activity A starts Activity B\n\n2. Transition Framework finds A Exit Transition (slide) and apply it to all visible views.\n3. Transition Framework finds B Enter Transition (fade) and apply it to all visible views.\n4. **On Back Pressed** Transition Framework executes Enter and Exit reverse animations respectively (If we had defined output `returnTransition` and `reenterTransition`, these have been executed instead) \n\n### ReturnTransition \u0026 ReenterTransition\n\nReturn and Reenter Transitions are the reverse animations for Enter and Exit respectively.\n\n  * EnterTransition \u003c--\u003e ReturnTransition\n  * ExitTransition \u003c--\u003e ReenterTransition\n\nIf Return or Reenter are not defined, Android will execute a reversed version of Enter and Exit Transitions. But if you do define them, you can have different transitions for entering and exiting an activity.\n\n![b back a][transition_b_to_a]\n\nWe can modify previous Fade sample and define a `ReturnTransition` for `TransitionActivity`, in this case, a **Slide** transition. This way, when returning from B to A, instead of seeing a Fade out (reversed Enter Transition) we will see a **Slide out** transition\n \n\u003e TransitionActivity.java\n \n```java\n\t@Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_transition);\n        setupWindowAnimations();\n    }\n\n    private void setupWindowAnimations() {\n        Fade fade = new Fade();\n        fade.setDuration(1000);\n        getWindow().setEnterTransition(fade);\n        \n        Slide slide = new Slide();\n        slide.setDuration(1000);\n        getWindow().setReturnTransition(slide);        \n    }\n\n```\n\n\nObserve that if no Return Transition is defined then a reversed Enter Transition is executed.\nIf a Return Transition is defined that one is executed instead. \n\nWithout Return Transition | With Return Transition \n--- | --- \nEnter: `Fade In` | Enter: `Fade In`\nExit: `Fade Out` | Exit: `Slide out`\n![transition_fade] | ![transition_fade2] \n\n\n## 2. Shared elements between Activities\n\nThe idea behind this is having two different views in two different layouts and link them somehow with an animation.\n\nTransition framework will then do _whatever animations it consider necessary_ to show the user a transition from one view to another.\n\nKeep this always in mind: the view **is not really moving** from one layout to another. They are two independent views.\n\n\n![A Start B with shared][shared_element]\n\n\n### a) Enable Window Content Transition\n\nThis is something you need to set up once on your app `styles.xml`.\n\n\u003e values/styles.xml\n\n```xml\n\u003cstyle name=\"MaterialAnimations\" parent=\"@style/Theme.AppCompat.Light.NoActionBar\"\u003e\n    ...\n    \u003citem name=\"android:windowContentTransitions\"\u003etrue\u003c/item\n    ...\n\u003c/style\u003e\n```\n\nHere you can also specify default enter, exit and shared element transitions for the whole app if you want\n\n```xml\n\u003cstyle name=\"MaterialAnimations\" parent=\"@style/Theme.AppCompat.Light.NoActionBar\"\u003e\n    ...\n    \u003c!-- specify enter and exit transitions --\u003e\n    \u003citem name=\"android:windowEnterTransition\"\u003e@transition/explode\u003c/item\u003e\n    \u003citem name=\"android:windowExitTransition\"\u003e@transition/explode\u003c/item\u003e\n\n    \u003c!-- specify shared element transitions --\u003e\n    \u003citem name=\"android:windowSharedElementEnterTransition\"\u003e@transition/changebounds\u003c/item\u003e\n    \u003citem name=\"android:windowSharedElementExitTransition\"\u003e@transition/changebounds\u003c/item\u003e\n    ...\n\u003c/style\u003e\n```\n\n\n\n### b) Define a common transition name\n\nTo make the trick you need to give both, origin and target views, the same **`android:transitionName`**. They may have different ids or properties, but `android:transitionName` must be the same.\n\n\u003e layout/activity_a.xml\n\n```xml\n\u003cImageView\n        android:id=\"@+id/small_blue_icon\"\n        style=\"@style/MaterialAnimations.Icon.Small\"\n        android:src=\"@drawable/circle\"\n        android:transitionName=\"@string/blue_name\" /\u003e\n```\n\n\u003e layout/activity_b.xml\n\n```xml\n\u003cImageView\n        android:id=\"@+id/big_blue_icon\"\n        style=\"@style/MaterialAnimations.Icon.Big\"\n        android:src=\"@drawable/circle\"\n        android:transitionName=\"@string/blue_name\" /\u003e\n```\n\n### c) Start an activity with a shared element \n\nUse the `ActivityOptions.makeSceneTransitionAnimation()` method to define shared element origin view and transition name.\n\n\u003e MainActivity.java\n\n```java\n\nblueIconImageView.setOnClickListener(new View.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n        Intent i = new Intent(MainActivity.this, SharedElementActivity.class);\n\n        View sharedView = blueIconImageView;\n        String transitionName = getString(R.string.blue_name);\n\n        ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, sharedView, transitionName);\n        startActivity(i, transitionActivityOptions.toBundle());\n    }\n});\n\n```\n\n\nJust that code will produce this beautiful transition animation:\n\n![a to b with shared element][shared_element_anim]\n\nAs you can see, Transition framework is creating and executing an animation to create the illusion that views are moving and changing shape from one activity to the other\n\n## Shared elements between fragments\n\nShared element transition works with Fragments in a very similar way as it does with activities. \n\nSteps **a)** and **b)** are exactly the **same**. Only **c)** changes\t\t\t\n\n### a) Enable Window Content Transition\n\n\u003e values/styles.xml\n\n```xml\n\u003cstyle name=\"MaterialAnimations\" parent=\"@style/Theme.AppCompat.Light.NoActionBar\"\u003e\n    ...\n    \u003citem name=\"android:windowContentTransitions\"\u003etrue\u003c/item\u003e\n    ...\n\u003c/style\u003e\n```\n\n### b) Define a common transition name\n\n\u003e layout/fragment_a.xml\n\n```xml\n\u003cImageView\n        android:id=\"@+id/small_blue_icon\"\n        style=\"@style/MaterialAnimations.Icon.Small\"\n        android:src=\"@drawable/circle\"\n        android:transitionName=\"@string/blue_name\" /\u003e\n```\n\n\u003e layout/fragment_b.xml\n\n```xml\n\u003cImageView\n        android:id=\"@+id/big_blue_icon\"\n        style=\"@style/MaterialAnimations.Icon.Big\"\n        android:src=\"@drawable/circle\"\n        android:transitionName=\"@string/blue_name\" /\u003e\n```\n\n###  c) Start a fragment with a shared element\n\nTo do this you need to include shared element transition information as part of the **`FragmentTransaction`** process.\n\n```java\nFragmentB fragmentB = FragmentB.newInstance(sample);\n\n// Defines enter transition for all fragment views\nSlide slideTransition = new Slide(Gravity.RIGHT);\nslideTransition.setDuration(1000);\nsharedElementFragment2.setEnterTransition(slideTransition);\n\n// Defines enter transition only for shared element\nChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);\nfragmentB.setSharedElementEnterTransition(changeBoundsTransition);\n\ngetFragmentManager().beginTransaction()\n        .replace(R.id.content, fragmentB)\n        .addSharedElement(blueView, getString(R.string.blue_name))\n        .commit();\n```\n\nAnd this is the final result:\n\n![shared_element_no_overlap]\n\n## Allow Transition Overlap\n\nYou can define if enter and exit transitions can overlap each other. \n\nFrom [Android documentation](http://developer.android.com/intl/ko/reference/android/app/Fragment.html#getAllowEnterTransitionOverlap()):\n\u003e When **true**, the enter transition will start as soon as possible. \n\u003e \n\u003e When **false**, the enter transition will wait until the exit transition completes before starting.\n\nThis works for both Fragments and Activities shared element transitions.\n\n```java\nFragmentB fragmentB = FragmentB.newInstance(sample);\n\n// Defines enter transition for all fragment views\nSlide slideTransition = new Slide(Gravity.RIGHT);\nslideTransition.setDuration(1000);\nsharedElementFragment2.setEnterTransition(slideTransition);\n\n// Defines enter transition only for shared element\nChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);\nfragmentB.setSharedElementEnterTransition(changeBoundsTransition);\n\n// Prevent transitions for overlapping\nfragmentB.setAllowEnterTransitionOverlap(overlap);\nfragmentB.setAllowReturnTransitionOverlap(overlap);\n\ngetFragmentManager().beginTransaction()\n        .replace(R.id.content, fragmentB)\n        .addSharedElement(blueView, getString(R.string.blue_name))\n        .commit();\n```\n\nIt is very easy to spot the difference in this example:\n\nOverlap True | Overlap False\n--- | --- \nFragment_2 appears on top of Fragment_1 | Fragment_2 waits until Fragment_1 is gone\n![shared_element_overlap] | ![shared_element_no_overlap]\n \n\n\n## 3. Animate view layout elements\n\n### Scenes\nTransition Framework can also be used to animate element changes within current activity layout. \n\nTransitions happen between scenes. A scene is just a regular layout which **defines a static state of our UI**. You can transition from one scene to another and Transition Framework will animate views in between.\n\n```java\nscene1 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene1, this);\nscene2 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene2, this);\nscene3 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene3, this);\nscene4 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene4, this);\n\n(...)\n\n@Override\npublic void onClick(View v) {\n    switch (v.getId()) {\n        case R.id.button1:\n            TransitionManager.go(scene1, new ChangeBounds());\n            break;\n        case R.id.button2:\n            TransitionManager.go(scene2, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds));\n            break;\n        case R.id.button3:\n            TransitionManager.go(scene3, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential));\n            break;\n        case R.id.button4:\n            TransitionManager.go(scene4, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential_with_interpolators));\n            break;  \n    }\n}\n```\n\nThat code would produce transition between four scenes in the same activity. Each transition has a different animation defined. \n\nTransition Framework will take all visible views in current scene and calculate whatever necessary animations are needed to arrange those views according to next scene.\n\n![scenes_anim]\n\n\n### Layout changes\n\nTransition Framework can also be used to animate layout property changes in a view. You just need to make whatever changes you want and it will perform necessary animations for you\n\n#### a) Begin Delayed Transition\n\nWith just this line of code we are telling the framework we are going to perform some UI changes that it will need to animate.\n\n```java\nTransitionManager.beginDelayedTransition(sceneRoot);\n```\n#### b) Change view layout properties\n\n\n```java\nViewGroup.LayoutParams params = greenIconView.getLayoutParams();\nparams.width = 200;\ngreenIconView.setLayoutParams(params);\n\n```\n\nChanging view width attribute to make it smaller 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.\n\n    \n![view layout animation][view_layout_anim]\n\n\n## 4. (Bonus) Shared elements + Circular Reveal\nCircular Reveal is just an animation to show or hide a group of UI elements. It is available since API 21 in `ViewAnimationUtils` class. \n\n\nCircular Reveal animation can be used in combination of Shared Element Transition to create meaningful animations that smoothly teach the user what is happening in the app.\n\n![reveal_shared_anim]\n\nWhat is happening in this example step by step is:\n\n* Orange circle is a shared element transitioning from `MainActivity` to `RevealActivity`.\n* On `RevealActivity` there is a listener to listen for shared element transition end. When that happens it does two things:\n  * Execute a Circular Reveal animation for the Toolbar\n  * Execute a scale up animation on `RevealActivity` views using plain old `ViewPropertyAnimator`\n\n\n\u003e Listen to shared element enter transition end\n\n```java\nTransition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);\ngetWindow().setSharedElementEnterTransition(transition);\ntransition.addListener(new Transition.TransitionListener() {\n    @Override\n    public void onTransitionEnd(Transition transition) {\n        animateRevealShow(toolbar);\n        animateButtonsIn();\n    }\n    \n    (...)\n\n});\n        \n```\n\n\u003e Reveal Toolbar\n\n```java\nprivate void animateRevealShow(View viewRoot) {\n    int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;\n    int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;\n    int finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());\n\n    Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);\n    viewRoot.setVisibility(View.VISIBLE);\n    anim.setDuration(1000);\n    anim.setInterpolator(new AccelerateInterpolator());\n    anim.start();\n}\n```  \n\n\u003e Scale up activity layout views\n\n```java\nprivate void animateButtonsIn() {\n    for (int i = 0; i \u003c bgViewGroup.getChildCount(); i++) {\n        View child = bgViewGroup.getChildAt(i);\n        child.animate()\n                .setStartDelay(100 + i * DELAY)\n                .setInterpolator(interpolator)\n                .alpha(1)\n                .scaleX(1)\n                .scaleY(1);\n    }\n}\n```\n\n### More circular reveal animations\n\nThere are many different ways you can create a reveal animation. The important thing is to use the animation to help the user understand what is happening in the app.\n\n#### Circular Reveal from the middle of target view\n\n![reveal_green]\n\n```java\nint cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;\nint cy = viewRoot.getTop();\nint finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());\n\nAnimator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);\nviewRoot.setBackgroundColor(color);\nanim.start();\n```        \n\n#### Circular Reveal from top of target view + animations\n\n![reveal_blue]\n\n```java\nint cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;\nint cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;\nint finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());\n\nAnimator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);\nviewRoot.setBackgroundColor(color);\nanim.addListener(new AnimatorListenerAdapter() {\n    @Override\n    public void onAnimationEnd(Animator animation) {\n        animateButtonsIn();\n    }\n});\nanim.start();\n``` \n\n\n#### Circular Reveal from touch point\n\n![reveal_yellow]\n\n```java\n@Override\npublic boolean onTouch(View view, MotionEvent motionEvent) {\n    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {\n        if (view.getId() == R.id.square_yellow) {\n            revealFromCoordinates(motionEvent.getRawX(), motionEvent.getRawY());\n        }\n    }\n    return false;\n}\n```\n\n```java \nprivate Animator animateRevealColorFromCoordinates(int x, int y) {\n    float finalRadius = (float) Math.hypot(viewRoot.getWidth(), viewRoot.getHeight());\n\n    Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, x, y, 0, finalRadius);\n    viewRoot.setBackgroundColor(color);\n    anim.start();\n}\n```       \n\n#### Animate and Reveal\n\n![reveal_red]\n\n```java\nTransition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);\ntransition.addListener(new Transition.TransitionListener() {\n    @Override\n    public void onTransitionEnd(Transition transition) {\n        animateRevealColor(bgViewGroup, R.color.red);\n    }\n    (...)\n   \n});\nTransitionManager.beginDelayedTransition(bgViewGroup, transition);\nRelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);\nlayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);\nbtnRed.setLayoutParams(layoutParams);\n```         \n  \n\n# Sample source code\n\n**[https://github.com/lgvalle/Material-Animations](https://github.com/lgvalle/Material-Animations/)**\n\n\n# More information\n\n  * Alex Lockwood posts about Transition Framework. A great in deep into this topic: [http://www.androiddesignpatterns.com/2014/12/activity-fragment-transitions-in-android-lollipop-part1.html](http://www.androiddesignpatterns.com/2014/12/activity-fragment-transitions-in-android-lollipop-part1.html)\n  * Amazing repository with lot of Material Design samples by Saul Molinero: [https://github.com/saulmm/Android-Material-Examples](https://github.com/saulmm/Android-Material-Examples)\n  * Chet Hasse video explaining Transition framework: [https://www.youtube.com/watch?v=S3H7nJ4QaD8](https://www.youtube.com/watch?v=S3H7nJ4QaD8)\n\n\n\n[transition-framework]: https://developer.android.com/training/transitions/overview.html\n\n[explode_link]: https://developer.android.com/reference/android/transition/Explode.html\n[fade_link]: https://developer.android.com/reference/android/transition/Fade.html\n[slide_link]: https://developer.android.com/reference/android/transition/Slide.html\n\n[transition_explode]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/transition_explode.gif\n[transition_slide]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/transition_slide.gif\n[transition_fade]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/transition_fade.gif\n[transition_fade2]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/transition_fade2.gif\n[transition_a_to_b]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/transition_A_to_B.png\n[transition_b_to_a]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/transition_B_to_A.png\n\n[shared_element]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/shared_element.png\n[shared_element_anim]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/shared_element_anim.gif\n[shared_element_no_overlap]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/shared_element_no_overlap.gif\n[shared_element_overlap]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/shared_element_overlap.gif\n\n[scenes_anim]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/scenes_anim.gif\n[view_layout_anim]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/view_layout_anim.gif\n\n[reveal_blue]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/reveal_blue.gif\n[reveal_red]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/reveal_red.gif\n[reveal_green]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/reveal_green.gif\n[reveal_yellow]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/reveal_yellow.gif\n[reveal_shared_anim]: https://raw.githubusercontent.com/lgvalle/Material-Animations/master/screenshots/shared_reveal_anim.gif\n","funding_links":[],"categories":["Java","Libraries","动画系列","Libs","\u003ca name=\"Transition\"\u003eTransition\u003c/a\u003e"],"sub_categories":["Animations","\u003cA NAME=\"Animations\"\u003e\u003c/A\u003eAnimations","Personal Blog"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgvalle%2FMaterial-Animations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flgvalle%2FMaterial-Animations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgvalle%2FMaterial-Animations/lists"}