[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-4031":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":16,"starSnapshotCount":16,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},4031,"Material-Animations","lgvalle\u002FMaterial-Animations","lgvalle","Android Transition animations explanation with examples.","",null,"Java",13566,2444,517,16,0,1,45,"MIT License",false,"master",true,[],"2026-06-12 02:00:57","# 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:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAndroid%20Arsenal-Material--Animations-brightgreen.svg?style=flat)](http:\u002F\u002Fandroid-arsenal.com\u002Fdetails\u002F3\u002F1880)\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\u002Ftransition`\n\n> res\u002Ftransition\u002Factivity_fade.xml\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"utf-8\"?>\n\u003Cfade xmlns:android=\"http:\u002F\u002Fschemas.android.com\u002Fapk\u002Fres\u002F\"\n    android:duration=\"1000\"\u002F>\n\n```\n\n> res\u002Ftransition\u002Factivity_slide.xml\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"utf-8\"?>\n\u003Cslide xmlns:android=\"http:\u002F\u002Fschemas.android.com\u002Fapk\u002Fres\u002F\"\n    android:duration=\"1000\"\u002F>\n\n```\n\nTo use these transitions you need to inflate them using `TransitionInflater`\n\n> 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> 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> 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> 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 & ReenterTransition\n\nReturn and Reenter Transitions are the reverse animations for Enter and Exit respectively.\n\n  * EnterTransition \u003C--> ReturnTransition\n  * ExitTransition \u003C--> 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> 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> values\u002Fstyles.xml\n\n```xml\n\u003Cstyle name=\"MaterialAnimations\" parent=\"@style\u002FTheme.AppCompat.Light.NoActionBar\">\n    ...\n    \u003Citem name=\"android:windowContentTransitions\">true\u003C\u002Fitem\n    ...\n\u003C\u002Fstyle>\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\u002FTheme.AppCompat.Light.NoActionBar\">\n    ...\n    \u003C!-- specify enter and exit transitions -->\n    \u003Citem name=\"android:windowEnterTransition\">@transition\u002Fexplode\u003C\u002Fitem>\n    \u003Citem name=\"android:windowExitTransition\">@transition\u002Fexplode\u003C\u002Fitem>\n\n    \u003C!-- specify shared element transitions -->\n    \u003Citem name=\"android:windowSharedElementEnterTransition\">@transition\u002Fchangebounds\u003C\u002Fitem>\n    \u003Citem name=\"android:windowSharedElementExitTransition\">@transition\u002Fchangebounds\u003C\u002Fitem>\n    ...\n\u003C\u002Fstyle>\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> layout\u002Factivity_a.xml\n\n```xml\n\u003CImageView\n        android:id=\"@+id\u002Fsmall_blue_icon\"\n        style=\"@style\u002FMaterialAnimations.Icon.Small\"\n        android:src=\"@drawable\u002Fcircle\"\n        android:transitionName=\"@string\u002Fblue_name\" \u002F>\n```\n\n> layout\u002Factivity_b.xml\n\n```xml\n\u003CImageView\n        android:id=\"@+id\u002Fbig_blue_icon\"\n        style=\"@style\u002FMaterialAnimations.Icon.Big\"\n        android:src=\"@drawable\u002Fcircle\"\n        android:transitionName=\"@string\u002Fblue_name\" \u002F>\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> 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> values\u002Fstyles.xml\n\n```xml\n\u003Cstyle name=\"MaterialAnimations\" parent=\"@style\u002FTheme.AppCompat.Light.NoActionBar\">\n    ...\n    \u003Citem name=\"android:windowContentTransitions\">true\u003C\u002Fitem>\n    ...\n\u003C\u002Fstyle>\n```\n\n### b) Define a common transition name\n\n> layout\u002Ffragment_a.xml\n\n```xml\n\u003CImageView\n        android:id=\"@+id\u002Fsmall_blue_icon\"\n        style=\"@style\u002FMaterialAnimations.Icon.Small\"\n        android:src=\"@drawable\u002Fcircle\"\n        android:transitionName=\"@string\u002Fblue_name\" \u002F>\n```\n\n> layout\u002Ffragment_b.xml\n\n```xml\n\u003CImageView\n        android:id=\"@+id\u002Fbig_blue_icon\"\n        style=\"@style\u002FMaterialAnimations.Icon.Big\"\n        android:src=\"@drawable\u002Fcircle\"\n        android:transitionName=\"@string\u002Fblue_name\" \u002F>\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\u002F\u002F Defines enter transition for all fragment views\nSlide slideTransition = new Slide(Gravity.RIGHT);\nslideTransition.setDuration(1000);\nsharedElementFragment2.setEnterTransition(slideTransition);\n\n\u002F\u002F 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:\u002F\u002Fdeveloper.android.com\u002Fintl\u002Fko\u002Freference\u002Fandroid\u002Fapp\u002FFragment.html#getAllowEnterTransitionOverlap()):\n> When **true**, the enter transition will start as soon as possible. \n> \n> 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\u002F\u002F Defines enter transition for all fragment views\nSlide slideTransition = new Slide(Gravity.RIGHT);\nslideTransition.setDuration(1000);\nsharedElementFragment2.setEnterTransition(slideTransition);\n\n\u002F\u002F Defines enter transition only for shared element\nChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);\nfragmentB.setSharedElementEnterTransition(changeBoundsTransition);\n\n\u002F\u002F 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> 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> Reveal Toolbar\n\n```java\nprivate void animateRevealShow(View viewRoot) {\n    int cx = (viewRoot.getLeft() + viewRoot.getRight()) \u002F 2;\n    int cy = (viewRoot.getTop() + viewRoot.getBottom()) \u002F 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> 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()) \u002F 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()) \u002F 2;\nint cy = (viewRoot.getTop() + viewRoot.getBottom()) \u002F 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:\u002F\u002Fgithub.com\u002Flgvalle\u002FMaterial-Animations](https:\u002F\u002Fgithub.com\u002Flgvalle\u002FMaterial-Animations\u002F)**\n\n\n# More information\n\n  * Alex Lockwood posts about Transition Framework. A great in deep into this topic: [http:\u002F\u002Fwww.androiddesignpatterns.com\u002F2014\u002F12\u002Factivity-fragment-transitions-in-android-lollipop-part1.html](http:\u002F\u002Fwww.androiddesignpatterns.com\u002F2014\u002F12\u002Factivity-fragment-transitions-in-android-lollipop-part1.html)\n  * Amazing repository with lot of Material Design samples by Saul Molinero: [https:\u002F\u002Fgithub.com\u002Fsaulmm\u002FAndroid-Material-Examples](https:\u002F\u002Fgithub.com\u002Fsaulmm\u002FAndroid-Material-Examples)\n  * Chet Hasse video explaining Transition framework: [https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=S3H7nJ4QaD8](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=S3H7nJ4QaD8)\n\n\n\n[transition-framework]: https:\u002F\u002Fdeveloper.android.com\u002Ftraining\u002Ftransitions\u002Foverview.html\n\n[explode_link]: https:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Ftransition\u002FExplode.html\n[fade_link]: https:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Ftransition\u002FFade.html\n[slide_link]: https:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Ftransition\u002FSlide.html\n\n[transition_explode]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Ftransition_explode.gif\n[transition_slide]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Ftransition_slide.gif\n[transition_fade]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Ftransition_fade.gif\n[transition_fade2]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Ftransition_fade2.gif\n[transition_a_to_b]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Ftransition_A_to_B.png\n[transition_b_to_a]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Ftransition_B_to_A.png\n\n[shared_element]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fshared_element.png\n[shared_element_anim]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fshared_element_anim.gif\n[shared_element_no_overlap]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fshared_element_no_overlap.gif\n[shared_element_overlap]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fshared_element_overlap.gif\n\n[scenes_anim]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fscenes_anim.gif\n[view_layout_anim]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fview_layout_anim.gif\n\n[reveal_blue]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Freveal_blue.gif\n[reveal_red]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Freveal_red.gif\n[reveal_green]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Freveal_green.gif\n[reveal_yellow]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Freveal_yellow.gif\n[reveal_shared_anim]: https:\u002F\u002Fraw.githubusercontent.com\u002Flgvalle\u002FMaterial-Animations\u002Fmaster\u002Fscreenshots\u002Fshared_reveal_anim.gif\n","Material-Animations 是一个专注于 Android 转场动画的示例项目。它详细解释了如何使用 Android Transition Framework 实现三种主要类型的动画：活动间布局内容的动画、共享元素（英雄视图）在活动间的过渡以及同一活动内视图变化的动画。项目提供了 Explode、Slide 和 Fade 三种预定义转场效果的具体实现方式，既可以通过 XML 声明式定义也可以通过 Java 代码编程式设置。尽管该项目已不再维护，但其内容仍可作为理解和应用 Android 动画的良好参考。适合于希望提升应用程序用户体验或对 Android 动画机制感兴趣的开发者学习和实践。",2,"2026-06-11 02:58:00","top_language"]