* commit 'bbe0365f67d7e8146e65c6b57fee20d32f2e4089': Cross-Activity Scene transitions API demo.
@@ -1293,6 +1293,25 @@
|
|||||||
<!-- ANDROID.ANIMATION PACKAGE SAMPLES -->
|
<!-- ANDROID.ANIMATION PACKAGE SAMPLES -->
|
||||||
<!-- ************************************* -->
|
<!-- ************************************* -->
|
||||||
|
|
||||||
|
<activity android:name=".animation.ActivityTransition"
|
||||||
|
android:label="Animation/Activity Transition"
|
||||||
|
android:enabled="@bool/atLeastHoneycomb"
|
||||||
|
android:theme="@style/ActivityTransitionTheme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".animation.ActivityTransitionDetails"
|
||||||
|
android:label="Animation/Activity Transition Details"
|
||||||
|
android:enabled="@bool/atLeastHoneycomb"
|
||||||
|
android:theme="@style/ActivityTransitionTheme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".animation.AnimationLoading"
|
<activity android:name=".animation.AnimationLoading"
|
||||||
android:label="Animation/Loading"
|
android:label="Animation/Loading"
|
||||||
android:enabled="@bool/atLeastHoneycomb">
|
android:enabled="@bool/atLeastHoneycomb">
|
||||||
|
|||||||
BIN
samples/ApiDemos/res/drawable-nodpi/ball.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/block.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/ducky.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/jellies.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/mug.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/pencil.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/scissors.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
samples/ApiDemos/res/drawable-nodpi/woot.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
82
samples/ApiDemos/res/layout/image_block.xml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:columnCount="2"
|
||||||
|
android:rowCount="4"
|
||||||
|
>
|
||||||
|
<ImageView android:id="@+id/ducky"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ducky"
|
||||||
|
android:layout_column="0"
|
||||||
|
android:layout_row="0"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/woot"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/woot"
|
||||||
|
android:layout_column="1"
|
||||||
|
android:layout_row="0"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/ball"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ball"
|
||||||
|
android:layout_column="0"
|
||||||
|
android:layout_row="1"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/block"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/block"
|
||||||
|
android:layout_column="1"
|
||||||
|
android:layout_row="1"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/jellies"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/jellies"
|
||||||
|
android:layout_column="0"
|
||||||
|
android:layout_row="2"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/mug"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/mug"
|
||||||
|
android:layout_column="1"
|
||||||
|
android:layout_row="2"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/pencil"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/pencil"
|
||||||
|
android:layout_column="0"
|
||||||
|
android:layout_row="3"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
<ImageView android:id="@+id/scissors"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/scissors"
|
||||||
|
android:layout_column="1"
|
||||||
|
android:layout_row="3"
|
||||||
|
android:onClick="clicked"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
87
samples/ApiDemos/res/layout/image_details.xml
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<ImageView android:id="@+id/titleImage"
|
||||||
|
android:layout_height="0px"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:onClick="clicked"
|
||||||
|
android:sharedElementName="hero"
|
||||||
|
/>
|
||||||
|
<LinearLayout android:layout_height="0px"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Ducky"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Woot!"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Ball"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Block"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Jelly Bean"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Mug"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Pencil"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
<View android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="#808080"/>
|
||||||
|
<TextView android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="Scissors"
|
||||||
|
android:textSize="30sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
@@ -18,36 +18,40 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/container">
|
android:id="@+id/container">
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:background="#f00"
|
android:background="#f00"
|
||||||
|
android:text="Hello"
|
||||||
android:id="@+id/view1"/>
|
android:id="@+id/view1"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:background="#0f0"
|
android:background="#0f0"
|
||||||
|
android:text="World"
|
||||||
android:id="@+id/view2"/>
|
android:id="@+id/view2"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:background="#00f"
|
android:background="#00f"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
|
android:text="Foo"
|
||||||
android:id="@+id/view3"/>
|
android:id="@+id/view3"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:background="#0ff"
|
android:background="#0ff"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
|
android:text="Bar"
|
||||||
android:id="@+id/view4"/>
|
android:id="@+id/view4"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
@@ -18,36 +18,40 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/container">
|
android:id="@+id/container">
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="100dip"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:background="#f00"
|
android:background="#f00"
|
||||||
|
android:text="Hello"
|
||||||
android:id="@+id/view1"/>
|
android:id="@+id/view1"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="100dip"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:background="#0f0"
|
android:background="#0f0"
|
||||||
|
android:text="World"
|
||||||
android:id="@+id/view2"/>
|
android:id="@+id/view2"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="100dip"
|
android:layout_height="wrap_content"
|
||||||
android:background="#00f"
|
android:background="#00f"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
|
android:text="Foo"
|
||||||
android:id="@+id/view3"/>
|
android:id="@+id/view3"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="100dip"
|
android:layout_height="wrap_content"
|
||||||
android:background="#0ff"
|
android:background="#0ff"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
|
android:text="Bar"
|
||||||
android:id="@+id/view4"/>
|
android:id="@+id/view4"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
@@ -18,36 +18,40 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/container">
|
android:id="@+id/container">
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:background="#f00"
|
android:background="#f00"
|
||||||
|
android:text="Hello"
|
||||||
android:id="@+id/view1"/>
|
android:id="@+id/view1"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:background="#0f0"
|
android:background="#0f0"
|
||||||
|
android:text="World"
|
||||||
android:id="@+id/view2"/>
|
android:id="@+id/view2"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:background="#00f"
|
android:background="#00f"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
|
android:text="Foo"
|
||||||
android:id="@+id/view3"/>
|
android:id="@+id/view3"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="100dip"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dip"
|
android:layout_height="wrap_content"
|
||||||
android:background="#0ff"
|
android:background="#0ff"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
|
android:text="Bar"
|
||||||
android:id="@+id/view4"/>
|
android:id="@+id/view4"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
17
samples/ApiDemos/res/transition/activity_transition_mgr.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2013 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.
|
||||||
|
-->
|
||||||
|
<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
</transitionManager>
|
||||||
@@ -28,5 +28,6 @@
|
|||||||
<color name="solid_blue">#0000ff</color>
|
<color name="solid_blue">#0000ff</color>
|
||||||
<color name="solid_green">#f0f0</color>
|
<color name="solid_green">#f0f0</color>
|
||||||
<color name="solid_yellow">#ffffff00</color>
|
<color name="solid_yellow">#ffffff00</color>
|
||||||
|
<color name="purply">#ff884488</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -121,4 +121,13 @@
|
|||||||
<item name="android:layout_width">wrap_content</item>
|
<item name="android:layout_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="ActivityTransitionTheme" parent="android:style/Theme.Holo">
|
||||||
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
|
<!--
|
||||||
|
-->
|
||||||
|
<item name="android:windowContentTransitionManager">@transition/activity_transition_mgr</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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.apis.animation;
|
||||||
|
|
||||||
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.RectEvaluator;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityOptions;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.transition.TransitionManager;
|
||||||
|
import android.transition.TransitionSet;
|
||||||
|
import android.util.Property;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewGroupOverlay;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ActivityTransition extends Activity {
|
||||||
|
private static final String TAG = "ActivityTransition";
|
||||||
|
|
||||||
|
private static final String KEY_LEFT_ON_SCREEN = "ViewTransitionValues:left:";
|
||||||
|
private static final String KEY_TOP_ON_SCREEN = "ViewTransitionValues:top:";
|
||||||
|
private static final String KEY_WIDTH = "ViewTransitionValues:width:";
|
||||||
|
private static final String KEY_HEIGHT = "ViewTransitionValues:height:";
|
||||||
|
private static final String KEY_ID = "ViewTransitionValues:id";
|
||||||
|
|
||||||
|
private Random mRandom = new Random();
|
||||||
|
private boolean mComeBack;
|
||||||
|
private Fall mFall;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
|
||||||
|
setEarlyBackgroundTransition(false);
|
||||||
|
getWindow().setBackgroundDrawable(new ColorDrawable(randomColor()));
|
||||||
|
setContentView(R.layout.image_block);
|
||||||
|
View hero = getHero();
|
||||||
|
if (hero != null) {
|
||||||
|
hero.setSharedElementName("hero");
|
||||||
|
}
|
||||||
|
TransitionManager transitionManager = getContentTransitionManager();
|
||||||
|
TransitionSet transitions = new TransitionSet();
|
||||||
|
Fall fall = new Fall();
|
||||||
|
fall.setDuration(600);
|
||||||
|
fall.setStartDelay(600);
|
||||||
|
fall.setHero(hero);
|
||||||
|
transitions.addTransition(fall);
|
||||||
|
transitions.addTransition(new Up());
|
||||||
|
transitionManager.setTransition("null", getContentScene(), transitions);
|
||||||
|
|
||||||
|
transitions = new TransitionSet();
|
||||||
|
mFall = new Fall();
|
||||||
|
mFall.setDuration(600);
|
||||||
|
transitions.addTransition(mFall);
|
||||||
|
transitions.addTransition(new Up());
|
||||||
|
transitionManager.setTransition(getContentScene(), "null", transitions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (mComeBack) {
|
||||||
|
mComeBack = false;
|
||||||
|
setContentView(R.layout.image_block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private View getHero() {
|
||||||
|
Bundle transitionArgs = getTransitionArgs();
|
||||||
|
if (transitionArgs == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int id = transitionArgs.getInt(KEY_ID);
|
||||||
|
return findViewById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Property<Drawable, Rect> DRAWABLE_BOUNDS
|
||||||
|
= new Property<Drawable, Rect>(Rect.class, "bounds") {
|
||||||
|
@Override
|
||||||
|
public Rect get(Drawable object) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Drawable object, Rect value) {
|
||||||
|
object.setBounds(value);
|
||||||
|
object.invalidateSelf();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startSharedElementTransition(Bundle transitionArgs) {
|
||||||
|
final ImageView hero = (ImageView)getHero();
|
||||||
|
hero.setSharedElementName(null);
|
||||||
|
hero.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
int[] loc = new int[2];
|
||||||
|
hero.getLocationOnScreen(loc);
|
||||||
|
int endScreenLeft = loc[0];
|
||||||
|
int endScreenTop = loc[1];
|
||||||
|
int originalWidth = hero.getWidth();
|
||||||
|
int originalHeight = hero.getHeight();
|
||||||
|
|
||||||
|
hero.setVisibility(View.INVISIBLE);
|
||||||
|
ViewGroup sceneRoot = getContentScene().getSceneRoot();
|
||||||
|
sceneRoot.getLocationOnScreen(loc);
|
||||||
|
int overlayLeft = loc[0];
|
||||||
|
int overlayTop = loc[1];
|
||||||
|
final ViewGroupOverlay overlay = sceneRoot.getOverlay();
|
||||||
|
|
||||||
|
int endX = endScreenLeft - overlayLeft;
|
||||||
|
int endY = endScreenTop - overlayTop;
|
||||||
|
|
||||||
|
int startX = transitionArgs.getInt(KEY_LEFT_ON_SCREEN) - overlayLeft;
|
||||||
|
int startY = transitionArgs.getInt(KEY_TOP_ON_SCREEN) - overlayTop;
|
||||||
|
int startWidth = transitionArgs.getInt(KEY_WIDTH);
|
||||||
|
int startHeight = transitionArgs.getInt(KEY_HEIGHT);
|
||||||
|
|
||||||
|
int endHeight = originalWidth * startHeight / startWidth;
|
||||||
|
final Drawable image = hero.getDrawable();
|
||||||
|
Rect startBounds = new Rect(startX, startY, startX + startWidth, startY + startHeight);
|
||||||
|
endY += originalHeight - endHeight;
|
||||||
|
Rect endBounds = new Rect(endX, endY, endX + originalWidth, endY + endHeight);
|
||||||
|
ObjectAnimator boundsAnimator = ObjectAnimator.ofObject(image, DRAWABLE_BOUNDS,
|
||||||
|
new RectEvaluator(new Rect()), startBounds, endBounds);
|
||||||
|
hero.setImageDrawable(null);
|
||||||
|
image.setBounds(startBounds);
|
||||||
|
overlay.add(image);
|
||||||
|
|
||||||
|
boundsAnimator.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
overlay.remove(image);
|
||||||
|
hero.setImageDrawable(image);
|
||||||
|
hero.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
boundsAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clicked(View v) {
|
||||||
|
v.setSharedElementName("hero");
|
||||||
|
mFall.setHero(v);
|
||||||
|
Intent intent = new Intent(this, ActivityTransitionDetails.class);
|
||||||
|
Bundle args = getHeroInfo(v);
|
||||||
|
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(args);
|
||||||
|
startActivity(intent, options.toBundle());
|
||||||
|
//v.setTranslationZ(300);
|
||||||
|
mComeBack = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int randomColor() {
|
||||||
|
int red = mRandom.nextInt(128);
|
||||||
|
int green = mRandom.nextInt(128);
|
||||||
|
int blue = mRandom.nextInt(128);
|
||||||
|
return 0xFF000000 | (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bundle getHeroInfo(View view) {
|
||||||
|
int[] loc = new int[2];
|
||||||
|
view.getLocationOnScreen(loc);
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putInt(KEY_LEFT_ON_SCREEN, loc[0]);
|
||||||
|
bundle.putInt(KEY_TOP_ON_SCREEN, loc[1]);
|
||||||
|
bundle.putInt(KEY_WIDTH, view.getWidth());
|
||||||
|
bundle.putInt(KEY_HEIGHT, view.getHeight());
|
||||||
|
bundle.putInt(KEY_ID, view.getId());
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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.apis.animation;
|
||||||
|
|
||||||
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.RectEvaluator;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityOptions;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.transition.TransitionManager;
|
||||||
|
import android.transition.TransitionSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Property;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewGroupOverlay;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ActivityTransitionDetails extends Activity {
|
||||||
|
private static final String TAG = "ActivityTransitionDetails";
|
||||||
|
|
||||||
|
private static final String KEY_LEFT_ON_SCREEN = "ViewTransitionValues:left:";
|
||||||
|
private static final String KEY_TOP_ON_SCREEN = "ViewTransitionValues:top:";
|
||||||
|
private static final String KEY_WIDTH = "ViewTransitionValues:width:";
|
||||||
|
private static final String KEY_HEIGHT = "ViewTransitionValues:height:";
|
||||||
|
private static final String KEY_ID = "ViewTransitionValues:id";
|
||||||
|
|
||||||
|
private Random mRandom = new Random();
|
||||||
|
private boolean mComeBack;
|
||||||
|
private int mImageResourceId = R.drawable.ducky;
|
||||||
|
private int mId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
|
||||||
|
setEarlyBackgroundTransition(false);
|
||||||
|
getWindow().setBackgroundDrawable(new ColorDrawable(randomColor()));
|
||||||
|
setContentView(R.layout.image_details);
|
||||||
|
setImageMatrix();
|
||||||
|
ImageView hero = (ImageView)findViewById(R.id.titleImage);
|
||||||
|
hero.setImageDrawable(getHeroDrawable());
|
||||||
|
//hero.setTranslationZ(300);
|
||||||
|
TransitionManager transitionManager = getContentTransitionManager();
|
||||||
|
TransitionSet transitions = new TransitionSet();
|
||||||
|
Fall fall = new Fall();
|
||||||
|
fall.setDuration(600);
|
||||||
|
fall.setStartDelay(600);
|
||||||
|
transitions.addTransition(fall);
|
||||||
|
transitions.addTransition(new Up());
|
||||||
|
transitionManager.setTransition("null", getContentScene(), transitions);
|
||||||
|
|
||||||
|
transitions = new TransitionSet();
|
||||||
|
fall = new Fall();
|
||||||
|
fall.setDuration(600);
|
||||||
|
transitions.addTransition(fall);
|
||||||
|
transitions.addTransition(new Up());
|
||||||
|
transitionManager.setTransition(getContentScene(), "null", transitions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (mComeBack) {
|
||||||
|
mComeBack = false;
|
||||||
|
setContentView(R.layout.image_details);
|
||||||
|
ImageView hero = (ImageView)findViewById(R.id.titleImage);
|
||||||
|
hero.setImageDrawable(getHeroDrawable());
|
||||||
|
setImageMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable getHeroDrawable() {
|
||||||
|
Bundle args = getTransitionArgs();
|
||||||
|
int id = args == null ? 0 : args.getInt(KEY_ID);
|
||||||
|
int resourceId;
|
||||||
|
switch (id) {
|
||||||
|
case R.id.ducky: resourceId = R.drawable.ducky; break;
|
||||||
|
case R.id.jellies: resourceId = R.drawable.jellies; break;
|
||||||
|
case R.id.mug: resourceId = R.drawable.mug; break;
|
||||||
|
case R.id.pencil: resourceId = R.drawable.pencil; break;
|
||||||
|
case R.id.scissors: resourceId = R.drawable.scissors; break;
|
||||||
|
case R.id.woot: resourceId = R.drawable.woot; break;
|
||||||
|
case R.id.ball: resourceId = R.drawable.ball; break;
|
||||||
|
case R.id.block: resourceId = R.drawable.block; break;
|
||||||
|
default:
|
||||||
|
resourceId = mImageResourceId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mImageResourceId = resourceId;
|
||||||
|
return getResources().getDrawable(resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Property<Drawable, Rect> DRAWABLE_BOUNDS
|
||||||
|
= new Property<Drawable, Rect>(Rect.class, "bounds") {
|
||||||
|
@Override
|
||||||
|
public Rect get(Drawable object) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Drawable object, Rect value) {
|
||||||
|
object.setBounds(value);
|
||||||
|
object.invalidateSelf();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void setImageMatrix() {
|
||||||
|
getWindow().getDecorView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreDraw() {
|
||||||
|
getWindow().getDecorView().getViewTreeObserver().removeOnPreDrawListener(this);
|
||||||
|
// Use an image matrix such that it aligns with the bottom.
|
||||||
|
final ImageView hero = (ImageView)findViewById(R.id.titleImage);
|
||||||
|
hero.setScaleType(ImageView.ScaleType.MATRIX);
|
||||||
|
Matrix matrix = hero.getImageMatrix();
|
||||||
|
int height = hero.getHeight();
|
||||||
|
int width = hero.getWidth();
|
||||||
|
Drawable image = hero.getDrawable();
|
||||||
|
int intrinsicHeight = image.getIntrinsicHeight();
|
||||||
|
int intrinsicWidth = image.getIntrinsicWidth();
|
||||||
|
int scaledHeight = intrinsicHeight * width / intrinsicWidth;
|
||||||
|
matrix.postTranslate(0, (height - scaledHeight) / 2);
|
||||||
|
hero.setImageMatrix(matrix);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startSharedElementTransition(Bundle transitionArgs) {
|
||||||
|
mId = transitionArgs.getInt(KEY_ID);
|
||||||
|
final ImageView hero = (ImageView)findViewById(R.id.titleImage);
|
||||||
|
int[] loc = new int[2];
|
||||||
|
hero.getLocationOnScreen(loc);
|
||||||
|
int endScreenLeft = loc[0];
|
||||||
|
int endScreenTop = loc[1];
|
||||||
|
int originalWidth = hero.getWidth();
|
||||||
|
int originalHeight = hero.getHeight();
|
||||||
|
|
||||||
|
hero.setVisibility(View.INVISIBLE);
|
||||||
|
ViewGroup sceneRoot = getContentScene().getSceneRoot();
|
||||||
|
sceneRoot.getLocationOnScreen(loc);
|
||||||
|
int overlayLeft = loc[0];
|
||||||
|
int overlayTop = loc[1];
|
||||||
|
final ViewGroupOverlay overlay = sceneRoot.getOverlay();
|
||||||
|
|
||||||
|
int endX = endScreenLeft - overlayLeft;
|
||||||
|
int endY = endScreenTop - overlayTop;
|
||||||
|
|
||||||
|
int startX = transitionArgs.getInt(KEY_LEFT_ON_SCREEN) - overlayLeft;
|
||||||
|
int startY = transitionArgs.getInt(KEY_TOP_ON_SCREEN) - overlayTop;
|
||||||
|
int startWidth = transitionArgs.getInt(KEY_WIDTH);
|
||||||
|
int startHeight = transitionArgs.getInt(KEY_HEIGHT);
|
||||||
|
|
||||||
|
int endHeight = originalWidth * startHeight / startWidth;
|
||||||
|
final Drawable image = hero.getDrawable();
|
||||||
|
Rect startBounds = new Rect(startX, startY, startX + startWidth, startY + startHeight);
|
||||||
|
endY += originalHeight - endHeight;
|
||||||
|
Rect endBounds = new Rect(endX, endY, endX + originalWidth, endY + endHeight);
|
||||||
|
ObjectAnimator boundsAnimator = ObjectAnimator.ofObject(image, DRAWABLE_BOUNDS,
|
||||||
|
new RectEvaluator(new Rect()), startBounds, endBounds);
|
||||||
|
hero.setImageDrawable(null);
|
||||||
|
image.setBounds(startBounds);
|
||||||
|
overlay.add(image);
|
||||||
|
|
||||||
|
boundsAnimator.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
overlay.remove(image);
|
||||||
|
hero.setImageDrawable(image);
|
||||||
|
hero.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
boundsAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clicked(View v) {
|
||||||
|
Intent intent = new Intent(this, ActivityTransition.class);
|
||||||
|
Bundle args = getHeroInfo((ImageView)v);
|
||||||
|
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(args);
|
||||||
|
startActivity(intent, options.toBundle());
|
||||||
|
mComeBack = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int randomColor() {
|
||||||
|
int red = mRandom.nextInt(128);
|
||||||
|
int green = mRandom.nextInt(128);
|
||||||
|
int blue = mRandom.nextInt(128);
|
||||||
|
return 0xFF000000 | (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bundle getHeroInfo(ImageView view) {
|
||||||
|
int[] loc = new int[2];
|
||||||
|
view.getLocationOnScreen(loc);
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
Drawable image = view.getDrawable();
|
||||||
|
int intrinsicWidth = image.getIntrinsicWidth();
|
||||||
|
int intrinsicHeight = image.getIntrinsicHeight();
|
||||||
|
int width = view.getWidth();
|
||||||
|
int height = intrinsicHeight * width / intrinsicWidth;
|
||||||
|
int top = loc[1] + view.getHeight() - height;
|
||||||
|
bundle.putInt(KEY_LEFT_ON_SCREEN, loc[0]);
|
||||||
|
bundle.putInt(KEY_TOP_ON_SCREEN, top);
|
||||||
|
bundle.putInt(KEY_WIDTH, width);
|
||||||
|
bundle.putInt(KEY_HEIGHT, height);
|
||||||
|
bundle.putInt(KEY_ID, mId);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,335 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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.apis.animation;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.TimeInterpolator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.transition.Transition;
|
||||||
|
import android.transition.TransitionValues;
|
||||||
|
import android.transition.Visibility;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AccelerateInterpolator;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Fall extends Visibility {
|
||||||
|
private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
|
||||||
|
private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
|
||||||
|
private static final String TAG = "Fall";
|
||||||
|
private static final String PROPNAME_SCREEN_LOCATION = "android:fade:screen_location";
|
||||||
|
|
||||||
|
private View mHero;
|
||||||
|
|
||||||
|
public void setHero(View hero) {
|
||||||
|
mHero = hero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Animator createAnimation(final View view, long startDelay, final float startY,
|
||||||
|
float endY, AnimatorListenerAdapter listener, TimeInterpolator interpolator) {
|
||||||
|
if (startY == endY) {
|
||||||
|
// run listener if we're noop'ing the animation, to get the end-state results now
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onAnimationEnd(null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, startY, endY);
|
||||||
|
|
||||||
|
if (listener != null) {
|
||||||
|
anim.addListener(listener);
|
||||||
|
anim.addPauseListener(listener);
|
||||||
|
}
|
||||||
|
anim.setInterpolator(interpolator);
|
||||||
|
anim.setStartDelay(startDelay);
|
||||||
|
AnimatorSet wrapper = new AnimatorSet();
|
||||||
|
wrapper.play(anim);
|
||||||
|
wrapper.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
view.setTranslationY(startY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void captureValues(TransitionValues transitionValues) {
|
||||||
|
int[] loc = new int[2];
|
||||||
|
transitionValues.view.getLocationOnScreen(loc);
|
||||||
|
transitionValues.values.put(PROPNAME_SCREEN_LOCATION, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void captureStartValues(TransitionValues transitionValues) {
|
||||||
|
super.captureStartValues(transitionValues);
|
||||||
|
captureValues(transitionValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void captureEndValues(TransitionValues transitionValues) {
|
||||||
|
super.captureEndValues(transitionValues);
|
||||||
|
captureValues(transitionValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Animator onAppear(ViewGroup sceneRoot,
|
||||||
|
TransitionValues startValues, int startVisibility,
|
||||||
|
TransitionValues endValues, int endVisibility) {
|
||||||
|
if (endValues == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final View endView = endValues.view;
|
||||||
|
Log.v(TAG, "onAppear: " + endView.getId());
|
||||||
|
final float endY = endView.getTranslationY();
|
||||||
|
final float startY = endY + sceneRoot.getHeight();
|
||||||
|
|
||||||
|
TransitionListener transitionListener = new TransitionListener() {
|
||||||
|
boolean mCanceled = false;
|
||||||
|
float mPausedY;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionCancel(Transition transition) {
|
||||||
|
endView.setTranslationY(endY);
|
||||||
|
mCanceled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionStart(Transition transition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionEnd(Transition transition) {
|
||||||
|
if (!mCanceled) {
|
||||||
|
endView.setTranslationY(endY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionPause(Transition transition) {
|
||||||
|
mPausedY = endView.getTranslationY();
|
||||||
|
endView.setTranslationY(endY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionResume(Transition transition) {
|
||||||
|
endView.setTranslationY(mPausedY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addListener(transitionListener);
|
||||||
|
int[] loc = (int[]) endValues.values.get(PROPNAME_SCREEN_LOCATION);
|
||||||
|
long startDelay = calculateRiseStartDelay(sceneRoot, endView, loc);
|
||||||
|
return createAnimation(endView, startDelay, startY, endY, null, sDecelerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Animator onDisappear(ViewGroup sceneRoot,
|
||||||
|
TransitionValues startValues, int startVisibility,
|
||||||
|
TransitionValues endValues, int endVisibility) {
|
||||||
|
View view = null;
|
||||||
|
View startView = (startValues != null) ? startValues.view : null;
|
||||||
|
View endView = (endValues != null) ? endValues.view : null;
|
||||||
|
View overlayView = null;
|
||||||
|
View viewToKeep = null;
|
||||||
|
if (endView == null || endView.getParent() == null) {
|
||||||
|
if (endView != null) {
|
||||||
|
// endView was removed from its parent - add it to the overlay
|
||||||
|
view = overlayView = endView;
|
||||||
|
} else if (startView != null) {
|
||||||
|
// endView does not exist. Use startView only under certain
|
||||||
|
// conditions, because placing a view in an overlay necessitates
|
||||||
|
// it being removed from its current parent
|
||||||
|
if (startView.getParent() == null) {
|
||||||
|
// no parent - safe to use
|
||||||
|
view = overlayView = startView;
|
||||||
|
} else if (startView.getParent() instanceof View &&
|
||||||
|
startView.getParent().getParent() == null) {
|
||||||
|
View startParent = (View) startView.getParent();
|
||||||
|
int id = startParent.getId();
|
||||||
|
if (id != View.NO_ID && sceneRoot.findViewById(id) != null && canRemoveViews()) {
|
||||||
|
// no parent, but its parent is unparented but the parent
|
||||||
|
// hierarchy has been replaced by a new hierarchy with the same id
|
||||||
|
// and it is safe to un-parent startView
|
||||||
|
view = overlayView = startView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// visibility change
|
||||||
|
if (endVisibility == View.INVISIBLE) {
|
||||||
|
view = endView;
|
||||||
|
viewToKeep = view;
|
||||||
|
} else {
|
||||||
|
// Becoming GONE
|
||||||
|
if (startView == endView) {
|
||||||
|
view = endView;
|
||||||
|
viewToKeep = view;
|
||||||
|
} else {
|
||||||
|
view = startView;
|
||||||
|
overlayView = view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int finalVisibility = endVisibility;
|
||||||
|
|
||||||
|
int[] loc = (int[]) startValues.values.get(PROPNAME_SCREEN_LOCATION);
|
||||||
|
// TODO: add automatic facility to Visibility superclass for keeping views around
|
||||||
|
if (overlayView != null) {
|
||||||
|
// TODO: Need to do this for general case of adding to overlay
|
||||||
|
long startDelay = calculateFallStartDelay(sceneRoot, overlayView, loc);
|
||||||
|
int screenX = loc[0];
|
||||||
|
int screenY = loc[1];
|
||||||
|
loc = new int[2];
|
||||||
|
sceneRoot.getLocationOnScreen(loc);
|
||||||
|
overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
|
||||||
|
overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
|
||||||
|
sceneRoot.getOverlay().add(overlayView);
|
||||||
|
// TODO: add automatic facility to Visibility superclass for keeping views around
|
||||||
|
final float startY = overlayView.getTranslationY();
|
||||||
|
float endY = startY + sceneRoot.getHeight();
|
||||||
|
final View finalView = view;
|
||||||
|
final View finalOverlayView = overlayView;
|
||||||
|
final View finalViewToKeep = viewToKeep;
|
||||||
|
final ViewGroup finalSceneRoot = sceneRoot;
|
||||||
|
final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
finalView.setTranslationY(startY);
|
||||||
|
// TODO: restore view offset from overlay repositioning
|
||||||
|
if (finalViewToKeep != null) {
|
||||||
|
finalViewToKeep.setVisibility(finalVisibility);
|
||||||
|
}
|
||||||
|
if (finalOverlayView != null) {
|
||||||
|
finalSceneRoot.getOverlay().remove(finalOverlayView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationPause(Animator animation) {
|
||||||
|
if (finalOverlayView != null) {
|
||||||
|
finalSceneRoot.getOverlay().remove(finalOverlayView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationResume(Animator animation) {
|
||||||
|
if (finalOverlayView != null) {
|
||||||
|
finalSceneRoot.getOverlay().add(finalOverlayView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return createAnimation(view, startDelay, startY, endY, endListener, sAccelerate);
|
||||||
|
}
|
||||||
|
if (viewToKeep != null) {
|
||||||
|
long startDelay = calculateFallStartDelay(sceneRoot, viewToKeep, loc);
|
||||||
|
// TODO: find a different way to do this, like just changing the view to be
|
||||||
|
// VISIBLE for the duration of the transition
|
||||||
|
viewToKeep.setVisibility((View.VISIBLE));
|
||||||
|
// TODO: add automatic facility to Visibility superclass for keeping views around
|
||||||
|
final float startY = viewToKeep.getTranslationY();
|
||||||
|
float endY = startY + sceneRoot.getHeight();
|
||||||
|
final View finalView = view;
|
||||||
|
final View finalOverlayView = overlayView;
|
||||||
|
final View finalViewToKeep = viewToKeep;
|
||||||
|
final ViewGroup finalSceneRoot = sceneRoot;
|
||||||
|
final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
|
||||||
|
boolean mCanceled = false;
|
||||||
|
float mPausedY = -1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationPause(Animator animation) {
|
||||||
|
if (finalViewToKeep != null && !mCanceled) {
|
||||||
|
finalViewToKeep.setVisibility(finalVisibility);
|
||||||
|
}
|
||||||
|
mPausedY = finalView.getTranslationY();
|
||||||
|
finalView.setTranslationY(startY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationResume(Animator animation) {
|
||||||
|
if (finalViewToKeep != null && !mCanceled) {
|
||||||
|
finalViewToKeep.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
finalView.setTranslationY(mPausedY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
mCanceled = true;
|
||||||
|
if (mPausedY >= 0) {
|
||||||
|
finalView.setTranslationY(mPausedY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
if (!mCanceled) {
|
||||||
|
finalView.setTranslationY(startY);
|
||||||
|
}
|
||||||
|
// TODO: restore view offset from overlay repositioning
|
||||||
|
if (finalViewToKeep != null && !mCanceled) {
|
||||||
|
finalViewToKeep.setVisibility(finalVisibility);
|
||||||
|
}
|
||||||
|
if (finalOverlayView != null) {
|
||||||
|
finalSceneRoot.getOverlay().remove(finalOverlayView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return createAnimation(view, startDelay, startY, endY, endListener, sAccelerate);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long calculateFallStartDelay(View sceneRoot, View view, int[] viewLoc) {
|
||||||
|
int[] loc = new int[2];
|
||||||
|
sceneRoot.getLocationOnScreen(loc);
|
||||||
|
int bottom = loc[1] + sceneRoot.getHeight();
|
||||||
|
float distance = bottom - viewLoc[1] + view.getTranslationY();
|
||||||
|
if (mHero != null) {
|
||||||
|
mHero.getLocationOnScreen(loc);
|
||||||
|
float heroX = loc[0] + mHero.getTranslationX() + (mHero.getWidth() / 2.0f);
|
||||||
|
float viewX = viewLoc[0] + view.getTranslationX() + (view.getWidth() / 2.0f);
|
||||||
|
float distanceX = Math.abs(heroX - viewX);
|
||||||
|
float distanceXRatio = distanceX / sceneRoot.getWidth();
|
||||||
|
distance += (1 - distanceXRatio) * mHero.getHeight();
|
||||||
|
}
|
||||||
|
float distanceRatio = distance/sceneRoot.getHeight() / 3;
|
||||||
|
return Math.max(0, Math.round(distanceRatio * getDuration()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private long calculateRiseStartDelay(View sceneRoot, View view, int[] viewLoc) {
|
||||||
|
int[] loc = new int[2];
|
||||||
|
sceneRoot.getLocationOnScreen(loc);
|
||||||
|
int top = loc[1];
|
||||||
|
float distance = viewLoc[1] + view.getTranslationY() - top;
|
||||||
|
if (mHero != null) {
|
||||||
|
mHero.getLocationOnScreen(loc);
|
||||||
|
float heroX = loc[0] + mHero.getTranslationX() + (mHero.getWidth() / 2.0f);
|
||||||
|
float viewX = viewLoc[0] + view.getTranslationX() + (view.getWidth() / 2.0f);
|
||||||
|
float distanceX = Math.abs(heroX - viewX);
|
||||||
|
float distanceXRatio = distanceX / sceneRoot.getWidth();
|
||||||
|
distance += distanceXRatio * mHero.getHeight();
|
||||||
|
}
|
||||||
|
float distanceRatio = distance/sceneRoot.getHeight() / 3;
|
||||||
|
return Math.max(0, Math.round(distanceRatio * getDuration()));
|
||||||
|
}
|
||||||
|
}
|
||||||
103
samples/ApiDemos/src/com/example/android/apis/animation/Up.java
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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.apis.animation;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.transition.Transition;
|
||||||
|
import android.transition.TransitionValues;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Up extends Transition {
|
||||||
|
private static final String PROPNAME_Z = "android:z:height";
|
||||||
|
private static final String[] sTransitionProperties = {
|
||||||
|
PROPNAME_Z,
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void captureStartValues(TransitionValues transitionValues) {
|
||||||
|
captureValues(transitionValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void captureEndValues(TransitionValues transitionValues) {
|
||||||
|
captureValues(transitionValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void captureValues(TransitionValues transitionValues) {
|
||||||
|
View view = transitionValues.view;
|
||||||
|
transitionValues.values.put(PROPNAME_Z, view.getTranslationZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getTransitionProperties() {
|
||||||
|
return sTransitionProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
|
||||||
|
TransitionValues endValues) {
|
||||||
|
if (startValues == null || endValues == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final float startZ = (Float)startValues.values.get(PROPNAME_Z);
|
||||||
|
final float endZ = (Float)endValues.values.get(PROPNAME_Z);
|
||||||
|
if (startZ == endZ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final View view = endValues.view;
|
||||||
|
|
||||||
|
TransitionListener transitionListener = new TransitionListener() {
|
||||||
|
boolean mCanceled = false;
|
||||||
|
float mPausedZ;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionCancel(Transition transition) {
|
||||||
|
view.setTranslationZ(endZ);
|
||||||
|
mCanceled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionStart(Transition transition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionEnd(Transition transition) {
|
||||||
|
if (!mCanceled) {
|
||||||
|
view.setTranslationZ(endZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionPause(Transition transition) {
|
||||||
|
mPausedZ = view.getTranslationZ();
|
||||||
|
view.setTranslationZ(endZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionResume(Transition transition) {
|
||||||
|
view.setTranslationZ(mPausedZ);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addListener(transitionListener);
|
||||||
|
|
||||||
|
return ObjectAnimator.ofFloat(view, View.TRANSLATION_Z, startZ, endZ);
|
||||||
|
}
|
||||||
|
}
|
||||||