Add a demo of custom Transition
CustomUsage demonstrates how to create and use a custom Transition with
the support library.
This also fixes the Transition API and aligns it to the platform
version.
Change-Id: Idf3edf1438faa06c4d047d2522ad1f8e0c8561e6
diff --git a/samples/SupportTransitionDemos/AndroidManifest.xml b/samples/SupportTransitionDemos/AndroidManifest.xml
index 2d6469c..479b0a5 100644
--- a/samples/SupportTransitionDemos/AndroidManifest.xml
+++ b/samples/SupportTransitionDemos/AndroidManifest.xml
@@ -45,5 +45,14 @@
<category android:name="com.example.android.support.transition.SAMPLE_CODE" />
</intent-filter>
</activity>
+
+ <activity android:name=".widget.CustomUsage"
+ android:label="@string/custom"
+ android:theme="@style/Theme.Transition">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.support.transition.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/samples/SupportTransitionDemos/res/layout/basic_usage.xml b/samples/SupportTransitionDemos/res/layout/basic_usage.xml
index 52a3e47..e3970cc 100644
--- a/samples/SupportTransitionDemos/res/layout/basic_usage.xml
+++ b/samples/SupportTransitionDemos/res/layout/basic_usage.xml
@@ -34,10 +34,6 @@
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_weight="1">
-
- <include layout="@layout/scene0"/>
-
- </FrameLayout>
+ android:layout_weight="1"/>
</LinearLayout>
diff --git a/samples/SupportTransitionDemos/res/layout/custom0.xml b/samples/SupportTransitionDemos/res/layout/custom0.xml
new file mode 100644
index 0000000..63b46fb
--- /dev/null
+++ b/samples/SupportTransitionDemos/res/layout/custom0.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ android:id="@+id/container"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <View
+ android:id="@+id/view_1"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#f00"/>
+
+ <View
+ android:id="@+id/view_2"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#0f0"/>
+
+ <View
+ android:id="@+id/view_3"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#00f"/>
+
+</LinearLayout>
diff --git a/samples/SupportTransitionDemos/res/layout/custom1.xml b/samples/SupportTransitionDemos/res/layout/custom1.xml
new file mode 100644
index 0000000..af4d9ed
--- /dev/null
+++ b/samples/SupportTransitionDemos/res/layout/custom1.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ android:id="@+id/container"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <View
+ android:id="@+id/view_1"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#0f0"/>
+
+ <View
+ android:id="@+id/view_2"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#00f"/>
+
+ <View
+ android:id="@+id/view_3"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#f00"/>
+
+</LinearLayout>
diff --git a/samples/SupportTransitionDemos/res/layout/custom2.xml b/samples/SupportTransitionDemos/res/layout/custom2.xml
new file mode 100644
index 0000000..d699743
--- /dev/null
+++ b/samples/SupportTransitionDemos/res/layout/custom2.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ android:id="@+id/container"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <View
+ android:id="@+id/view_1"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#00f"/>
+
+ <View
+ android:id="@+id/view_2"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#f00"/>
+
+ <View
+ android:id="@+id/view_3"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_margin="8dp"
+ android:background="#0f0"/>
+
+</LinearLayout>
diff --git a/samples/SupportTransitionDemos/res/values/strings.xml b/samples/SupportTransitionDemos/res/values/strings.xml
index 7f106f1..bc1029d 100644
--- a/samples/SupportTransitionDemos/res/values/strings.xml
+++ b/samples/SupportTransitionDemos/res/values/strings.xml
@@ -17,5 +17,6 @@
<resources>
<string name="activity_sample_code">Support Transition Demos</string>
<string name="basic">Basic</string>
+ <string name="custom">Custom</string>
<string name="toggle">Toggle</string>
</resources>
diff --git a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BasicUsage.java b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BasicUsage.java
index 709ed4c..11b460e 100644
--- a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BasicUsage.java
+++ b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BasicUsage.java
@@ -16,58 +16,28 @@
package com.example.android.support.transition.widget;
-import android.os.Bundle;
+import com.example.android.support.transition.R;
+
import android.support.transition.Scene;
import android.support.transition.TransitionManager;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.FrameLayout;
-
-import com.example.android.support.transition.R;
+import android.view.ViewGroup;
/**
* This demonstrates basic usage of the Transition API.
*/
-public class BasicUsage extends AppCompatActivity {
-
- private final Scene[] mScenes = new Scene[2];
- private int mCurrentScene;
+public class BasicUsage extends TransitionUsageBase {
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.basic_usage);
-
- // Retrieve the Toolbar from our content view, and set it as the action bar
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- FrameLayout root = (FrameLayout) findViewById(R.id.root);
- mScenes[0] = Scene.getSceneForLayout(root, R.layout.scene0, this);
- mScenes[1] = Scene.getSceneForLayout(root, R.layout.scene1, this);
+ Scene[] setUpScenes(ViewGroup root) {
+ return new Scene[]{
+ Scene.getSceneForLayout(root, R.layout.scene0, this),
+ Scene.getSceneForLayout(root, R.layout.scene1, this),
+ };
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.basic_usage, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_toggle:
- if (mCurrentScene == 0) {
- mCurrentScene = 1;
- } else {
- mCurrentScene = 0;
- }
- TransitionManager.go(mScenes[mCurrentScene]);
- return true;
- }
- return false;
+ void go(Scene scene) {
+ TransitionManager.go(scene);
}
}
diff --git a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/ChangeColor.java b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/ChangeColor.java
new file mode 100644
index 0000000..4036f13
--- /dev/null
+++ b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/ChangeColor.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.support.transition.widget;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.transition.Transition;
+import android.support.transition.TransitionValues;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A sample implementation of support {@link Transition}.
+ */
+public class ChangeColor extends Transition {
+
+ /** Key to store a color value in TransitionValues object */
+ private static final String PROPNAME_BACKGROUND = "transitiondemos:change_color:background";
+
+ /**
+ * Convenience method: Add the background Drawable property value
+ * to the TransitionsValues.value Map for a target.
+ */
+ private void captureValues(TransitionValues values) {
+ // Capture the property values of views for later use
+ values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
+ }
+
+ @Override
+ public void captureEndValues(@NonNull TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureStartValues(@NonNull TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ // Create an animation for each target that is in both the starting and ending Scene. For each
+ // pair of targets, if their background property value is a color (rather than a graphic),
+ // create a ValueAnimator based on an ArgbEvaluator that interpolates between the starting and
+ // ending color. Also create an update listener that sets the View background color for each
+ // animation frame
+ @Nullable
+ @Override
+ public Animator createAnimator(@NonNull ViewGroup sceneRoot,
+ @Nullable TransitionValues startValues,
+ @Nullable TransitionValues endValues) {
+ // This transition can only be applied to views that are on both starting and ending scenes.
+ if (null == startValues || null == endValues) {
+ return null;
+ }
+ // Store a convenient reference to the target. Both the starting and ending layout have the
+ // same target.
+ final View view = endValues.view;
+ // Store the object containing the background property for both the starting and ending
+ // layouts.
+ Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
+ Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
+ // This transition changes background colors for a target. It doesn't animate any other
+ // background changes. If the property isn't a ColorDrawable, ignore the target.
+ if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
+ ColorDrawable startColor = (ColorDrawable) startBackground;
+ ColorDrawable endColor = (ColorDrawable) endBackground;
+ // If the background color for the target in the starting and ending layouts is
+ // different, create an animation.
+ if (startColor.getColor() != endColor.getColor()) {
+ // Create a new Animator object to apply to the targets as the transitions framework
+ // changes from the starting to the ending layout. Use the class ValueAnimator,
+ // which provides a timing pulse to change property values provided to it. The
+ // animation runs on the UI thread. The Evaluator controls what type of
+ // interpolation is done. In this case, an ArgbEvaluator interpolates between two
+ // #argb values, which are specified as the 2nd and 3rd input arguments.
+ ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),
+ startColor.getColor(), endColor.getColor());
+ // Add an update listener to the Animator object.
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ Object value = animation.getAnimatedValue();
+ // Each time the ValueAnimator produces a new frame in the animation, change
+ // the background color of the target. Ensure that the value isn't null.
+ if (null != value) {
+ view.setBackgroundColor((Integer) value);
+ }
+ }
+ });
+ // Return the Animator object to the transitions framework. As the framework changes
+ // between the starting and ending layouts, it applies the animation you've created.
+ return animator;
+ }
+ }
+ // For non-ColorDrawable backgrounds, we just return null, and no animation will take place.
+ return null;
+ }
+
+}
diff --git a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/CustomUsage.java b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/CustomUsage.java
new file mode 100644
index 0000000..2bd9d27
--- /dev/null
+++ b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/CustomUsage.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.support.transition.widget;
+
+import com.example.android.support.transition.R;
+
+import android.os.Bundle;
+import android.support.transition.Scene;
+import android.support.transition.Transition;
+import android.support.transition.TransitionManager;
+import android.view.ViewGroup;
+
+/**
+ * This demonstrates usage of a custom Transition. See {@link ChangeColor} for the actual
+ * implementation of a custom Transition.
+ */
+public class CustomUsage extends TransitionUsageBase {
+
+ private Transition mTransition;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mTransition = new ChangeColor();
+ }
+
+ @Override
+ Scene[] setUpScenes(ViewGroup root) {
+ return new Scene[]{
+ Scene.getSceneForLayout(root, R.layout.custom0, this),
+ Scene.getSceneForLayout(root, R.layout.custom1, this),
+ Scene.getSceneForLayout(root, R.layout.custom2, this),
+ };
+ }
+
+ @Override
+ void go(Scene scene) {
+ TransitionManager.go(scene, mTransition);
+ }
+
+}
diff --git a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java
new file mode 100644
index 0000000..83c3a29
--- /dev/null
+++ b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.support.transition.widget;
+
+import com.example.android.support.transition.R;
+
+import android.os.Bundle;
+import android.support.transition.Scene;
+import android.support.transition.TransitionManager;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+/**
+ * Base class for usages of the Transition API.
+ */
+abstract class TransitionUsageBase extends AppCompatActivity {
+
+ protected Scene[] mScenes;
+
+ private int mCurrentScene;
+
+ abstract Scene[] setUpScenes(ViewGroup root);
+
+ abstract void go(Scene scene);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.basic_usage);
+
+ // Retrieve the Toolbar from our content view, and set it as the action bar
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ FrameLayout root = (FrameLayout) findViewById(R.id.root);
+ mScenes = setUpScenes(root);
+ TransitionManager.go(mScenes[0]);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.basic_usage, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_toggle:
+ mCurrentScene = (mCurrentScene + 1) % mScenes.length;
+ go(mScenes[mCurrentScene]);
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/transition/ics/android/support/transition/FadePort.java b/transition/ics/android/support/transition/FadePort.java
index 027a907..dad6b80 100644
--- a/transition/ics/android/support/transition/FadePort.java
+++ b/transition/ics/android/support/transition/FadePort.java
@@ -117,14 +117,7 @@
}
if (listener != null) {
anim.addListener(listener);
-// anim.addPauseListener(listener);
}
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- System.out.println("animation value now " + animation.getAnimatedValue());
- }
- });
return anim;
}
diff --git a/transition/src/android/support/transition/Transition.java b/transition/src/android/support/transition/Transition.java
index 44dd415..42e1e19 100644
--- a/transition/src/android/support/transition/Transition.java
+++ b/transition/src/android/support/transition/Transition.java
@@ -259,8 +259,10 @@
*/
@Override
@Nullable
- public abstract Animator createAnimator(@NonNull ViewGroup sceneRoot,
- @NonNull TransitionValues startValues, @NonNull TransitionValues endValues);
+ public Animator createAnimator(@NonNull ViewGroup sceneRoot,
+ @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
+ return null;
+ }
/**
* Whether to add the children of given target to the list of target children
diff --git a/transition/tests/res/layout/activity_transition.xml b/transition/tests/res/layout/activity_transition.xml
index 9ba9ddc..cfbbe61b 100644
--- a/transition/tests/res/layout/activity_transition.xml
+++ b/transition/tests/res/layout/activity_transition.xml
@@ -16,6 +16,5 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>