[go: nahoru, domu]

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"/>