mirror of
https://github.com/material-components/material-components-android.git
synced 2026-02-20 08:39:55 +08:00
[Motion] Update Motion.md docs and guide for 1.2.0-beta01
PiperOrigin-RevId: 313789334
This commit is contained in:
parent
61d2be7c00
commit
c596a77a31
@ -3,7 +3,7 @@ title: "Motion"
|
||||
layout: detail
|
||||
section: theming
|
||||
excerpt: "Transition between UI elements to help users understand and navigate an app."
|
||||
latest_update: "February 11, 2020"
|
||||
latest_update: "May 29, 2020"
|
||||
path: /theming/motion/
|
||||
-->
|
||||
|
||||
@ -13,16 +13,20 @@ Material motion is a set of transition patterns that help users understand and n
|
||||
an app.
|
||||
|
||||
Before you can use the motion library, you need to add a dependency on the
|
||||
Material Components for Android library. For more information, go to the
|
||||
Material Components for Android library (version 1.2.0-beta01 or later). For
|
||||
more information, go to the
|
||||
[Getting started](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md)
|
||||
page.
|
||||
|
||||
_**Note:** Motion is only available on API level 21 (Android 5.0 Lollipop) and
|
||||
up. Additionally, the transitions included in the motion library are built using the
|
||||
Android Framework Transition library (`android.transition`), **not** the
|
||||
AndroidX Transition library (`androidx.transition`). Make sure any `Transition`
|
||||
being used in conjunction with the transitions provided extends
|
||||
`android.transition.*` and not `androidx.transition.*`._
|
||||
_**Note:** Motion for Android includes two packages -
|
||||
`com.google.android.material.transition` and
|
||||
`com.google.android.material.transition.platform`. The `transition` package is
|
||||
built using the AndroidX Transition library (`androidx.transition`), is
|
||||
available down to API level 14, and is the prefered way of implementing motion.
|
||||
The `transition.platform` package contains the same set of transitions, built
|
||||
with the Android Framework Transition library (`android.transition`). The
|
||||
`transition.platform` package is available down to API level 21 (Android 5.0
|
||||
Lollipop) and should only be used for Activity or Window transitions._
|
||||
|
||||
Material Components for Android provides support for all four motion patterns
|
||||
defined in the Material spec.
|
||||
@ -36,7 +40,9 @@ defined in the Material spec.
|
||||
|
||||
## Container transform
|
||||
|
||||
The **container transform** pattern is designed for transitions between UI elements that include a container. This pattern creates a visible connection between two UI elements.
|
||||
The **container transform** pattern is designed for transitions between UI
|
||||
elements that include a container. This pattern creates a visible connection
|
||||
between two UI elements.
|
||||
|
||||
`MaterialContainerTransform` is a
|
||||
[shared element transition](https://developer.android.com/training/transitions/start-activity#start-with-element).
|
||||
@ -66,7 +72,9 @@ Android structures including Fragments, Activities and Views.
|
||||
|
||||
#### Transition between Fragments
|
||||
|
||||
In Fragment A and Fragment B's layouts, identify the start and end Views (as described in the [container transform overview](#material-container-transform)) which will be shared. Add a matching `transitionName` to each of these Views.
|
||||
In Fragment A and Fragment B's layouts, identify the start and end Views (as
|
||||
described in the [container transform overview](#material-container-transform))
|
||||
which will be shared. Add a matching `transitionName` to each of these Views.
|
||||
|
||||
```xml
|
||||
<!--fragment_a.xml-->
|
||||
@ -87,12 +95,14 @@ could be mapped to an end View in your end layout (e.g. each `RecyclerView` item
|
||||
to a details screen), read about shared element mapping at
|
||||
[Continuous Shared Element Transitions: RecyclerView to ViewPager](https://android-developers.googleblog.com/2018/02/continuous-shared-element-transitions.html)._
|
||||
|
||||
Set Fragment B's `sharedElementEnterTransition` to a new `MaterialContainerTransform`. This can be done either before adding/replacing Fragment B into your Fragment container or in Fragment B's `onCreate` method.
|
||||
Set Fragment B's `sharedElementEnterTransition` to a new
|
||||
`MaterialContainerTransform`. This can be done either before adding/replacing
|
||||
Fragment B into your Fragment container or in Fragment B's `onCreate` method.
|
||||
|
||||
```kt
|
||||
// FragmentA.kt
|
||||
val fragmentB = FragmentB()
|
||||
fragmentB.sharedElementEnterTransition = MaterialContainerTransform(requireContext())
|
||||
fragmentB.sharedElementEnterTransition = MaterialContainerTransform()
|
||||
|
||||
|
||||
/*** OR ***/
|
||||
@ -101,7 +111,7 @@ fragmentB.sharedElementEnterTransition = MaterialContainerTransform(requireConte
|
||||
// FragmentB.kt
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform(requireContext())
|
||||
sharedElementEnterTransition = MaterialContainerTransform()
|
||||
}
|
||||
```
|
||||
|
||||
@ -125,11 +135,22 @@ val extras = FragmentNavigatorExtras(view to "shared_element_container")
|
||||
findNavController().navigate(R.id.action_fragmentA_to_fragmentB, null, null, extras)
|
||||
```
|
||||
|
||||
Completing these steps should give you a working enter and return container transform when navigating from Fragment A to Fragment B and popping from Fragment B to Fragment A.
|
||||
Completing these steps should give you a working enter and return container
|
||||
transform when navigating from Fragment A to Fragment B and popping from
|
||||
Fragment B to Fragment A.
|
||||
|
||||
_**Note:** Fragments are able to define enter and return shared element transitions. When only an enter shared element transition is set, it will be re-used when the Fragment is popped (returns). `MaterialContainerTransform` internally configures the transition’s properties based on whether or not it’s entering or returning. If you need to customize either the enter or return style of the transition, see [Customizing the container transform](#customization)._
|
||||
_**Note:** Fragments are able to define enter and return shared element
|
||||
transitions. When only an enter shared element transition is set, it will be
|
||||
re-used when the Fragment is popped (returns). `MaterialContainerTransform`
|
||||
internally configures the transition’s properties based on whether or not it’s
|
||||
entering or returning. If you need to customize either the enter or return style
|
||||
of the transition, see [Customizing the container transform](#customization)._
|
||||
|
||||
When running this new transition, you might notice that Fragment A (everything besides the shared element) disappears as soon as the container transform starts. This is because FragmentA has been removed from its container. To “hold” FragmentA in place as the container transform plays, set the provided `Hold` transition as FragmentA’s exit transition.
|
||||
When running this new transition, you might notice that Fragment A (everything
|
||||
besides the shared element) disappears as soon as the container transform
|
||||
starts. This is because FragmentA has been removed from its container. To “hold”
|
||||
FragmentA in place as the container transform plays, set FragmentA's exit
|
||||
transition to the the provided `Hold` transition.
|
||||
|
||||
```kt
|
||||
// FragmentA.kt
|
||||
@ -145,7 +166,14 @@ fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
#### Transition between Activities
|
||||
|
||||
In Activity A’s layout, identify the start View to be used as the “shared element” as described in the [container transform overview](#material-container-transform). Give the start view a `transitionName`.
|
||||
_**Note:** Activity and Window transitions require using Android Framework
|
||||
Transitions provided in the `com.google.android.material.transition.platform`
|
||||
package and are only available on API level 21 and above._
|
||||
|
||||
In Activity A’s layout, identify the start View to be used as the “shared
|
||||
element” as described in the
|
||||
[container transform overview](#material-container-transform). Give the start
|
||||
view a `transitionName`.
|
||||
|
||||
```xml
|
||||
<!--activity_a.xml-->
|
||||
@ -193,13 +221,13 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
|
||||
|
||||
// Set this Activity’s enter and return transition to a MaterialContainerTransform
|
||||
window.sharedElementEnterTransition = MaterialContainerTransform(this).apply {
|
||||
window.sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
addTarget(android.R.id.content)
|
||||
duration = 300L
|
||||
}
|
||||
window.sharedElementReturnTransition = MaterialContainerTransform(this).apply {
|
||||
window.sharedElementReturnTransition = MaterialContainerTransform().apply {
|
||||
addTarget(android.R.id.content)
|
||||
duration = 300L
|
||||
duration = 250L
|
||||
}
|
||||
|
||||
super.onCreate(bundle)
|
||||
@ -208,9 +236,16 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
}
|
||||
```
|
||||
|
||||
_**Note:** We are using `android.R.id.content` (the window’s root) as the shared element “container” in Activity B. This will cause the start view being transformed from Activity A to transition into the full screen of Activity B. If you have views in Activity A and Activity B that you do not want included as part of the transform, you can alternatively set the transition name on a `View`/`ViewGroup` in Activity B’s layout or include/exclude `View`s with helper methods on the Transition class (`Transition#addTarget`, `Transition#excludeChildren`, etc)._
|
||||
_**Note:** We are using `android.R.id.content` (the window’s root) as the shared
|
||||
element “container” in Activity B. This will cause the start view from Activity
|
||||
A to transition into the full screen of Activity B. If you have views in
|
||||
Activity A and Activity B that you do not want included as part of the
|
||||
transform, you can alternatively set the transition name on a `View`/`ViewGroup`
|
||||
in Activity B’s layout or include/exclude `View`s with helper methods on the
|
||||
Transition class (`Transition#addTarget`, `Transition#excludeChildren`, etc)._
|
||||
|
||||
From Activity A, start the container transform by constructing an Intent with the following options.
|
||||
From Activity A, start the container transform by constructing an Intent with
|
||||
the following options.
|
||||
|
||||
```kt
|
||||
val intent = Intent(this, ActivityB::class.java)
|
||||
@ -225,10 +260,12 @@ startActivity(intent, options.toBundle())
|
||||
|
||||
#### Transition between Views
|
||||
|
||||
In the Activity or Fragment where you are transitioning between two views, trigger a `MaterialContainerTransform` by manually setting the transition’s start and end `View`s.
|
||||
In the Activity or Fragment where you are transitioning between two views,
|
||||
trigger a `MaterialContainerTransform` by manually setting the transition’s
|
||||
start and end `View`s.
|
||||
|
||||
```kt
|
||||
val transform = MaterialContainerTransform(this).apply {
|
||||
val transform = MaterialContainerTransform().apply {
|
||||
// Manually tell the container transform which Views to transform between.
|
||||
startView = fab
|
||||
endView = bottomToolbar
|
||||
@ -248,13 +285,18 @@ fab.visibility = View.GONE
|
||||
bottomToolbar.visibility = View.VISIBLE
|
||||
```
|
||||
|
||||
This will perform a container transform from the start view transitioning to the end view. To return, set up the same transform, switching the start and end Views and undoing any property changes (setting the FAB back to `View.VISIBLE` and the `bottomToolbar` back to `View.GONE`) done by the first transform.
|
||||
This will perform a container transform from the start view transitioning to the
|
||||
end view. To return, set up the same transform, switching the start and end
|
||||
Views and undoing any property changes (setting the FAB back to `View.VISIBLE`
|
||||
and the `bottomToolbar` back to `View.GONE`) done by the first transform.
|
||||
|
||||
### Customization
|
||||
|
||||
While the out-of-the-box container transform should work in most cases, you can manually set the following properties on `MaterialContainerTransform` to customize the look and feel of the animation:
|
||||
While the out-of-the-box container transform should work in most cases, you can
|
||||
manually set the following properties on `MaterialContainerTransform` to
|
||||
customize the look and feel of the animation:
|
||||
|
||||
#### Container transform attributes<
|
||||
#### Container transform attributes
|
||||
|
||||
<!-- Todo: Update this table with links to source where listing defaults is too lengthy (thresholds) -->
|
||||
|
||||
@ -264,28 +306,35 @@ While the out-of-the-box container transform should work in most cases, you can
|
||||
|
||||
#### Container transform properties
|
||||
|
||||
| Related method(s) | Default value
|
||||
-------------- | --------------------------------- | -------------
|
||||
**Duration** | `getDuration`<br/>`setDuration` | `300`
|
||||
**Interpolation** | `getInterpolation`<br/>`setInterpolation` | `R.interpolator.fast_out_slow_in`
|
||||
**Path Motion** | `getPathMotion`<br/>`setPathMotion` | `null` (Linear)
|
||||
**Z Order** | `getDrawingViewId`<br/>`setDrawingViewId` | `android.R.id.content`
|
||||
**Container Background Color** | `getContainerColor`<br/>`setContainerColor` | `Color.TRANSPARENT`
|
||||
**Scrim Color** | `getScrimColor`<br/>`setScrimColor` | `R.attr.scrimBackground`
|
||||
**Direction** | `getTransitionDirection`<br/>`setTransitionDirection` | `TransitionDirection.TRANSITION_DIRECTION_AUTO`
|
||||
**Fade Mode** | `getFadeMode`<br/>`setFadeMode` | `FadeMode.FADE_MODE_IN`
|
||||
**Fit Mode** | `getFitMode`<br/>`setFitMode` | `FitMode.FIT_MODE_AUTO`
|
||||
**Fade Thresholds** | `getFadeProgressThresholds`<br/>`setFadeProgressThresholds` |
|
||||
**Scale Thresholds** | `getScaleProgressThresholds`<br/>`setScaleProgressThresholds` |
|
||||
**Scale Mask Thresholds** | `getScaleMaskProgressThresholds`<br/>`setScaleMaskProgressThresholds` |
|
||||
**Shape Mask Thresholds** | `getShapeMaskProgressThresholds`<br/>`setShapeMaskProgressThresholds` |
|
||||
**Debug Drawing** | `isDrawDebugEnabled()`<br/>`setDrawDebugEnabled()` | `false`
|
||||
| Related method(s) | Default value
|
||||
----------------------------------------- | --------------------------------------------------------------------- | -------------
|
||||
**Duration** | `getDuration`<br/>`setDuration` | `300`
|
||||
**Interpolation** | `getInterpolation`<br/>`setInterpolation` | `R.interpolator.fast_out_slow_in`
|
||||
**Path Motion** | `getPathMotion`<br/>`setPathMotion` | `null` (Linear)
|
||||
**Z Order** | `getDrawingViewId`<br/>`setDrawingViewId` | `android.R.id.content`
|
||||
**Container Background Color** | `getContainerColor`<br/>`setContainerColor` | `Color.TRANSPARENT`
|
||||
**Container Start View Background Color** | `getStartContainerColor`<br/>`setStartContainerColor` | `Color.TRANSPARENT`
|
||||
**Container End View Background Color** | `getEndContainerColor`<br/>`setEndContainerColor` | `Color.TRANSPARENT`
|
||||
**Scrim Color** | `getScrimColor`<br/>`setScrimColor` | `#52000000` (32% opacity, black)
|
||||
**Direction** | `getTransitionDirection`<br/>`setTransitionDirection` | `TransitionDirection.TRANSITION_DIRECTION_AUTO`
|
||||
**Fade Mode** | `getFadeMode`<br/>`setFadeMode` | `FadeMode.FADE_MODE_IN`
|
||||
**Fit Mode** | `getFitMode`<br/>`setFitMode` | `FitMode.FIT_MODE_AUTO`
|
||||
**Fade Thresholds** | `getFadeProgressThresholds`<br/>`setFadeProgressThresholds` | `[0.0 - 0.25] enter`<br/>`[0.6 - 0.9] return`<br/>`[0.1 - 0.4] enter w. arc`<br/>`[0.6 - 0.9] return w. arc`
|
||||
**Scale Thresholds** | `getScaleProgressThresholds`<br/>`setScaleProgressThresholds` | `[0.0 - 1.0] enter`<br/>`[0.0 - 1.0] return`<br/>`[0.1 - 1.0] enter w. arc`<br/>`[0.0 - 0.9] return w. arc`
|
||||
**Scale Mask Thresholds** | `getScaleMaskProgressThresholds`<br/>`setScaleMaskProgressThresholds` | `[0.0 - 1.0] enter`<br/>`[0.0 - 0.9] return`<br/>`[0.1 - 1.0] enter w. arc`<br/>`[0.0 - 0.9] return w. arc`
|
||||
**Shape Mask Thresholds** | `getShapeMaskProgressThresholds`<br/>`setShapeMaskProgressThresholds` | `[0.0 - 0.75] enter`<br/>`[0.3 - 0.9] return`<br/>`[0.1 - 0.9] enter w. arc`<br/>`[0.2 - 0.9] return w. arc`
|
||||
**Debug Drawing** | `isDrawDebugEnabled()`<br/>`setDrawDebugEnabled()` | `false`
|
||||
|
||||
_**Note:** All of these properties have defaults. In most cases, each property
|
||||
has a different default value depending on whether or not the transition is
|
||||
entering or returning._
|
||||
|
||||
_When you manually set any of the above properties, the value set will be used when the transition is both entering and returning (including when an enter transition is being re-used due to no return being set). If you need to manually set properties which differ depending on whether or not the transition is entering or returning, create two `MaterialContainerTransforms` and set both the `sharedElementEnterTransition` and `sharedElementReturnTransition`._
|
||||
_When you manually set any of the above properties, the value set will be used
|
||||
when the transition is both entering and returning (including when an enter
|
||||
transition is being re-used due to no return being set). If you need to manually
|
||||
set properties which differ depending on whether or not the transition is
|
||||
entering or returning, create two `MaterialContainerTransforms` and set both the
|
||||
`sharedElementEnterTransition` and `sharedElementReturnTransition`._
|
||||
|
||||
<br><br>
|
||||
|
||||
@ -305,14 +354,12 @@ _Examples of the shared axis pattern:_
|
||||
|
||||
### Using the shared axis pattern
|
||||
|
||||
`MaterialSharedAxis` is a `Visibility` transition. A `Visibility` transition is
|
||||
triggered when the target `View`'s visibility is changed or when the `View` is
|
||||
added or removed. This means `MaterialSharedAxis` requires a View to be changing
|
||||
in visibility or to be added or removed to trigger its animation.
|
||||
|
||||
`MaterialSharedAxis` is a `TransitionSet` composed of smaller, “atomic”,
|
||||
transitions. By default, these atomic transitions extend `Visibility`, a
|
||||
`Transition` which triggers when the target View's visibility is changed or when
|
||||
the View is added or removed. This means `MaterialSharedAxis` requires a View to
|
||||
be changing in visibility or to be added or removed to trigger its animation.
|
||||
|
||||
`MaterialSharedAxis` has the concept of moving in the forward or backward
|
||||
`MaterialSharedAxis` uses the concept of moving in the forward or backward
|
||||
direction. Below are the directions in which a `MaterialSharedAxis` will move
|
||||
for both the forward and backward directions along each axis.
|
||||
|
||||
@ -324,6 +371,13 @@ Axis | Forward | Backward
|
||||
**Y** | Up on y-axis | Down on y-axis
|
||||
**Z** | Forward on z-axis | Backward on z-axis
|
||||
|
||||
_**Note:** Since a shared axis' direction is independent of whether its target
|
||||
is appearing or dissapearing (an appearing target will sometimes be moving
|
||||
forward when entering **and** forward when exiting), `MaterialSharedAxis` is not
|
||||
able to automatically reverse when only a target's enter transition is set. For
|
||||
this reason, you should manually configure and set a target's transitions (enter
|
||||
,exit, return, reenter) with the correct direction._
|
||||
|
||||
A shared axis transition can be configured to transition between a number of
|
||||
Android structures including Fragments, Activities and Views.
|
||||
|
||||
@ -344,10 +398,10 @@ In Fragment A, configure an enter and exit transition.
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val backward = MaterialSharedAxis.create(requireContext(), MaterialSharedAxis.Z, false)
|
||||
val backward = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
reenterTransition = backward
|
||||
|
||||
val forward = MaterialSharedAxis.create(requireContext(), MaterialSharedAxis.Z, true)
|
||||
val forward = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
exitTransition = forward
|
||||
}
|
||||
```
|
||||
@ -360,10 +414,10 @@ In Fragment B, again configure an enter and exit transition.
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val forward = MaterialSharedAxis.create(requireContext(), MaterialSharedAxis.Z, true)
|
||||
val forward = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
enterTransition = forward
|
||||
|
||||
val backward = MaterialSharedAxis.create(requireContext(), MaterialSharedAxis.Z, false)
|
||||
val backward = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
returnTransition = backward
|
||||
}
|
||||
```
|
||||
@ -372,7 +426,7 @@ It’s important to note here how these two fragments move together. When Fragme
|
||||
A is exiting, Fragment B will be entering. This is why, in Fragment A, the exit
|
||||
transition is `forward` and in Fragment B the enter transition is also
|
||||
`forward`. This will ensure that both Fragments are moving in the same direction
|
||||
when their transitions are playing. The opposite is true in the backwards
|
||||
when these transition pairs are running. The opposite is true in the backwards
|
||||
direction. When Fragment B is exiting, Fragment A will be entering. For this
|
||||
reason, Fragment B is configured to exit in the backward direction and Fragment
|
||||
A is configured to enter in the backward direction.
|
||||
@ -396,6 +450,10 @@ _not_ spatially related.
|
||||
|
||||
#### Transition between Activities
|
||||
|
||||
_**Note:** Activity and Window transitions require using Android Framework
|
||||
Transitions provided in the `com.google.android.material.transition.platform`
|
||||
package and are only available on API level 21 and above._
|
||||
|
||||
Enable Activity transitions by either setting
|
||||
`android:windowActivityTransitions` to true in your theme or enabling them on an
|
||||
Activity by Activity basis by setting the `Window.FEATURE_ACTIVITY_TRANSITIONS`
|
||||
@ -424,7 +482,7 @@ as the Activity's `exitTransition`.
|
||||
// ActivityA.kt
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val exit = MaterialSharedAxis.create(this, MaterialSharedAxis.X, true).apply {
|
||||
val exit = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
|
||||
|
||||
// Only run the transition on the contents of this activity, excluding
|
||||
// system bars or app bars if provided by the app’s theme.
|
||||
@ -445,7 +503,7 @@ ignore Views. Use the combination you need to have the transition applied where
|
||||
desired. For example:
|
||||
|
||||
```kt
|
||||
val exit = MaterialSharedAxis.create(this, MaterialSharedAxis.X, true).apply {
|
||||
val exit = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
|
||||
|
||||
// Only run the transition on the root ViewGroup of this activity. This will exclude
|
||||
// other views except what is specified by this method.
|
||||
@ -469,7 +527,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
|
||||
|
||||
val enter = MaterialSharedAxis.create(this, MaterialSharedAxis.X, true).apply {
|
||||
val enter = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
|
||||
addTarget(R.id.b_container)
|
||||
}
|
||||
window.enterTransition = enter
|
||||
@ -501,8 +559,8 @@ should not yet be added to the layout. When you’re ready to replace the outgoi
|
||||
view with the incoming View, do so with a shared axis transition as follows.
|
||||
|
||||
```kt
|
||||
// Set up a new MaterialSharedAxis in the specified ais and direction.
|
||||
val sharedAxis = MaterialSharedAxis.create(requireContext(), MaterialSharedAxis.Y, true)
|
||||
// Set up a new MaterialSharedAxis in the specified axis and direction.
|
||||
val sharedAxis = MaterialSharedAxis(MaterialSharedAxis.Y, true)
|
||||
|
||||
// Begin watching for changes in the View hierarchy.
|
||||
TransitionManager.beginDelayedTransition(container, sharedAxis)
|
||||
@ -519,11 +577,15 @@ View back to `View.GONE`.
|
||||
|
||||
### Customization
|
||||
|
||||
`MaterialSharedAxis` is an extension of `MaterialTransitionSet`. A
|
||||
`MaterialTransitionSet` is composed of a primary and secondary Transition. For
|
||||
any `MaterialTransitionSet`, the secondary transition can either be modified or
|
||||
replaced using `MaterialTransitionSet.getSecondaryTransition` and
|
||||
`MaterialTransitionSet.setSecondaryTransition`.
|
||||
`MaterialSharedAxis` is an extension of `MaterialVisibility`.
|
||||
`MaterialVisibility` is a `Visibility` transition composed of smaller, "atomic"
|
||||
`VisibilityAnimatorProvider`s. These providers are classes which can be
|
||||
configured and are able to construct an animator depending on whether a target
|
||||
is appearing or disappearing. By default, a `MaterialVisibility` implementation
|
||||
has a primary and secondary `VisibilityAnimatorProvider`. The primary provider
|
||||
can be modified while the secondary provider can be either modified, replaced or
|
||||
removed. This allows for the customization of Material motion while still
|
||||
adhering to a pattern's foundation and is refered to as a _variant_.
|
||||
|
||||
#### Shared axis composition
|
||||
|
||||
@ -532,26 +594,22 @@ replaced using `MaterialTransitionSet.getSecondaryTransition` and
|
||||
| **MaterialSharedAxis** | **X** -`SlideDistance`<br> **Y** -`SlideDistance`<br> **Z** -`Scale` | `FadeThrough` |
|
||||
|
||||
|
||||
|
||||
This allows the tweaking of shared axis to create “variants” as mentioned in the
|
||||
Material Motion spec. <!-- Todo: Add Link to spec article -->
|
||||
|
||||
#### Shared axis fade variant
|
||||
|
||||
The following is a `MaterialSharedAxis` Z transition between Activities which fades
|
||||
Activity B in and over Activity A while leaving Activity A’s alpha unchanged can
|
||||
be accomplished by removing the secondary `FadeThrough` transition from Activity
|
||||
A's exit transition.
|
||||
The following is a `MaterialSharedAxis` Z transition between Activities which
|
||||
fades Activity B in and over Activity A while leaving Activity A’s alpha
|
||||
unchanged. This can be accomplished by removing the secondary
|
||||
`FadeThroughProvider` from Activity A's exit transition.
|
||||
|
||||
```kt
|
||||
// ActivityA.kt
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val exit = MaterialSharedAxis.create(this, MaterialSharedAxis.Z, true).apply {
|
||||
// Remove the exit transitions secondary transition completely so this Activity
|
||||
val exit = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
|
||||
// Remove the exit transitions secondary animator provider completely so this Activity
|
||||
// only scales instead of scaling and fading out. Alternatively, this could be
|
||||
// set to a modified FadeThrough transition or any other custom transition.
|
||||
secondaryTransition = null
|
||||
// set to a modified FadeThroughProvider or any other VisibilityAnimatorProvider.
|
||||
secondaryAnimatorProvider = null
|
||||
|
||||
addTarget(R.id.main_container)
|
||||
}
|
||||
@ -581,11 +639,10 @@ _Examples of the fade through pattern:_
|
||||
|
||||
### Using the fade through pattern
|
||||
|
||||
`MaterialFadeThrough` is a `TransitionSet` composed of smaller, “atomic”,
|
||||
transitions. By default, these atomic transitions extend `Visibility`, a
|
||||
`Transition` which triggers when the target View's visibility is changed or when
|
||||
the View is added or removed. This means `MaterialFadeThrough` requires a View
|
||||
to be changing in visibility or to be added or removed to trigger its animation.
|
||||
`MaterialFadeThrough` is a `Visibility` transition. A `Visibility` transition is
|
||||
triggered when the target `View`'s visibility is changed or when the `View` is
|
||||
added or removed. This means `MaterialFadeThrough` requires a View to be
|
||||
changing in visibility or to be added or removed to trigger its animation.
|
||||
|
||||
A fade through can be configured to transition between a number of Android
|
||||
structures including Fragments, Activities and Views.
|
||||
@ -605,7 +662,7 @@ Fragment B to Fragment A.
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
exitTransition = MaterialFadeThrough.create(requireContext())
|
||||
exitTransition = MaterialFadeThrough()
|
||||
}
|
||||
```
|
||||
|
||||
@ -615,13 +672,13 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
enterTransition = MaterialFadeThrough.create(requireContext())
|
||||
enterTransition = MaterialFadeThrough()
|
||||
}
|
||||
```
|
||||
|
||||
_**Note:** Since `MaterialFadeThrough`'s primary and secondary transitions both
|
||||
extend `Visibility`, `MaterialFadeThrough` appropriately animates its targets
|
||||
depending on whether they are appearing or disappearing._
|
||||
_**Note:** Since `MaterialFadeThrough` extends `Visibility`,
|
||||
`MaterialFadeThrough` is able to appropriately animate targets depending on
|
||||
whether they are apperaing or disappearing._
|
||||
|
||||
When you're ready to navigate between Fragment A and Fragment B, use a standard
|
||||
Fragment transaction or use the
|
||||
@ -636,6 +693,10 @@ supportFragmentManager
|
||||
|
||||
#### Transition between Activities
|
||||
|
||||
_**Note:** Activity and Window transitions require using Android Framework
|
||||
Transitions provided in the `com.google.android.material.transition.platform`
|
||||
package and are only available on API level 21 and above._
|
||||
|
||||
Enable Activity transitions by either setting
|
||||
`android:windowActivityTransitions` to true in your theme or enabling them on an
|
||||
Activity-by-Activity basis by setting the `Window.FEATURE_ACTIVITY_TRANSITIONS`
|
||||
@ -665,7 +726,7 @@ as the Activity's exitTransition.
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
val exit = MaterialFadeThrough.create(this).apply {
|
||||
val exit = MaterialFadeThrough().apply {
|
||||
|
||||
// Only run the transition on the contents of this activity, excluding
|
||||
// system bars or app bars if provided by the app’s theme.
|
||||
@ -683,7 +744,7 @@ ignore Views. Use the combination you need to have the transition applied where
|
||||
you’d like. For example:
|
||||
|
||||
```kt
|
||||
val exit = MaterialFadeThrough.create(this).apply {
|
||||
val exit = MaterialFadeThrough().apply {
|
||||
|
||||
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
|
||||
|
||||
@ -709,7 +770,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
|
||||
|
||||
val enter = MaterialFadeThrough.create(this).apply {
|
||||
val enter = MaterialFadeThrough().apply {
|
||||
addTarget(R.id.b_container)
|
||||
}
|
||||
window.enterTransition = enter
|
||||
@ -740,7 +801,7 @@ layout. When you’re ready to replace the outgoing View with the incoming View,
|
||||
do so with a fade through transition as follows.
|
||||
|
||||
```kt
|
||||
val fadeThrough = MaterialFadeThrough.create(requireContext())
|
||||
val fadeThrough = MaterialFadeThrough()
|
||||
|
||||
// Begin watching for changes in the View hierarchy.
|
||||
TransitionManager.beginDelayedTransition(container, fadeThrough)
|
||||
@ -757,11 +818,15 @@ your outgoing View back to `View.VISIBLE` and your incoming View back to
|
||||
|
||||
### Customization
|
||||
|
||||
`MaterialFadeThrough` is an extension of `MaterialTransitionSet`. A
|
||||
`MaterialTransitionSet` is composed of a primary and secondary `Transition`. For
|
||||
any `MaterialTransitionSet`, the secondary transition can either be modified or
|
||||
replaced using `MaterialTransitionSet.getSecondaryTransition` and
|
||||
`MaterialTransitionSet.setSecondaryTransition`.
|
||||
`MaterialFadeThrough` is an extension of `MaterialVisibility`.
|
||||
`MaterialVisibility` is a `Visibility` transition composed of smaller, "atomic"
|
||||
`VisibilityAnimatorProvider`s. These providers are classes which can be
|
||||
configured and are able to construct an animator depending on whether a target
|
||||
is appearing or disappearing. By default, a `MaterialVisibility` implementation
|
||||
has a primary and secondary `VisibilityAnimatorProvider`. The primary provider
|
||||
can be modified while the secondary provider can be either modified, replaced or
|
||||
removed. This allows for the customization of Material motion while still
|
||||
adhering to a pattern's foundation and is refered to as a _variant_.
|
||||
|
||||
#### Fade through composition
|
||||
|
||||
@ -769,10 +834,6 @@ replaced using `MaterialTransitionSet.getSecondaryTransition` and
|
||||
----------------------- | ------------------ | --------------------
|
||||
**MaterialFadeThrough** | `FadeThrough` | `Scale`
|
||||
|
||||
|
||||
This allows the tweaking of fade through to create “variants” as mentioned in
|
||||
the Material Motion design spec. <!-- Todo: Add Link to spec article -->
|
||||
|
||||
#### Fade through slide variant
|
||||
|
||||
The below will create a fade through between Fragments which fades
|
||||
@ -784,9 +845,9 @@ of a scale.
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
exitTransition = MaterialFadeThrough.create(requireContext()).apply {
|
||||
exitTransition = MaterialFadeThrough().apply {
|
||||
// Remove the exit fade through's secondary scale so this Fragment simply fades out.
|
||||
secondaryTransition = null
|
||||
secondaryAnimatorProvider = null
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -797,9 +858,9 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
enterTransition = MaterialFadeThrough.create(requireContext()).apply {
|
||||
// Replace the enter fade through's secondary transition to use a SlideDistance transition.
|
||||
secondaryTransition = SlideDistance(requireContext(), Gravity.BOTTOM)
|
||||
enterTransition = MaterialFadeThrough().apply {
|
||||
// Replace the enter fade through's secondary animator provider with a SlideDistanceProvider.
|
||||
secondaryAnimatorProvider = SlideDistanceProvider(Gravity.BOTTOM)
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -821,10 +882,9 @@ _Examples of the fade pattern:_
|
||||
|
||||
### Using the fade pattern
|
||||
|
||||
`MaterialFade` is a `TransitionSet` composed of smaller, “atomic”, transitions.
|
||||
By default, these atomic transitions extend `Visibility`, a `Transition` which
|
||||
triggers when the target View's visibility is changed or when the View is added
|
||||
or removed. This means `MaterialFade` requires a View to be changing in
|
||||
`MaterialFade` is a `Visibility` transition. A `Visibility` transition is
|
||||
triggered when the target `View`'s visibility is changed or when the `View` is
|
||||
added or removed. This means `MaterialFade` requires a View to be changing in
|
||||
visibility or to be added or removed to trigger its animation.
|
||||
|
||||
### Fade examples
|
||||
@ -838,37 +898,41 @@ case a Floating Action Button, using a `MaterialFade` to animate the change.
|
||||
// FragmentA.kt
|
||||
|
||||
showButton.setOnClickListener {
|
||||
val materialFade = MaterialFade.create(this)
|
||||
val materialFade = MaterialFade().apply {
|
||||
duration = 150L
|
||||
}
|
||||
TransitionManager.beginDelayedTransition(container, materialFade)
|
||||
fab.visibility = View.VISIBLE
|
||||
}
|
||||
```
|
||||
|
||||
_**Note:** `MaterialFade` optionally takes an `entering` parameter in its
|
||||
`create` constructor. This controls the duration used by `MaterialFade`'s
|
||||
primary `Fade` transition - using a longer duration when true and a shorter
|
||||
duration when false. By default, `MaterialFade` is configured to "enter". If
|
||||
your target View is disappearing, construct a `MaterialFade` and set the
|
||||
entering parameter to `false`._
|
||||
When reversing the transition, configure and trigger a `MaterialFade` in the
|
||||
same manner, making any adjustments to the transition that differ when entering
|
||||
versus exiting.
|
||||
|
||||
```kt
|
||||
// FragmentA.kt
|
||||
|
||||
hideButton.setOnClickListener {
|
||||
val materialFade = MaterialFade.create(this, false)
|
||||
val materialFade = MaterialFade().apply {
|
||||
duration = 84L
|
||||
}
|
||||
TransitionManager.beginDelayedTransition(container, materialFade)
|
||||
fab.visibility = View.GONE
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Customization
|
||||
|
||||
`MaterialFade` is an extension of `MaterialTransitionSet`. A
|
||||
`MaterialTransitionSet` is composed of a primary and secondary `Transition`. For
|
||||
any `MaterialTransitionSet`, the secondary transition can either be modified or
|
||||
replaced using `MaterialTransitionSet.getSecondaryTransition` and
|
||||
`MaterialTransitionSet.setSecondaryTransition`.
|
||||
`MaterialFade` is an extension of `MaterialVisibility`. `MaterialVisibility` is
|
||||
a `Visibility` transition composed of smaller, "atomic"
|
||||
`VisibilityAnimatorProvider`s. These providers are classes which can be
|
||||
configured and are able to construct an animator depending on whether a target
|
||||
is appearing or disappearing. By default, a `MaterialVisibility` implementation
|
||||
has a primary and secondary `VisibilityAnimatorProvider`. The primary provider
|
||||
can be modified while the secondary provider can be either modified, replaced or
|
||||
removed. This allows for the customization of Material motion while still
|
||||
adhering to a pattern's foundation and is refered to as a _variant_.
|
||||
|
||||
#### Fade composition
|
||||
|
||||
@ -877,7 +941,4 @@ replaced using `MaterialTransitionSet.getSecondaryTransition` and
|
||||
**MaterialFade** | `Fade` | `Scale`
|
||||
|
||||
|
||||
This allows the tweaking of fade to create “variants” as mentioned in the
|
||||
Material Motion design spec. <!-- Todo: Add Link to spec article -->
|
||||
|
||||
<!-- Todo: Add snippet of variant -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user