am 690af128: Cherrypick from Change-Id: I4ae984cf776604cede32b98db6b1eb3cb6c59c7e
* commit '690af1285c320a1d3fc31cc57414347c74bd8e1d':
Cherrypick from Change-Id: I4ae984cf776604cede32b98db6b1eb3cb6c59c7e
diff --git a/samples/devbytes/animation/Bouncer/AndroidManifest.xml b/samples/devbytes/animation/Bouncer/AndroidManifest.xml
new file mode 100644
index 0000000..ff10b72
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/AndroidManifest.xml
@@ -0,0 +1,67 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.bouncer"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="14"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".Bouncer"
+ android:label="@string/title_activity_bouncer" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".Bouncer1"
+ android:label="@string/title_activity_bouncer1" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".Bouncer2"
+ android:label="@string/title_activity_bouncer2" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="com.example.android.bouncer.Bouncer3"
+ android:label="@string/title_activity_bouncer3" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png b/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png
new file mode 100644
index 0000000..22b224a
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png
Binary files differ
diff --git a/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml
new file mode 100644
index 0000000..543951b
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml
@@ -0,0 +1,28 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:background="#007F00"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <view android:id="@+id/myview"
+ class="com.example.android.bouncer.Bouncer$MyView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Bouncer" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml
new file mode 100644
index 0000000..765f6ae
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml
@@ -0,0 +1,28 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:background="#007F00"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <view android:id="@+id/myview"
+ class="com.example.android.bouncer.Bouncer1$MyView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Bouncer" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml
new file mode 100644
index 0000000..db21eee
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml
@@ -0,0 +1,28 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:background="#007F00"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <view android:id="@+id/myview"
+ class="com.example.android.bouncer.Bouncer2$MyView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Bouncer" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml
new file mode 100644
index 0000000..a1a6911
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml
@@ -0,0 +1,28 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:background="#007F00"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <view android:id="@+id/myview"
+ class="com.example.android.bouncer.Bouncer3$MyView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Bouncer" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml b/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/Bouncer/res/values-v14/styles.xml b/samples/devbytes/animation/Bouncer/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/Bouncer/res/values/strings.xml b/samples/devbytes/animation/Bouncer/res/values/strings.xml
new file mode 100644
index 0000000..85e2391
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values/strings.xml
@@ -0,0 +1,23 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">Bouncer</string>
+ <string name="title_activity_bouncer">Bouncer</string>
+ <string name="title_activity_bouncer1">Bouncer1</string>
+ <string name="title_activity_bouncer2">Bouncer2</string>
+ <string name="title_activity_bouncer3">Bouncer3</string>
+
+</resources>
diff --git a/samples/devbytes/animation/Bouncer/res/values/styles.xml b/samples/devbytes/animation/Bouncer/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer.java b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer.java
new file mode 100644
index 0000000..a04c378
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer.java
@@ -0,0 +1,144 @@
+/*
+ * 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.bouncer;
+
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * This example shows simple uses of ValueAnimator, ObjectAnimator, and interpolators
+ * to control how a shape is moved around on the screen.
+ *
+ * The Bouncer1, Bouncer2, and Vouncer3 files are exactly like this one except for variations
+ * in how the animation is set up and run.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=vCTcmPIKgpM.
+ */
+public class Bouncer extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bouncer);
+ }
+
+ /**
+ * A custom view is used to paint the green background and the shape.
+ */
+ static class MyView extends View {
+
+ Bitmap mBitmap;
+ Paint paint = new Paint();
+ int mShapeX, mShapeY;
+ int mShapeW, mShapeH;
+
+ public MyView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setupShape();
+ }
+
+ public MyView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setupShape();
+ }
+
+ public MyView(Context context) {
+ super(context);
+ setupShape();
+ }
+
+ private void setupShape() {
+ mBitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.electricsheep);
+ mShapeW = mBitmap.getWidth();
+ mShapeH = mBitmap.getHeight();
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startAnimation();
+ }
+ });
+ }
+
+ /**
+ * Moving the shape in x or y causes an invalidation of the area it used to occupy
+ * plus the area it now occupies.
+ */
+ public void setShapeX(int shapeX) {
+ int minX = mShapeX;
+ int maxX = mShapeX + mShapeW;
+ mShapeX = shapeX;
+ minX = Math.min(mShapeX, minX);
+ maxX = Math.max(mShapeX + mShapeW, maxX);
+ invalidate(minX, mShapeY, maxX, mShapeY + mShapeH);
+ }
+
+ /**
+ * Moving the shape in x or y causes an invalidation of the area it used to occupy
+ * plus the area it now occupies.
+ */
+ public void setShapeY(int shapeY) {
+ int minY = mShapeY;
+ int maxY = mShapeY + mShapeH;
+ mShapeY = shapeY;
+ minY = Math.min(mShapeY, minY);
+ maxY = Math.max(mShapeY + mShapeH, maxY);
+ invalidate(mShapeX, minY, mShapeX + mShapeW, maxY);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mShapeX = (w - mBitmap.getWidth()) / 2;
+ mShapeY = 0;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint);
+ }
+
+ void startAnimation() {
+ // This version uses ValueAnimator, which requires adding an update
+ // listener and manually updating the shape position on each frame.
+ ValueAnimator anim = getValueAnimator();
+ anim.start();
+ }
+
+ ValueAnimator getValueAnimator() {
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ setShapeY((int) (animation.getAnimatedFraction() *
+ (getHeight() - mShapeH)));
+ }
+ });
+ return anim;
+ }
+
+ }
+}
diff --git a/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer1.java b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer1.java
new file mode 100644
index 0000000..554c0f2
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer1.java
@@ -0,0 +1,128 @@
+/*
+ * 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.bouncer;
+
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * See the comments in Bouncer for the overall functionality of this app. Changes for this
+ * variation are down in the animation setup code.
+ */
+public class Bouncer1 extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bouncer1);
+ }
+
+ static class MyView extends View {
+
+ Bitmap mBitmap;
+ Paint paint = new Paint();
+ int mShapeX, mShapeY;
+ int mShapeW, mShapeH;
+
+ public MyView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setupShape();
+ }
+
+ public MyView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setupShape();
+ }
+
+ public MyView(Context context) {
+ super(context);
+ setupShape();
+ }
+
+ public void setShapeX(int shapeX) {
+ int minX = mShapeX;
+ int maxX = mShapeX + mShapeW;
+ mShapeX = shapeX;
+ minX = Math.min(mShapeX, minX);
+ maxX = Math.max(mShapeX + mShapeW, maxX);
+ invalidate(minX, mShapeY, maxX, mShapeY + mShapeH);
+ }
+
+ public void setShapeY(int shapeY) {
+ int minY = mShapeY;
+ int maxY = mShapeY + mShapeH;
+ mShapeY = shapeY;
+ minY = Math.min(mShapeY, minY);
+ maxY = Math.max(mShapeY + mShapeH, maxY);
+ invalidate(mShapeX, minY, mShapeX + mShapeW, maxY);
+ }
+
+ private void setupShape() {
+ mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.electricsheep);
+ mShapeW = mBitmap.getWidth();
+ mShapeH = mBitmap.getHeight();
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startAnimation();
+ }
+ });
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mShapeX = (w - mBitmap.getWidth()) / 2;
+ mShapeY = 0;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint);
+ }
+
+ void startAnimation() {
+ ValueAnimator anim = getValueAnimator();
+ // In this variation, we put the shape into an infinite bounce, where it keeps moving
+ // up and down. Note that it's still not actually "bouncing" because it just uses
+ // default time interpolation.
+ anim.setRepeatCount(ValueAnimator.INFINITE);
+ anim.setRepeatMode(ValueAnimator.REVERSE);
+ anim.start();
+ }
+
+ ValueAnimator getValueAnimator() {
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ setShapeY((int) (animation.getAnimatedFraction() * (getHeight() - mShapeH)));
+ }
+ });
+ return anim;
+ }
+
+ }
+}
diff --git a/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer2.java b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer2.java
new file mode 100644
index 0000000..30ff64d
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer2.java
@@ -0,0 +1,130 @@
+/*
+ * 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.bouncer;
+
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+
+/**
+ * See the comments in Bouncer for the overall functionality of this app. Changes for this
+ * variation are down in the animation setup code.
+ */
+public class Bouncer2 extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bouncer2);
+ }
+
+ static class MyView extends View {
+
+ Bitmap mBitmap;
+ Paint paint = new Paint();
+ int mShapeX, mShapeY;
+ int mShapeW, mShapeH;
+
+ public MyView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setupShape();
+ }
+
+ public MyView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setupShape();
+ }
+
+ public MyView(Context context) {
+ super(context);
+ setupShape();
+ }
+
+ public void setShapeX(int shapeX) {
+ int minX = mShapeX;
+ int maxX = mShapeX + mShapeW;
+ mShapeX = shapeX;
+ minX = Math.min(mShapeX, minX);
+ maxX = Math.max(mShapeX + mShapeW, maxX);
+ invalidate(minX, mShapeY, maxX, mShapeY + mShapeH);
+ }
+
+ public void setShapeY(int shapeY) {
+ int minY = mShapeY;
+ int maxY = mShapeY + mShapeH;
+ mShapeY = shapeY;
+ minY = Math.min(mShapeY, minY);
+ maxY = Math.max(mShapeY + mShapeH, maxY);
+ invalidate(mShapeX, minY, mShapeX + mShapeW, maxY);
+ }
+
+ private void setupShape() {
+ mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.electricsheep);
+ mShapeW = mBitmap.getWidth();
+ mShapeH = mBitmap.getHeight();
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startAnimation();
+ }
+ });
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mShapeX = (w - mBitmap.getWidth()) / 2;
+ mShapeY = 0;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint);
+ }
+
+ void startAnimation() {
+ ValueAnimator anim = getValueAnimator();
+ anim.setRepeatCount(ValueAnimator.INFINITE);
+ anim.setRepeatMode(ValueAnimator.REVERSE);
+ // This variation finally has the shape bouncing, due to the use of an
+ // AccelerateInterpolator, which speeds up as the animation proceed. Note that
+ // when the animation reverses, the interpolator acts in reverse, decelerating
+ // movement.
+ anim.setInterpolator(new AccelerateInterpolator());
+ anim.start();
+ }
+
+ ValueAnimator getValueAnimator() {
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ setShapeY((int) (animation.getAnimatedFraction() * (getHeight() - mShapeH)));
+ }
+ });
+ return anim;
+ }
+ }
+}
diff --git a/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer3.java b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer3.java
new file mode 100644
index 0000000..cea9a3d
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/src/com/example/android/bouncer/Bouncer3.java
@@ -0,0 +1,124 @@
+/*
+ * 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.bouncer;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+
+/**
+ * See the comments in Bouncer for the overall functionality of this app. Changes for this
+ * variation are down in the animation setup code.
+ */
+public class Bouncer3 extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bouncer3);
+ }
+
+ static class MyView extends View {
+
+ Bitmap mBitmap;
+ Paint paint = new Paint();
+ int mShapeX, mShapeY;
+ int mShapeW, mShapeH;
+
+ public MyView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setupShape();
+ }
+
+ public MyView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setupShape();
+ }
+
+ public MyView(Context context) {
+ super(context);
+ setupShape();
+ }
+
+ public void setShapeX(int shapeX) {
+ int minX = mShapeX;
+ int maxX = mShapeX + mShapeW;
+ mShapeX = shapeX;
+ minX = Math.min(mShapeX, minX);
+ maxX = Math.max(mShapeX + mShapeW, maxX);
+ invalidate(minX, mShapeY, maxX, mShapeY + mShapeH);
+ }
+
+ public void setShapeY(int shapeY) {
+ int minY = mShapeY;
+ int maxY = mShapeY + mShapeH;
+ mShapeY = shapeY;
+ minY = Math.min(mShapeY, minY);
+ maxY = Math.max(mShapeY + mShapeH, maxY);
+ invalidate(mShapeX, minY, mShapeX + mShapeW, maxY);
+ }
+
+ private void setupShape() {
+ mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.electricsheep);
+ mShapeW = mBitmap.getWidth();
+ mShapeH = mBitmap.getHeight();
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startAnimation();
+ }
+ });
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mShapeX = (w - mBitmap.getWidth()) / 2;
+ mShapeY = 0;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint);
+ }
+
+ void startAnimation() {
+ // This variation uses an ObjectAnimator. The functionality is exactly the same as
+ // in Bouncer2, but this time the boilerplate code is greatly reduced because we
+ // tell ObjectAnimator to automatically animate the target object for us, so we no
+ // longer need to listen for frame updates and do that work ourselves.
+ ObjectAnimator anim = getObjectAnimator();
+ anim.setRepeatCount(ValueAnimator.INFINITE);
+ anim.setRepeatMode(ValueAnimator.REVERSE);
+ anim.setInterpolator(new AccelerateInterpolator());
+ anim.start();
+ }
+
+ ObjectAnimator getObjectAnimator() {
+ return ObjectAnimator.ofInt(this, "shapeY", 0, (getHeight() - mShapeH));
+ }
+
+ }
+}
diff --git a/samples/devbytes/animation/CrossFading/AndroidManifest.xml b/samples/devbytes/animation/CrossFading/AndroidManifest.xml
new file mode 100644
index 0000000..0d38d6a
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.crossfading"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.crossfading.CrossFading"
+ android:label="@string/title_activity_cross_fading" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/CrossFading/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/CrossFading/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/CrossFading/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/CrossFading/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/CrossFading/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/CrossFading/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/CrossFading/res/layout/activity_cross_fading.xml b/samples/devbytes/animation/CrossFading/res/layout/activity_cross_fading.xml
new file mode 100644
index 0000000..9c5423d
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/layout/activity_cross_fading.xml
@@ -0,0 +1,27 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <ImageView
+ android:id="@+id/imageview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/CrossFading/res/values-v11/styles.xml b/samples/devbytes/animation/CrossFading/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/CrossFading/res/values-v14/styles.xml b/samples/devbytes/animation/CrossFading/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/CrossFading/res/values/strings.xml b/samples/devbytes/animation/CrossFading/res/values/strings.xml
new file mode 100644
index 0000000..dbfca7e
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values/strings.xml
@@ -0,0 +1,20 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">CrossFading</string>
+ <string name="title_activity_cross_fading">CrossFading</string>
+
+</resources>
diff --git a/samples/devbytes/animation/CrossFading/res/values/styles.xml b/samples/devbytes/animation/CrossFading/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/CrossFading/src/com/example/android/crossfading/CrossFading.java b/samples/devbytes/animation/CrossFading/src/com/example/android/crossfading/CrossFading.java
new file mode 100644
index 0000000..e02694c
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/src/com/example/android/crossfading/CrossFading.java
@@ -0,0 +1,81 @@
+/*
+ * 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.crossfading;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * This example shows how to use TransitionDrawable to perform a simple cross-fade effect
+ * between two drawables.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=atH3o2uh_94.
+ */
+public class CrossFading extends Activity {
+
+ int mCurrentDrawable = 0;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_cross_fading);
+
+ final ImageView imageview = (ImageView) findViewById(R.id.imageview);
+
+ // Create red and green bitmaps to cross-fade between
+ Bitmap bitmap0 = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
+ Bitmap bitmap1 = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap0);
+ canvas.drawColor(Color.RED);
+ canvas = new Canvas(bitmap1);
+ canvas.drawColor(Color.GREEN);
+ BitmapDrawable drawables[] = new BitmapDrawable[2];
+ drawables[0] = new BitmapDrawable(getResources(), bitmap0);
+ drawables[1] = new BitmapDrawable(getResources(), bitmap1);
+
+ // Add the red/green bitmap drawables to a TransitionDrawable. They are layered
+ // in the transition drawalbe. The cross-fade effect happens by fading one out and the
+ // other in.
+ final TransitionDrawable crossfader = new TransitionDrawable(drawables);
+ imageview.setImageDrawable(crossfader);
+
+ // Clicking on the drawable will cause the cross-fade effect to run. Depending on
+ // which drawable is currently being shown, we either 'start' or 'reverse' the
+ // transition, which determines which drawable is faded out/in during the transition.
+ imageview.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (mCurrentDrawable == 0) {
+ crossfader.startTransition(500);
+ mCurrentDrawable = 1;
+ } else {
+ crossfader.reverseTransition(500);
+ mCurrentDrawable = 0;
+ }
+ }
+ });
+ }
+}
diff --git a/samples/devbytes/animation/KeyframeAnimation/AndroidManifest.xml b/samples/devbytes/animation/KeyframeAnimation/AndroidManifest.xml
new file mode 100644
index 0000000..2406281
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.keyframeanimation"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.keyframeanimation.KeyframeAnimation"
+ android:label="@string/title_activity_keyframe_animation" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/KeyframeAnimation/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/KeyframeAnimation/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/KeyframeAnimation/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/layout/activity_keyframe_animation.xml b/samples/devbytes/animation/KeyframeAnimation/res/layout/activity_keyframe_animation.xml
new file mode 100644
index 0000000..4da3948
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/layout/activity_keyframe_animation.xml
@@ -0,0 +1,28 @@
+<!-- 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <ImageView
+ android:id="@+id/imageview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ tools:context=".KeyframeAnimation" />
+
+</RelativeLayout>
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/values-v11/styles.xml b/samples/devbytes/animation/KeyframeAnimation/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/values-v14/styles.xml b/samples/devbytes/animation/KeyframeAnimation/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/values/strings.xml b/samples/devbytes/animation/KeyframeAnimation/res/values/strings.xml
new file mode 100644
index 0000000..330dae2
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values/strings.xml
@@ -0,0 +1,20 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">KeyframeAnimation</string>
+ <string name="title_activity_keyframe_animation">KeyframeAnimation</string>
+
+</resources>
diff --git a/samples/devbytes/animation/KeyframeAnimation/res/values/styles.xml b/samples/devbytes/animation/KeyframeAnimation/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/KeyframeAnimation/src/com/example/android/keyframeanimation/KeyframeAnimation.java b/samples/devbytes/animation/KeyframeAnimation/src/com/example/android/keyframeanimation/KeyframeAnimation.java
new file mode 100644
index 0000000..9a6bbd0
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/src/com/example/android/keyframeanimation/KeyframeAnimation.java
@@ -0,0 +1,85 @@
+/*
+ * 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.keyframeanimation;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * This example shows how to use AnimationDrawable to construct a keyframe animation where each
+ * frame is shown for a specified duration.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=V3ksidLf7vA.
+ */
+public class KeyframeAnimation extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_keyframe_animation);
+
+ ImageView imageview = (ImageView) findViewById(R.id.imageview);
+
+ // Create the AnimationDrawable in which we will store all frames of the animation
+ final AnimationDrawable animationDrawable = new AnimationDrawable();
+ for (int i = 0; i < 10; ++i) {
+ animationDrawable.addFrame(getDrawableForFrameNumber(i), 300);
+ }
+ // Run until we say stop
+ animationDrawable.setOneShot(false);
+
+ imageview.setImageDrawable(animationDrawable);
+
+ // When the user clicks on the image, toggle the animation on/off
+ imageview.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (animationDrawable.isRunning()) {
+ animationDrawable.stop();
+ } else {
+ animationDrawable.start();
+ }
+ }
+ });
+ }
+
+ /**
+ * The 'frames' in this app are nothing more than a gray background with text indicating
+ * the number of the frame.
+ */
+ private BitmapDrawable getDrawableForFrameNumber(int frameNumber) {
+ Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ canvas.drawColor(Color.GRAY);
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ paint.setTextSize(80);
+ paint.setColor(Color.BLACK);
+ canvas.drawText("Frame " + frameNumber, 40, 220, paint);
+ return new BitmapDrawable(getResources(), bitmap);
+ }
+
+}
diff --git a/samples/devbytes/animation/LayoutTransChanging/AndroidManifest.xml b/samples/devbytes/animation/LayoutTransChanging/AndroidManifest.xml
new file mode 100644
index 0000000..d9b55f5
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.layouttranschanging"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="16"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <application
+ android:icon="@drawable/icon"
+ android:label="@string/app_name"
+ android:hardwareAccelerated="true">
+ <activity android:label="@string/app_name"
+ android:name="com.example.android.layouttranschanging.LayoutTransChanging">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/LayoutTransChanging/res/drawable-hdpi/icon.png b/samples/devbytes/animation/LayoutTransChanging/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/devbytes/animation/LayoutTransChanging/res/drawable-ldpi/icon.png b/samples/devbytes/animation/LayoutTransChanging/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/devbytes/animation/LayoutTransChanging/res/drawable-mdpi/icon.png b/samples/devbytes/animation/LayoutTransChanging/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/devbytes/animation/LayoutTransChanging/res/layout/main.xml b/samples/devbytes/animation/LayoutTransChanging/res/layout/main.xml
new file mode 100644
index 0000000..3b5dd0d
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/layout/main.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/addButton"
+ android:id="@+id/addButton"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/removeButton"
+ android:id="@+id/removeButton"/>
+ </LinearLayout>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:animateLayoutChanges="true"
+ android:id="@+id/container"/>
+</LinearLayout>
diff --git a/samples/devbytes/animation/LayoutTransChanging/res/values/strings.xml b/samples/devbytes/animation/LayoutTransChanging/res/values/strings.xml
new file mode 100644
index 0000000..d50ad11
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+ <string name="app_name">LayoutTransChanging</string>
+ <string name="addButton">Add Item</string>
+ <string name="removeButton">Remove Item</string>
+</resources>
diff --git a/samples/devbytes/animation/LayoutTransChanging/src/com/example/android/layouttranschanging/LayoutTransChanging.java b/samples/devbytes/animation/LayoutTransChanging/src/com/example/android/layouttranschanging/LayoutTransChanging.java
new file mode 100644
index 0000000..e240330
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/src/com/example/android/layouttranschanging/LayoutTransChanging.java
@@ -0,0 +1,120 @@
+/*
+ * 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.layouttranschanging;
+
+import android.animation.LayoutTransition;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+
+/**
+ * This example shows how to use LayoutTransition to animate simple changes in a layout
+ * container.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=55wLsaWpQ4g.
+ */
+public class LayoutTransChanging extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ final Button addButton =
+ (Button) findViewById(R.id.addButton);
+ final Button removeButton =
+ (Button) findViewById(R.id.removeButton);
+ final LinearLayout container =
+ (LinearLayout) findViewById(R.id.container);
+ final Context context = this;
+
+ // Start with two views
+ for (int i = 0; i < 2; ++i) {
+ container.addView(new ColoredView(this));
+ }
+
+ addButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Adding a view will cause a LayoutTransition animation
+ container.addView(new ColoredView(context), 1);
+ }
+ });
+
+ removeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (container.getChildCount() > 0) {
+ // Removing a view will cause a LayoutTransition animation
+ container.removeViewAt(Math.min(1, container.getChildCount() - 1));
+ }
+ }
+ });
+
+ // Note that this assumes a LayoutTransition is set on the container, which is the
+ // case here because the container has the attribute "animateLayoutChanges" set to true
+ // in the layout file. You can also call setLayoutTransition(new LayoutTransition()) in
+ // code to set a LayoutTransition on any container.
+ LayoutTransition transition = container.getLayoutTransition();
+
+ // New capability as of Jellybean; monitor the container for *all* layout changes
+ // (not just add/remove/visibility changes) and animate these changes as well.
+ transition.enableTransitionType(LayoutTransition.CHANGING);
+ }
+
+ /**
+ * Custom view painted with a random background color and two different sizes which are
+ * toggled between due to user interaction.
+ */
+ private static class ColoredView extends View {
+
+ private boolean mExpanded = false;
+
+ private LayoutParams mCompressedParams = new LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, 50);
+
+ private LayoutParams mExpandedParams = new LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, 200);
+
+ private ColoredView(Context context) {
+ super(context);
+ int red = (int)(Math.random() * 128 + 127);
+ int green = (int)(Math.random() * 128 + 127);
+ int blue = (int)(Math.random() * 128 + 127);
+ int color = 0xff << 24 | (red << 16) |
+ (green << 8) | blue;
+ setBackgroundColor(color);
+ setLayoutParams(mCompressedParams);
+ setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Size changes will cause a LayoutTransition animation if the CHANGING
+ // transition is enabled
+ setLayoutParams(mExpanded ? mCompressedParams : mExpandedParams);
+ mExpanded = !mExpanded;
+ requestLayout();
+ }
+ });
+ }
+ }
+}
diff --git a/samples/devbytes/animation/ListViewAnimations/AndroidManifest.xml b/samples/devbytes/animation/ListViewAnimations/AndroidManifest.xml
new file mode 100644
index 0000000..16a0bf1
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.listviewanimations"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.listviewanimations.ListViewAnimations"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/ListViewAnimations/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/ListViewAnimations/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/ListViewAnimations/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/ListViewAnimations/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/ListViewAnimations/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/ListViewAnimations/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/ListViewAnimations/res/layout/activity_list_view_animations.xml b/samples/devbytes/animation/ListViewAnimations/res/layout/activity_list_view_animations.xml
new file mode 100644
index 0000000..b8fc9cd
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/layout/activity_list_view_animations.xml
@@ -0,0 +1,43 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".ListViewAnimations" >
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <CheckBox
+ android:id="@+id/vpaCB"
+ android:text="@string/viewpropertyanimator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <CheckBox
+ android:id="@+id/setTransientStateCB"
+ android:text="@string/transient_state"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <ListView
+ android:id="@+id/listview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/ListViewAnimations/res/values-v11/styles.xml b/samples/devbytes/animation/ListViewAnimations/res/values-v11/styles.xml
new file mode 100644
index 0000000..139d283
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values-v11/styles.xml
@@ -0,0 +1,25 @@
+<!-- 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.
+-->
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml b/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml
new file mode 100644
index 0000000..8ac4522
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml
@@ -0,0 +1,26 @@
+<!-- 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.
+-->
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml b/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml
new file mode 100644
index 0000000..5b41f5b
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">ListViewAnimations</string>
+ <string name="viewpropertyanimator">ViewPropertyAnimator</string>
+ <string name="transient_state">Transient State</string>
+
+</resources>
diff --git a/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml b/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml
new file mode 100644
index 0000000..f9460a7
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml
@@ -0,0 +1,34 @@
+<!-- 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.
+-->
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/Cheeses.java b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/Cheeses.java
new file mode 100644
index 0000000..69c027d
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/Cheeses.java
@@ -0,0 +1,154 @@
+/*
+ * 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.listviewanimations;
+
+public class Cheeses {
+
+ public static final String[] sCheeseStrings = {
+ "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+ "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+ "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+ "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+ "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+ "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+ "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+ "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+ "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+ "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+ "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+ "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+ "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+ "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+ "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+ "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+ "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+ "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+ "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+ "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+ "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+ "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+ "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+ "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+ "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+ "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+ "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+ "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+ "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+ "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+ "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+ "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+ "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+ "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+ "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+ "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+ "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+ "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+ "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+ "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+ "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+ "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+ "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+ "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+ "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+ "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+ "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+ "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+ "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+ "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+ "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+ "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+ "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+ "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+ "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+ "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+ "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+ "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+ "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+ "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+ "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+ "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+ "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+ "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+ "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+ "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+ "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+ "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+ "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+ "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+ "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+ "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+ "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+ "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+ "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+ "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+ "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+ "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+ "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+ "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+ "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+ "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+ "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+ "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+ "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+ "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+ "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+ "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+ "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+ "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+ "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+ "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+ "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+ "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+ "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+ "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+ "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+ "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+ "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+ "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+ "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+ "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+ "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+ "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+ "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+ "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+ "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+ "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+ "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+ "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+ "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+ "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+ "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+ "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+ "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+ "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+ "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+ "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+ "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+ "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+ "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+ "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+ "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+ "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+ "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+ "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+ "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+ "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+ "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+ "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+ };
+
+}
diff --git a/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/ListViewAnimations.java b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/ListViewAnimations.java
new file mode 100644
index 0000000..2d2cc68
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/ListViewAnimations.java
@@ -0,0 +1,134 @@
+/*
+ * 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.listviewanimations;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.ListView;
+
+/**
+ * This example shows how animating ListView items can lead to problems as views are recycled,
+ * and how to perform these types of animations correctly with new API added in Jellybean.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=8MIfSxgsHIs.
+ */
+public class ListViewAnimations extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_list_view_animations);
+
+ final CheckBox vpaCB = (CheckBox) findViewById(R.id.vpaCB);
+ final CheckBox setTransientStateCB = (CheckBox) findViewById(R.id.setTransientStateCB);
+ final ListView listview = (ListView) findViewById(R.id.listview);
+ final ArrayList<String> cheeseList = new ArrayList<String>();
+ for (int i = 0; i < Cheeses.sCheeseStrings.length; ++i) {
+ cheeseList.add(Cheeses.sCheeseStrings[i]);
+ }
+ final StableArrayAdapter adapter = new StableArrayAdapter(this,
+ android.R.layout.simple_list_item_1, cheeseList);
+ listview.setAdapter(adapter);
+
+ listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
+ final String item = (String) parent.getItemAtPosition(position);
+ if (vpaCB.isChecked()) {
+ view.animate().setDuration(1000).alpha(0).
+ withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ cheeseList.remove(item);
+ adapter.notifyDataSetChanged();
+ view.setAlpha(1);
+ }
+ });
+ } else {
+ // Here's where the problem starts - this animation will animate a View object.
+ // But that View may get recycled if it is animated out of the container,
+ // and the animation will continue to fade a view that now contains unrelated
+ // content.
+ ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
+ anim.setDuration(1000);
+ if (setTransientStateCB.isChecked()) {
+ // Here's the correct way to do this: if you tell a view that it has
+ // transientState, then ListView ill avoid recycling it until the
+ // transientState flag is reset.
+ // A different approach is to use ViewPropertyAnimator, which sets the
+ // transientState flag internally.
+ view.setHasTransientState(true);
+ }
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ cheeseList.remove(item);
+ adapter.notifyDataSetChanged();
+ view.setAlpha(1);
+ if (setTransientStateCB.isChecked()) {
+ view.setHasTransientState(false);
+ }
+ }
+ });
+ anim.start();
+
+ }
+ }
+
+ });
+ }
+
+ private class StableArrayAdapter extends ArrayAdapter<String> {
+
+ HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
+
+ public StableArrayAdapter(Context context, int textViewResourceId,
+ List<String> objects) {
+ super(context, textViewResourceId, objects);
+ for (int i = 0; i < objects.size(); ++i) {
+ mIdMap.put(objects.get(i), i);
+ }
+ }
+
+ @Override
+ public long getItemId(int position) {
+ String item = getItem(position);
+ return mIdMap.get(item);
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ }
+
+}
diff --git a/samples/devbytes/animation/PictureViewer/AndroidManifest.xml b/samples/devbytes/animation/PictureViewer/AndroidManifest.xml
new file mode 100644
index 0000000..6cb909e
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.pictureviewer"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.pictureviewer.PictureViewer"
+ android:label="@string/title_activity_picture_viewer" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg
new file mode 100644
index 0000000..9745818
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg
new file mode 100644
index 0000000..db8731f
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg
new file mode 100644
index 0000000..b240b3a
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg
new file mode 100644
index 0000000..4de9292
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml b/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml
new file mode 100644
index 0000000..599c770
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml
@@ -0,0 +1,35 @@
+<!-- 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:background="#000"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <ImageView
+ android:id="@+id/prevImageView"
+ android:adjustViewBounds="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+ <ImageView
+ android:id="@+id/nextImageView"
+ android:adjustViewBounds="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+</FrameLayout>
diff --git a/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml b/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/PictureViewer/res/values-v14/styles.xml b/samples/devbytes/animation/PictureViewer/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/PictureViewer/res/values/strings.xml b/samples/devbytes/animation/PictureViewer/res/values/strings.xml
new file mode 100644
index 0000000..5ed396b
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values/strings.xml
@@ -0,0 +1,20 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">PictureViewer</string>
+ <string name="title_activity_picture_viewer">PictureViewer</string>
+
+</resources>
diff --git a/samples/devbytes/animation/PictureViewer/res/values/styles.xml b/samples/devbytes/animation/PictureViewer/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/PictureViewer/src/com/example/android/pictureviewer/PictureViewer.java b/samples/devbytes/animation/PictureViewer/src/com/example/android/pictureviewer/PictureViewer.java
new file mode 100644
index 0000000..e1cb4dd
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/src/com/example/android/pictureviewer/PictureViewer.java
@@ -0,0 +1,97 @@
+/*
+ * 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.pictureviewer;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * This example shows how to use ViewPropertyAnimator to get a cross-fade effect as new
+ * bitmaps get installed in an ImageView.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=9XbKMUtVnJA.
+ */
+public class PictureViewer extends Activity {
+
+ int mCurrentDrawable = 0;
+ int drawableIDs[] = {
+ R.drawable.p1,
+ R.drawable.p2,
+ R.drawable.p3,
+ R.drawable.p4,
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_picture_viewer);
+
+ // This app works by having two views, which get faded in/out for the cross-fade effect
+ final ImageView prevImageView = (ImageView) findViewById(R.id.prevImageView);
+ final ImageView nextImageView = (ImageView) findViewById(R.id.nextImageView);
+ prevImageView.setBackgroundColor(Color.TRANSPARENT);
+ nextImageView.setBackgroundColor(Color.TRANSPARENT);
+
+ // Setup default ViewPropertyAnimator durations for the two ImageViews
+ prevImageView.animate().setDuration(1000);
+ nextImageView.animate().setDuration(1000);
+
+ // NOte that a real app would do this more robustly, and not just load all possible
+ // bitmaps at onCreate() time.
+ final BitmapDrawable drawables[] = new BitmapDrawable[drawableIDs.length];
+ for (int i = 0; i < drawableIDs.length; ++i) {
+ Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
+ drawableIDs[i]);
+ drawables[i] = new BitmapDrawable(getResources(), bitmap);
+ }
+ prevImageView.setImageDrawable(drawables[0]);
+ nextImageView.setImageDrawable(drawables[1]);
+
+ prevImageView.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ // Use ViewPropertyAnimator to fade the previous imageView out and the next one in
+ prevImageView.animate().alpha(0).withLayer();
+ nextImageView.animate().alpha(1).withLayer().
+ withEndAction(new Runnable() {
+ // When the animation ends, set up references to change the prev/next
+ // associations
+ @Override
+ public void run() {
+ mCurrentDrawable =
+ (mCurrentDrawable + 1) % drawables.length;
+ int nextDrawableIndex =
+ (mCurrentDrawable + 1) % drawables.length;
+ prevImageView.setImageDrawable(drawables[mCurrentDrawable]);
+ nextImageView.setImageDrawable(drawables[nextDrawableIndex]);
+ nextImageView.setAlpha(0f);
+ prevImageView.setAlpha(1f);
+ }
+ });
+ }
+ });
+ }
+
+}
diff --git a/samples/devbytes/animation/PropertyAnimations/AndroidManifest.xml b/samples/devbytes/animation/PropertyAnimations/AndroidManifest.xml
new file mode 100644
index 0000000..977d29e
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.propertyanimations"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="14"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.propertyanimations.PropertyAnimations"
+ android:label="@string/title_activity_property_animations" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/animator/combo.xml b/samples/devbytes/animation/PropertyAnimations/res/animator/combo.xml
new file mode 100644
index 0000000..6ae8ca0
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/combo.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:ordering="sequentially">
+ <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="alpha"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="0"/>
+ <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="translationX"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="800"/>
+
+ <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="rotation"
+ android:duration="300"
+ android:valueFrom="0"
+ android:valueTo="360"/>
+
+ <set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="2"/>
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="2"/>
+ </set>
+</set>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/animator/fade.xml b/samples/devbytes/animation/PropertyAnimations/res/animator/fade.xml
new file mode 100644
index 0000000..c27c6af
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/fade.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="alpha"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="0"/>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/animator/move.xml b/samples/devbytes/animation/PropertyAnimations/res/animator/move.xml
new file mode 100644
index 0000000..aaac09a
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/move.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="translationX"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="800"/>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/animator/scale.xml b/samples/devbytes/animation/PropertyAnimations/res/animator/scale.xml
new file mode 100644
index 0000000..7bbe0a9
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/scale.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="2"/>
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:repeatCount="1"
+ android:repeatMode="reverse"
+ android:duration="300"
+ android:valueTo="2"/>
+</set>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/animator/spin.xml b/samples/devbytes/animation/PropertyAnimations/res/animator/spin.xml
new file mode 100644
index 0000000..64fdc36
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/spin.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:duration="300"
+ android:valueTo="360"/>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/PropertyAnimations/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/PropertyAnimations/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/PropertyAnimations/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/PropertyAnimations/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/PropertyAnimations/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/PropertyAnimations/res/layout/activity_property_animations.xml b/samples/devbytes/animation/PropertyAnimations/res/layout/activity_property_animations.xml
new file mode 100644
index 0000000..add0a54
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/layout/activity_property_animations.xml
@@ -0,0 +1,58 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <CheckBox
+ android:id="@+id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/use_animation_resources" />
+
+ <Button
+ android:id="@+id/alphaButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/alpha" />
+
+ <Button
+ android:id="@+id/translateButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/translate" />
+
+ <Button
+ android:id="@+id/rotateButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/rotate" />
+
+ <Button
+ android:id="@+id/scaleButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/scale" />
+
+ <Button
+ android:id="@+id/setButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/set" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/values-v11/styles.xml b/samples/devbytes/animation/PropertyAnimations/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/values-v14/styles.xml b/samples/devbytes/animation/PropertyAnimations/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/values/strings.xml b/samples/devbytes/animation/PropertyAnimations/res/values/strings.xml
new file mode 100644
index 0000000..3a872d8
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values/strings.xml
@@ -0,0 +1,26 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">PropertyAnimations</string>
+ <string name="title_activity_property_animations">PropertyAnimations</string>
+ <string name="use_animation_resources">Use Animation Resources</string>
+ <string name="alpha">Alpha</string>
+ <string name="translate">Translate</string>
+ <string name="rotate">Rotate</string>
+ <string name="scale">Scale</string>
+ <string name="set">Set</string>
+
+</resources>
diff --git a/samples/devbytes/animation/PropertyAnimations/res/values/styles.xml b/samples/devbytes/animation/PropertyAnimations/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/PropertyAnimations/src/com/example/android/propertyanimations/PropertyAnimations.java b/samples/devbytes/animation/PropertyAnimations/src/com/example/android/propertyanimations/PropertyAnimations.java
new file mode 100644
index 0000000..89480f6
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/src/com/example/android/propertyanimations/PropertyAnimations.java
@@ -0,0 +1,111 @@
+/*
+ * 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.propertyanimations;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+
+/**
+ * This example shows how to use property animations, specifically ObjectAnimator, to perform
+ * various view animations. Compare this approach to that of the ViewAnimations demo, which
+ * shows how to achieve similar effects using the pre-3.0 animation APIs.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=3UbJhmkeSig.
+ */
+public class PropertyAnimations extends Activity {
+
+ CheckBox mCheckBox;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_property_animations);
+
+ mCheckBox = (CheckBox) findViewById(R.id.checkbox);
+ final Button alphaButton = (Button) findViewById(R.id.alphaButton);
+ final Button translateButton = (Button) findViewById(R.id.translateButton);
+ final Button rotateButton = (Button) findViewById(R.id.rotateButton);
+ final Button scaleButton = (Button) findViewById(R.id.scaleButton);
+ final Button setButton = (Button) findViewById(R.id.setButton);
+
+ // Fade the button out and back in
+ ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(alphaButton,
+ View.ALPHA, 0);
+ alphaAnimation.setRepeatCount(1);
+ alphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
+
+ // Move the button over to the right and then back
+ ObjectAnimator translateAnimation =
+ ObjectAnimator.ofFloat(translateButton, View.TRANSLATION_X, 800);
+ translateAnimation.setRepeatCount(1);
+ translateAnimation.setRepeatMode(ValueAnimator.REVERSE);
+
+ // Spin the button around in a full circle
+ ObjectAnimator rotateAnimation =
+ ObjectAnimator.ofFloat(rotateButton, View.ROTATION, 360);
+ rotateAnimation.setRepeatCount(1);
+ rotateAnimation.setRepeatMode(ValueAnimator.REVERSE);
+
+ // Scale the button in X and Y. Note the use of PropertyValuesHolder to animate
+ // multiple properties on the same object in parallel.
+ PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.SCALE_X, 2);
+ PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 2);
+ ObjectAnimator scaleAnimation =
+ ObjectAnimator.ofPropertyValuesHolder(scaleButton, pvhX, pvhY);
+ scaleAnimation.setRepeatCount(1);
+ scaleAnimation.setRepeatMode(ValueAnimator.REVERSE);
+
+ // Run the animations above in sequence
+ AnimatorSet setAnimation = new AnimatorSet();
+ setAnimation.play(translateAnimation).after(alphaAnimation).before(rotateAnimation);
+ setAnimation.play(rotateAnimation).before(scaleAnimation);
+
+ setupAnimation(alphaButton, alphaAnimation, R.animator.fade);
+ setupAnimation(translateButton, translateAnimation, R.animator.move);
+ setupAnimation(rotateButton, rotateAnimation, R.animator.spin);
+ setupAnimation(scaleButton, scaleAnimation, R.animator.scale);
+ setupAnimation(setButton, setAnimation, R.animator.combo);
+
+ }
+
+ private void setupAnimation(View view, final Animator animation, final int animationID) {
+ view.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ // If the button is checked, load the animation from the given resource
+ // id instead of using the passed-in animation parameter. See the xml files
+ // for the details on those animations.
+ if (mCheckBox.isChecked()) {
+ Animator anim = AnimatorInflater.loadAnimator(PropertyAnimations.this, animationID);
+ anim.setTarget(v);
+ anim.start();
+ return;
+ }
+ animation.start();
+ }
+ });
+ }
+}
diff --git a/samples/devbytes/animation/ViewAnimations/AndroidManifest.xml b/samples/devbytes/animation/ViewAnimations/AndroidManifest.xml
new file mode 100644
index 0000000..d713f4c
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.viewanimations"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.viewanimations.ViewAnimations"
+ android:label="@string/title_activity_view_animations" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/ViewAnimations/res/anim/alpha_anim.xml b/samples/devbytes/animation/ViewAnimations/res/anim/alpha_anim.xml
new file mode 100644
index 0000000..2afcb6c
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/alpha_anim.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="500" />
diff --git a/samples/devbytes/animation/ViewAnimations/res/anim/rotate_anim.xml b/samples/devbytes/animation/ViewAnimations/res/anim/rotate_anim.xml
new file mode 100644
index 0000000..622bd32
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/rotate_anim.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:toDegrees="360"
+ android:pivotX="50%" android:pivotY="50%"
+ android:duration="1000"/>
diff --git a/samples/devbytes/animation/ViewAnimations/res/anim/scale_anim.xml b/samples/devbytes/animation/ViewAnimations/res/anim/scale_anim.xml
new file mode 100644
index 0000000..1b10705
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/scale_anim.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<scale xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromXScale="1"
+ android:fromYScale="1"
+ android:toXScale="2"
+ android:toYScale="2"
+ android:duration="1000"/>
diff --git a/samples/devbytes/animation/ViewAnimations/res/anim/set_anim.xml b/samples/devbytes/animation/ViewAnimations/res/anim/set_anim.xml
new file mode 100644
index 0000000..567e3d5
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/set_anim.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="1000" />
+ <rotate android:toDegrees="180"
+ android:duration="1000"/>
+ <scale android:toXScale="2"
+ android:toYScale="2"
+ android:duration="1000"/>
+ <translate android:fromXDelta="0" android:toXDelta="100%p"
+ android:fromYDelta="0" android:toYDelta="100"
+ android:duration="1000" />
+</set>
diff --git a/samples/devbytes/animation/ViewAnimations/res/anim/translate_anim.xml b/samples/devbytes/animation/ViewAnimations/res/anim/translate_anim.xml
new file mode 100644
index 0000000..e33e8f1
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/translate_anim.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromXDelta="0" android:toXDelta="100%p"
+ android:fromYDelta="0" android:toYDelta="100"
+ android:duration="1000" />
diff --git a/samples/devbytes/animation/ViewAnimations/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/ViewAnimations/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/ViewAnimations/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/ViewAnimations/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/ViewAnimations/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/ViewAnimations/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/ViewAnimations/res/layout/activity_view_animations.xml b/samples/devbytes/animation/ViewAnimations/res/layout/activity_view_animations.xml
new file mode 100644
index 0000000..3338135
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/layout/activity_view_animations.xml
@@ -0,0 +1,57 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <CheckBox
+ android:id="@+id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/use_animation_resources" />
+
+ <Button
+ android:id="@+id/alphaButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/alpha" />
+
+ <Button
+ android:id="@+id/translateButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/translate" />
+
+ <Button
+ android:id="@+id/rotateButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/rotate" />
+
+ <Button
+ android:id="@+id/scaleButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/scale" />
+
+ <Button
+ android:id="@+id/setButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/set" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/ViewAnimations/res/values-v11/styles.xml b/samples/devbytes/animation/ViewAnimations/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/ViewAnimations/res/values-v14/styles.xml b/samples/devbytes/animation/ViewAnimations/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/ViewAnimations/res/values/strings.xml b/samples/devbytes/animation/ViewAnimations/res/values/strings.xml
new file mode 100644
index 0000000..a43f1af
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values/strings.xml
@@ -0,0 +1,26 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">ViewAnimations</string>
+ <string name="title_activity_view_animations">ViewAnimations</string>
+ <string name="alpha">Alpha</string>
+ <string name="translate">Translate</string>
+ <string name="rotate">Rotate</string>
+ <string name="scale">Scale</string>
+ <string name="set">Set</string>
+ <string name="use_animation_resources">Use Animation Resources</string>
+
+</resources>
diff --git a/samples/devbytes/animation/ViewAnimations/res/values/styles.xml b/samples/devbytes/animation/ViewAnimations/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/ViewAnimations/src/com/example/android/viewanimations/ViewAnimations.java b/samples/devbytes/animation/ViewAnimations/src/com/example/android/viewanimations/ViewAnimations.java
new file mode 100644
index 0000000..50d98a6
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/src/com/example/android/viewanimations/ViewAnimations.java
@@ -0,0 +1,104 @@
+/*
+ * 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.viewanimations;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AnimationUtils;
+import android.view.animation.RotateAnimation;
+import android.view.animation.ScaleAnimation;
+import android.view.animation.TranslateAnimation;
+import android.widget.Button;
+import android.widget.CheckBox;
+
+/**
+ * This example shows how to use pre-3.0 view Animation classes to create various animated UI
+ * effects. See also the demo PropertyAnimations, which shows how this is done using the new
+ * ObjectAnimator API introduced in Android 3.0.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=_UWXqFBF86U.
+ */
+public class ViewAnimations extends Activity {
+
+ CheckBox mCheckBox;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_view_animations);
+
+ mCheckBox = (CheckBox) findViewById(R.id.checkbox);
+ final Button alphaButton = (Button) findViewById(R.id.alphaButton);
+ final Button translateButton = (Button) findViewById(R.id.translateButton);
+ final Button rotateButton = (Button) findViewById(R.id.rotateButton);
+ final Button scaleButton = (Button) findViewById(R.id.scaleButton);
+ final Button setButton = (Button) findViewById(R.id.setButton);
+
+ // Fade the button out and back in
+ final AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
+ alphaAnimation.setDuration(1000);
+
+ // Move the button over and then back
+ final TranslateAnimation translateAnimation =
+ new TranslateAnimation(Animation.ABSOLUTE, 0,
+ Animation.RELATIVE_TO_PARENT, 1,
+ Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 100);
+ translateAnimation.setDuration(1000);
+
+ // Spin the button around in a full circle
+ final RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
+ Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f);
+ rotateAnimation.setDuration(1000);
+
+ // Scale the button in X and Y.
+ final ScaleAnimation scaleAnimation = new ScaleAnimation(1, 2, 1, 2);
+ scaleAnimation.setDuration(1000);
+
+ // Run the animations above in sequence on the final button. Looks horrible.
+ final AnimationSet setAnimation = new AnimationSet(true);
+ setAnimation.addAnimation(alphaAnimation);
+ setAnimation.addAnimation(translateAnimation);
+ setAnimation.addAnimation(rotateAnimation);
+ setAnimation.addAnimation(scaleAnimation);
+
+ setupAnimation(alphaButton, alphaAnimation, R.anim.alpha_anim);
+ setupAnimation(translateButton, translateAnimation, R.anim.translate_anim);
+ setupAnimation(rotateButton, rotateAnimation, R.anim.rotate_anim);
+ setupAnimation(scaleButton, scaleAnimation, R.anim.scale_anim);
+ setupAnimation(setButton, setAnimation, R.anim.set_anim);
+
+ }
+
+ private void setupAnimation(View view, final Animation animation,
+ final int animationID) {
+ view.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ // If the button is checked, load the animation from the given resource
+ // id instead of using the passed-in animation paramter. See the xml files
+ // for the details on those animations.
+ v.startAnimation(mCheckBox.isChecked() ?
+ AnimationUtils.loadAnimation(ViewAnimations.this, animationID) :
+ animation);
+ }
+ });
+ }
+}
diff --git a/samples/devbytes/animation/WindowAnimations/AndroidManifest.xml b/samples/devbytes/animation/WindowAnimations/AndroidManifest.xml
new file mode 100644
index 0000000..6f111eb
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/AndroidManifest.xml
@@ -0,0 +1,57 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.windowanimations"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".WindowAnimations"
+ android:label="@string/title_activity_window_animations" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".AnimatedSubActivity"
+ android:label="@string/title_activity_window_anim_sub" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="com.example.android.windowanimations.SubActivity"
+ android:label="@string/title_activity_sub" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_left.xml b/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_left.xml
new file mode 100644
index 0000000..8321f1f
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_left.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromXDelta="100%p" android:toXDelta="0"
+ android:duration="500" />
diff --git a/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_right.xml b/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_right.xml
new file mode 100644
index 0000000..c3f2920
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_right.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromXDelta="-50%p" android:toXDelta="0"
+ android:duration="500" />
diff --git a/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_left.xml b/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_left.xml
new file mode 100644
index 0000000..6c93ced
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_left.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromXDelta="0" android:toXDelta="-50%p"
+ android:duration="500" />
diff --git a/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_right.xml b/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_right.xml
new file mode 100644
index 0000000..2057345
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_right.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromXDelta="0" android:toXDelta="100%p"
+ android:duration="500" />
diff --git a/samples/devbytes/animation/WindowAnimations/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/WindowAnimations/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/WindowAnimations/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/WindowAnimations/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/WindowAnimations/res/drawable-nodpi/thumbnail.png b/samples/devbytes/animation/WindowAnimations/res/drawable-nodpi/thumbnail.png
new file mode 100644
index 0000000..e1722f3
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/drawable-nodpi/thumbnail.png
Binary files differ
diff --git a/samples/devbytes/animation/WindowAnimations/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/WindowAnimations/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/animation/WindowAnimations/res/layout/activity_sub.xml b/samples/devbytes/animation/WindowAnimations/res/layout/activity_sub.xml
new file mode 100644
index 0000000..3864752
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/layout/activity_sub.xml
@@ -0,0 +1,30 @@
+<!-- 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:background="#888"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="@string/activity_text"
+ android:textSize="40dip"
+ tools:context=".SubActivity" />
+
+</RelativeLayout>
diff --git a/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_anim_sub.xml b/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_anim_sub.xml
new file mode 100644
index 0000000..709e539
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_anim_sub.xml
@@ -0,0 +1,30 @@
+<!-- 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:background="#888"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="@string/activity_text"
+ android:textSize="40dip"
+ tools:context=".WindowAnimSubActivity" />
+
+</RelativeLayout>
diff --git a/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_animations.xml b/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_animations.xml
new file mode 100644
index 0000000..8d653ea
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_animations.xml
@@ -0,0 +1,44 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <Button android:id="@+id/defaultButton"
+ android:text="Default Animations"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:context=".WindowAnimations" />
+
+ <Button android:id="@+id/translateButton"
+ android:text="Translate Animations"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:context=".WindowAnimations" />
+
+ <Button android:id="@+id/scaleButton"
+ android:text="Scale Animations"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:context=".WindowAnimations" />
+
+ <ImageView android:id="@+id/thumbnail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/thumbnail" />
+
+</LinearLayout>
diff --git a/samples/devbytes/animation/WindowAnimations/res/values-v11/styles.xml b/samples/devbytes/animation/WindowAnimations/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/WindowAnimations/res/values-v14/styles.xml b/samples/devbytes/animation/WindowAnimations/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/animation/WindowAnimations/res/values/strings.xml b/samples/devbytes/animation/WindowAnimations/res/values/strings.xml
new file mode 100644
index 0000000..39fc436
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values/strings.xml
@@ -0,0 +1,25 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">WindowAnimations</string>
+ <string name="activity_text">Sub-Activity</string>
+ <string name="menu_settings">Settings</string>
+ <string name="title_activity_window_animations">WindowAnimations</string>
+ <string name="title_activity_window_anim_sub">WindowAnimSubActivity</string>
+ <string name="hello_world">Hello world!</string>
+ <string name="title_activity_sub">SubActivity</string>
+
+</resources>
diff --git a/samples/devbytes/animation/WindowAnimations/res/values/styles.xml b/samples/devbytes/animation/WindowAnimations/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/AnimatedSubActivity.java b/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/AnimatedSubActivity.java
new file mode 100644
index 0000000..ad26248
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/AnimatedSubActivity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.windowanimations;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * See WindowAnimations.java for comments on the overall application.
+ *
+ * This is a sub-activity which provides custom animation behavior. When this activity
+ * is exited, the user will see the behavior specified in the overridePendingTransition() call.
+ */
+public class AnimatedSubActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_window_anim_sub);
+ }
+
+ @Override
+ public void finish() {
+ super.finish();
+ overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right);
+ }
+}
diff --git a/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/SubActivity.java b/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/SubActivity.java
new file mode 100644
index 0000000..61b0a68
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/SubActivity.java
@@ -0,0 +1,35 @@
+/*
+ * 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.windowanimations;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * See WindowAnimations.java for comments on the overall application.
+ *
+ * This is a sub-activity which does not provide any custom animation. Exiting this
+ * sub-activity therefore gets the default system behavior for window animations.
+ */
+public class SubActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_sub);
+ }
+}
diff --git a/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/WindowAnimations.java b/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/WindowAnimations.java
new file mode 100644
index 0000000..a5c76b1
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/src/com/example/android/windowanimations/WindowAnimations.java
@@ -0,0 +1,106 @@
+/*
+ * 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.windowanimations;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+
+/**
+ * This example shows how to create custom Window animations to animate between different
+ * sub-activities.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=Ho8vk61lVIU.
+ */
+public class WindowAnimations extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_window_animations);
+
+ final Button defaultButton = (Button) findViewById(R.id.defaultButton);
+ final Button translateButton = (Button) findViewById(R.id.translateButton);
+ final Button scaleButton = (Button) findViewById(R.id.scaleButton);
+ final ImageView thumbnail = (ImageView) findViewById(R.id.thumbnail);
+
+ // By default, launching a sub-activity uses the system default for window animations
+ defaultButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent subActivity = new Intent(WindowAnimations.this,
+ SubActivity.class);
+ startActivity(subActivity);
+ }
+ });
+
+ // Custom animations allow us to do things like slide the next activity in as we
+ // slide this activity out
+ translateButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Using the AnimatedSubActivity also allows us to animate exiting that
+ // activity - see that activity for details
+ Intent subActivity = new Intent(WindowAnimations.this,
+ AnimatedSubActivity.class);
+ // The enter/exit animations for the two activities are specified by xml resources
+ Bundle translateBundle =
+ ActivityOptions.makeCustomAnimation(WindowAnimations.this,
+ R.anim.slide_in_left, R.anim.slide_out_left).toBundle();
+ startActivity(subActivity, translateBundle);
+ }
+ });
+
+ // Starting in Jellybean, you can provide an animation that scales up the new
+ // activity from a given source rectangle
+ scaleButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent subActivity = new Intent(WindowAnimations.this,
+ AnimatedSubActivity.class);
+ Bundle scaleBundle = ActivityOptions.makeScaleUpAnimation(
+ v, 0, 0, v.getWidth(), v.getHeight()).toBundle();
+ startActivity(subActivity, scaleBundle);
+ }
+ });
+
+ // Starting in Jellybean, you can also provide an animation that scales up the new
+ // activity from a given bitmap, cross-fading between the starting and ending
+ // representations. Here, we scale up from a thumbnail image of the final sub-activity
+ thumbnail.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ BitmapDrawable drawable = (BitmapDrawable) thumbnail.getDrawable();
+ Bitmap bm = drawable.getBitmap();
+ Intent subActivity = new Intent(WindowAnimations.this, AnimatedSubActivity.class);
+ Bundle scaleBundle = ActivityOptions.makeThumbnailScaleUpAnimation(
+ thumbnail, bm, 0, 0).toBundle();
+ startActivity(subActivity, scaleBundle);
+ }
+ });
+
+
+ }
+
+}
diff --git a/samples/devbytes/graphics/BitmapAllocation/AndroidManifest.xml b/samples/devbytes/graphics/BitmapAllocation/AndroidManifest.xml
new file mode 100644
index 0000000..5ffcb29
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.bitmapallocation"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="15"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.bitmapallocation.BitmapAllocation"
+ android:label="@string/title_activity_bitmap_allocation" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/graphics/BitmapAllocation/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/graphics/BitmapAllocation/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/a.jpg b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/a.jpg
new file mode 100644
index 0000000..23dc04a
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/a.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/b.jpg b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/b.jpg
new file mode 100644
index 0000000..b6beca2
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/b.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/c.jpg b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/c.jpg
new file mode 100644
index 0000000..d608554
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/c.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/d.jpg b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/d.jpg
new file mode 100644
index 0000000..f1ff9f5
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/d.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/e.jpg b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/e.jpg
new file mode 100644
index 0000000..580a0d1
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/e.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/f.jpg b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/f.jpg
new file mode 100644
index 0000000..bc14d12
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/f.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/graphics/BitmapAllocation/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/layout/activity_bitmap_allocation.xml b/samples/devbytes/graphics/BitmapAllocation/res/layout/activity_bitmap_allocation.xml
new file mode 100644
index 0000000..458178b
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/layout/activity_bitmap_allocation.xml
@@ -0,0 +1,38 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <CheckBox
+ android:id="@+id/checkbox"
+ android:text="@string/reuse_bitmap"
+ android:checked="false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <TextView
+ android:id="@+id/loadDuration"
+ android:textSize="30sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <ImageView
+ android:id="@+id/imageview"
+ android:adjustViewBounds="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/values-v11/styles.xml b/samples/devbytes/graphics/BitmapAllocation/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/values-v14/styles.xml b/samples/devbytes/graphics/BitmapAllocation/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/values/strings.xml b/samples/devbytes/graphics/BitmapAllocation/res/values/strings.xml
new file mode 100644
index 0000000..bf598f9
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">BitmapAllocation</string>
+ <string name="title_activity_bitmap_allocation">BitmapAllocation</string>
+ <string name="reuse_bitmap">Reuse Bitmap</string>
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapAllocation/res/values/styles.xml b/samples/devbytes/graphics/BitmapAllocation/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapAllocation/src/com/example/android/bitmapallocation/BitmapAllocation.java b/samples/devbytes/graphics/BitmapAllocation/src/com/example/android/bitmapallocation/BitmapAllocation.java
new file mode 100644
index 0000000..cc6b1e0
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/src/com/example/android/bitmapallocation/BitmapAllocation.java
@@ -0,0 +1,99 @@
+/*
+ * 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.bitmapallocation;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * This example shows how to speed up bitmap loading and reduce garbage collection
+ * by reusing existing bitmaps.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com,
+ * or on YouTube at https://www.youtube.com/watch?v=rsQet4nBVi8.
+ */
+public class BitmapAllocation extends Activity {
+
+ // There are some assumptions in this demo app that don't carry over well to the real world:
+ // it assumes that all bitmaps are the same size and that loading all bitmaps as the activity
+ // starts is good enough. A real application would be take a more flexible and robust
+ // approach. But these assumptions are good enough for the purposes of this tutorial,
+ // which is about reusing existing bitmaps of the same size.
+
+ int mCurrentIndex = 0;
+ Bitmap mCurrentBitmap = null;
+ BitmapFactory.Options mBitmapOptions;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bitmap_allocation);
+
+ final int[] imageIDs = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d,
+ R.drawable.e, R.drawable.f};
+
+ final CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox);
+ final TextView durationTextview = (TextView) findViewById(R.id.loadDuration);
+ final ImageView imageview = (ImageView) findViewById(R.id.imageview);
+
+ // Create bitmap to be re-used, based on the size of one of the bitmaps
+ mBitmapOptions = new BitmapFactory.Options();
+ mBitmapOptions.inJustDecodeBounds = true;
+ BitmapFactory.decodeResource(getResources(), R.drawable.a, mBitmapOptions);
+ mCurrentBitmap = Bitmap.createBitmap(mBitmapOptions.outWidth,
+ mBitmapOptions.outHeight, Bitmap.Config.ARGB_8888);
+ mBitmapOptions.inJustDecodeBounds = false;
+ mBitmapOptions.inBitmap = mCurrentBitmap;
+ mBitmapOptions.inSampleSize = 1;
+ BitmapFactory.decodeResource(getResources(), R.drawable.a, mBitmapOptions);
+ imageview.setImageBitmap(mCurrentBitmap);
+
+ // When the user clicks on the image, load the next one in the list
+ imageview.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mCurrentIndex = (mCurrentIndex + 1) % imageIDs.length;
+ BitmapFactory.Options bitmapOptions = null;
+ if (checkbox.isChecked()) {
+ // Re-use the bitmap by using BitmapOptions.inBitmap
+ bitmapOptions = mBitmapOptions;
+ bitmapOptions.inBitmap = mCurrentBitmap;
+ }
+ long startTime = System.currentTimeMillis();
+ mCurrentBitmap = BitmapFactory.decodeResource(getResources(),
+ imageIDs[mCurrentIndex], bitmapOptions);
+ imageview.setImageBitmap(mCurrentBitmap);
+
+ // One way you can see the difference between reusing and not is through the
+ // timing reported here. But you can also see a huge impact in the garbage
+ // collector if you look at logcat with and without reuse. Avoiding garbage
+ // collection when possible, especially for large items like bitmaps,
+ // is always a good idea.
+ durationTextview.setText("Load took " +
+ (System.currentTimeMillis() - startTime));
+ }
+ });
+ }
+
+}
diff --git a/samples/devbytes/graphics/BitmapScaling/AndroidManifest.xml b/samples/devbytes/graphics/BitmapScaling/AndroidManifest.xml
new file mode 100644
index 0000000..f926a27
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.bitmapscaling"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="15" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.bitmapscaling.BitmapScaling"
+ android:label="@string/title_activity_bitmap_scaling" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/graphics/BitmapScaling/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/graphics/BitmapScaling/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapScaling/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/graphics/BitmapScaling/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapScaling/res/drawable-nodpi/jellybean_statue.jpg b/samples/devbytes/graphics/BitmapScaling/res/drawable-nodpi/jellybean_statue.jpg
new file mode 100644
index 0000000..9f5349a
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/drawable-nodpi/jellybean_statue.jpg
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapScaling/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/graphics/BitmapScaling/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/graphics/BitmapScaling/res/layout/activity_bitmap_scaling.xml b/samples/devbytes/graphics/BitmapScaling/res/layout/activity_bitmap_scaling.xml
new file mode 100644
index 0000000..d9556fc
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/layout/activity_bitmap_scaling.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TextView
+ android:text="@string/original_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <ImageView
+ android:id="@+id/originalImageHolder"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:text="@string/scaled_images"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <LinearLayout
+ android:id="@+id/scaledImageContainer"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/devbytes/graphics/BitmapScaling/res/values-v11/styles.xml b/samples/devbytes/graphics/BitmapScaling/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapScaling/res/values-v14/styles.xml b/samples/devbytes/graphics/BitmapScaling/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapScaling/res/values/strings.xml b/samples/devbytes/graphics/BitmapScaling/res/values/strings.xml
new file mode 100644
index 0000000..466f6ae
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values/strings.xml
@@ -0,0 +1,22 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">BitmapScaling</string>
+ <string name="title_activity_bitmap_scaling">BitmapScaling</string>
+ <string name="original_image">Original Image</string>
+ <string name="scaled_images">Scaled Images</string>
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapScaling/res/values/styles.xml b/samples/devbytes/graphics/BitmapScaling/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/graphics/BitmapScaling/src/com/example/android/bitmapscaling/BitmapScaling.java b/samples/devbytes/graphics/BitmapScaling/src/com/example/android/bitmapscaling/BitmapScaling.java
new file mode 100644
index 0000000..8ca5a31
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/src/com/example/android/bitmapscaling/BitmapScaling.java
@@ -0,0 +1,75 @@
+/*
+ * 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.bitmapscaling;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+
+/**
+ * This example shows how the use of BitmapOptions affects the resulting size of a loaded
+ * bitmap. Sub-sampling can speed up load times and reduce the need for large bitmaps
+ * in memory if your target bitmap size is much smaller, although it's good to understand
+ * that you can't get specific Bitmap sizes, but rather power-of-two reductions in sizes.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=12cB7gnL6po.
+ */
+public class BitmapScaling extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bitmap_scaling);
+
+ LinearLayout container = (LinearLayout) findViewById(R.id.scaledImageContainer);
+ ImageView originalImageView = (ImageView) findViewById(R.id.originalImageHolder);
+
+ Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.jellybean_statue);
+ originalImageView.setImageBitmap(bitmap);
+
+ for (int i = 2; i < 10; ++i) {
+ addScaledImageView(bitmap, i, container);
+ }
+ }
+
+ private void addScaledImageView(Bitmap original, int sampleSize, LinearLayout container) {
+
+ // inSampleSize tells the loader how much to scale the final image, which it does at
+ // load time by simply reading less pixels for every pixel value in the final bitmap.
+ // Note that it only scales by powers of two, so a value of two results in a bitmap
+ // 1/2 the size of the original and a value of four results in a bitmap 1/4 the original
+ // size. Intermediate values are rounded down, so a value of three results in a bitmap 1/2
+ // the original size.
+
+ BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
+ bitmapOptions.inSampleSize = sampleSize;
+
+ Bitmap scaledBitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.jellybean_statue, bitmapOptions);
+ ImageView scaledImageView = new ImageView(this);
+ scaledImageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+ scaledImageView.setImageBitmap(scaledBitmap);
+ container.addView(scaledImageView);
+ }
+}
diff --git a/samples/devbytes/ui/ListViewDeletion/AndroidManifest.xml b/samples/devbytes/ui/ListViewDeletion/AndroidManifest.xml
new file mode 100644
index 0000000..ba48e97
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.listviewdeletion"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.listviewdeletion.ListViewDeletion"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/ui/ListViewDeletion/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/ui/ListViewDeletion/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/ui/ListViewDeletion/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/ui/ListViewDeletion/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/ui/ListViewDeletion/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/ui/ListViewDeletion/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/ui/ListViewDeletion/res/layout/activity_list_view_deletion.xml b/samples/devbytes/ui/ListViewDeletion/res/layout/activity_list_view_deletion.xml
new file mode 100644
index 0000000..4b98347
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/layout/activity_list_view_deletion.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".ListViewAnimations" >
+
+ <CheckBox
+ android:id="@+id/usePositionsCB"
+ android:text="@string/use_positions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button
+ android:id="@+id/deleteButton"
+ android:text="@string/delete_selected"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ListView
+ android:id="@+id/listview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/samples/devbytes/ui/ListViewDeletion/res/values-v11/styles.xml b/samples/devbytes/ui/ListViewDeletion/res/values-v11/styles.xml
new file mode 100644
index 0000000..139d283
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values-v11/styles.xml
@@ -0,0 +1,25 @@
+<!-- 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.
+-->
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml b/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml
new file mode 100644
index 0000000..8ac4522
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml
@@ -0,0 +1,26 @@
+<!-- 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.
+-->
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml b/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml
new file mode 100644
index 0000000..7801d60
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!-- 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.
+-->
+<resources>
+
+ <string name="app_name">ListViewDeletion</string>
+ <string name="use_positions">Use Positions</string>
+ <string name="delete_selected">Delete Selected</string>
+
+</resources>
diff --git a/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml b/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml
new file mode 100644
index 0000000..f9460a7
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml
@@ -0,0 +1,34 @@
+<!-- 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.
+-->
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
diff --git a/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/Cheeses.java b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/Cheeses.java
new file mode 100644
index 0000000..4bdd858
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/Cheeses.java
@@ -0,0 +1,154 @@
+/*
+ * 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.listviewdeletion;
+
+public class Cheeses {
+
+ public static final String[] sCheeseStrings = {
+ "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+ "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+ "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+ "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+ "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+ "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+ "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+ "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+ "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+ "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+ "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+ "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+ "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+ "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+ "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+ "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+ "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+ "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+ "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+ "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+ "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+ "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+ "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+ "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+ "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+ "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+ "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+ "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+ "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+ "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+ "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+ "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+ "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+ "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+ "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+ "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+ "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+ "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+ "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+ "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+ "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+ "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+ "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+ "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+ "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+ "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+ "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+ "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+ "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+ "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+ "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+ "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+ "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+ "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+ "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+ "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+ "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+ "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+ "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+ "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+ "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+ "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+ "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+ "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+ "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+ "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+ "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+ "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+ "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+ "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+ "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+ "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+ "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+ "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+ "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+ "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+ "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+ "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+ "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+ "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+ "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+ "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+ "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+ "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+ "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+ "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+ "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+ "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+ "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+ "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+ "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+ "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+ "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+ "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+ "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+ "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+ "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+ "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+ "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+ "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+ "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+ "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+ "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+ "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+ "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+ "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+ "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+ "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+ "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+ "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+ "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+ "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+ "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+ "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+ "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+ "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+ "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+ "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+ "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+ "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+ "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+ "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+ "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+ "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+ "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+ "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+ "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+ "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+ "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+ "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+ };
+
+}
diff --git a/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/ListViewDeletion.java b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/ListViewDeletion.java
new file mode 100644
index 0000000..d353823
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/ListViewDeletion.java
@@ -0,0 +1,175 @@
+/*
+ * 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.listviewdeletion;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.SparseBooleanArray;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.ListView;
+
+/**
+ * This example shows how animating ListView views can lead to artifacts if those views are
+ * recycled before you animate them.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=NewCSg2JKLk.
+ */
+public class ListViewDeletion extends Activity {
+
+ final ArrayList<View> mCheckedViews = new ArrayList<View>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_list_view_deletion);
+
+ final Button deleteButton = (Button) findViewById(R.id.deleteButton);
+ final CheckBox usePositionsCB = (CheckBox) findViewById(R.id.usePositionsCB);
+ final ListView listview = (ListView) findViewById(R.id.listview);
+ final ArrayList<String> cheeseList = new ArrayList<String>();
+ for (int i = 0; i < Cheeses.sCheeseStrings.length; ++i) {
+ cheeseList.add(Cheeses.sCheeseStrings[i]);
+ }
+ final StableArrayAdapter adapter = new StableArrayAdapter(this,
+ android.R.layout.simple_list_item_multiple_choice, cheeseList);
+ listview.setAdapter(adapter);
+ listview.setItemsCanFocus(false);
+ listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+
+ // Clicking the delete button fades out the currently selected views
+ deleteButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SparseBooleanArray checkedItems = listview.getCheckedItemPositions();
+ int numCheckedItems = checkedItems.size();
+ for (int i = numCheckedItems - 1; i >= 0; --i) {
+ if (!checkedItems.valueAt(i)) {
+ continue;
+ }
+ int position = checkedItems.keyAt(i);
+ final String item = adapter.getItem(position);
+ if (!usePositionsCB.isChecked()) {
+ // Remove the actual data after the time period that we're going to run
+ // the fading animation
+ v.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ adapter.remove(item);
+ }
+ }, 300);
+ } else {
+ // This is the correct way to do this: first wee whether the item is
+ // actually visible, and don't bother animating it if it's not.
+ // Next, get the view associated with the item at the time of deletion
+ // (not some old view chosen when the item was clicked).
+ mCheckedViews.clear();
+ int positionOnScreen = position - listview.getFirstVisiblePosition();
+ if (positionOnScreen >= 0 &&
+ positionOnScreen < listview.getChildCount()) {
+ final View view = listview.getChildAt(positionOnScreen);
+ // All set to fade this view out. Using ViewPropertyAnimator accounts
+ // for possible recycling of views during the animation itself
+ // (see the ListViewAnimations example for more on this).
+ view.animate().alpha(0).withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ view.setAlpha(1);
+ adapter.remove(item);
+ }
+ });
+ } else {
+ // Not animating the view, but don't delete it yet to avoid making the
+ // list shift due to offscreen deletions
+ v.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ adapter.remove(item);
+ }
+ }, 300);
+ }
+ }
+ }
+ // THIS IS THE WRONG WAY TO DO THIS
+ // We're basing our decision of the views to be animated based on outdated
+ // information at selection time. Then we're going ahead and running an animation
+ // on those views even when the selected items might not even be in view (in which
+ // case we'll probably be mistakenly fading out something else that is on the
+ // screen and is re-using that recycled view).
+ for (int i = 0; i < mCheckedViews.size(); ++i) {
+ final View checkedView = mCheckedViews.get(i);
+ checkedView.animate().alpha(0).withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ checkedView.setAlpha(1);
+ }
+ });
+ }
+ mCheckedViews.clear();
+ adapter.notifyDataSetChanged();
+ }
+ });
+
+ listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
+ boolean checked = listview.isItemChecked(position);
+ if (checked) {
+ mCheckedViews.add(view);
+ } else {
+ mCheckedViews.remove(view);
+ }
+ }
+ });
+ }
+
+ private class StableArrayAdapter extends ArrayAdapter<String> {
+
+ HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
+
+ public StableArrayAdapter(Context context, int textViewResourceId,
+ List<String> objects) {
+ super(context, textViewResourceId, objects);
+ for (int i = 0; i < objects.size(); ++i) {
+ mIdMap.put(objects.get(i), i);
+ }
+ }
+
+ @Override
+ public long getItemId(int position) {
+ String item = getItem(position);
+ return mIdMap.get(item);
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ }
+
+}
diff --git a/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml b/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml
new file mode 100644
index 0000000..219e014
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.requestduringlayout"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.requestduringlayout.RequestDuringLayout"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..fba1ff0
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..72a445d
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..002e7b0
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml b/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml
new file mode 100644
index 0000000..b026db8
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+ class="com.android.requestduringlayout.RequestDuringLayout$MyLayout"
+ android:orientation="vertical"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/addView"
+ android:id="@+id/addView" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/removeView"
+ android:id="@+id/removeView" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/forceLayout"
+ android:id="@+id/forceLayout" />
+ </LinearLayout>
+
+</view>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/values-large/dimens.xml b/samples/devbytes/ui/RequestDuringLayout/res/values-large/dimens.xml
new file mode 100644
index 0000000..59194f4
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values-large/dimens.xml
@@ -0,0 +1,21 @@
+<!-- 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.
+-->
+<resources>
+
+ <dimen name="padding_small">8dp</dimen>
+ <dimen name="padding_medium">16dp</dimen>
+ <dimen name="padding_large">16dp</dimen>
+
+</resources>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/values-v11/styles.xml b/samples/devbytes/ui/RequestDuringLayout/res/values-v11/styles.xml
new file mode 100644
index 0000000..c16b77b
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/values-v14/styles.xml b/samples/devbytes/ui/RequestDuringLayout/res/values-v14/styles.xml
new file mode 100644
index 0000000..0f1a1ef
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/values/dimens.xml b/samples/devbytes/ui/RequestDuringLayout/res/values/dimens.xml
new file mode 100644
index 0000000..dbe215a
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values/dimens.xml
@@ -0,0 +1,21 @@
+<!-- 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.
+-->
+<resources>
+
+ <dimen name="padding_small">8dp</dimen>
+ <dimen name="padding_medium">8dp</dimen>
+ <dimen name="padding_large">16dp</dimen>
+
+</resources>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/values/strings.xml b/samples/devbytes/ui/RequestDuringLayout/res/values/strings.xml
new file mode 100644
index 0000000..6a5e6d1
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<resources>
+ <string name="app_name">RequestDuringLayout</string>
+ <string name="button">Button</string>
+ <string name="menu_settings">Settings</string>
+ <string name="addView">Add</string>
+ <string name="removeView">Remove</string>
+ <string name="forceLayout">Layout</string>
+</resources>
diff --git a/samples/devbytes/ui/RequestDuringLayout/res/values/styles.xml b/samples/devbytes/ui/RequestDuringLayout/res/values/styles.xml
new file mode 100644
index 0000000..de01fbd
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values/styles.xml
@@ -0,0 +1,19 @@
+<!-- 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.
+-->
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
diff --git a/samples/devbytes/ui/RequestDuringLayout/src/com/example/android/requestduringlayout/RequestDuringLayout.java b/samples/devbytes/ui/RequestDuringLayout/src/com/example/android/requestduringlayout/RequestDuringLayout.java
new file mode 100644
index 0000000..e6f22cf
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/src/com/example/android/requestduringlayout/RequestDuringLayout.java
@@ -0,0 +1,131 @@
+/*
+ * 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.requestduringlayout;
+
+import com.android.requestduringlayout.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * This example shows what horrible things can result from calling requestLayout() during
+ * a layout pass. DON'T DO THIS.
+ *
+ * Watch the associated video for this demo on the DevBytes channel of developer.android.com
+ * or on YouTube at https://www.youtube.com/watch?v=HbAeTGoKG6k.
+ */
+public class RequestDuringLayout extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_request_during_layout);
+
+ final MyLayout myLayout = (MyLayout) findViewById(R.id.container);
+ Button addViewButton = (Button) findViewById(R.id.addView);
+ Button removeViewButton = (Button) findViewById(R.id.removeView);
+ Button forceLayoutButton = (Button) findViewById(R.id.forceLayout);
+
+ addViewButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ myLayout.mAddRequestPending = true;
+ myLayout.requestLayout();
+ }
+ });
+
+ removeViewButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ myLayout.mRemoveRequestPending = true;
+ myLayout.requestLayout();
+ }
+ });
+
+ forceLayoutButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ myLayout.requestLayout();
+ }
+ });
+
+ }
+
+ /**
+ * Custom layout to enable the convoluted way of requesting-during-layout that we're
+ * trying to show here. Yes, it's a hack. But it's a case that many apps hit (in much more
+ * complicated and less demoable ways), so it's interesting to at least understand the
+ * artifacts that come from this sequence of events.
+ */
+ static class MyLayout extends LinearLayout {
+
+ int numButtons = 0;
+ boolean mAddRequestPending = false;
+ boolean mRemoveRequestPending = false;
+
+ public MyLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public MyLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public MyLayout(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ // Here is the root of the problem: we are adding/removing views during layout. This
+ // means that this view and its container will be put into an uncertain state that
+ // can be difficult to discover and recover from.
+ // Better approach: just add/remove at a time when layout is not running, certainly not
+ // in the middle of onLayout(), or other layout-associated logic.
+ if (mRemoveRequestPending) {
+ removeButton();
+ mRemoveRequestPending = false;
+ }
+ if (mAddRequestPending) {
+ addButton();
+ mAddRequestPending = false;
+ }
+ }
+
+ private void removeButton() {
+ if (getChildCount() > 1) {
+ removeViewAt(1);
+ }
+ }
+
+ private void addButton() {
+ Button button = new Button(getContext());
+ button.setLayoutParams(new LayoutParams(
+ LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+ button.setText("Button " + (numButtons++));
+ addView(button);
+ }
+
+ }
+
+}