diff --git a/samples/devbytes/animation/Bouncer/AndroidManifest.xml b/samples/devbytes/animation/Bouncer/AndroidManifest.xml
new file mode 100644
index 000000000..ff10b726f
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/AndroidManifest.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png 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 000000000..22b224ab8
Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png 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 000000000..543951b03
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
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 000000000..765f6aefd
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
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 000000000..db21eee3d
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
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 000000000..a1a6911cf
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..85e239198
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values/strings.xml
@@ -0,0 +1,23 @@
+
+
+
+ Bouncer
+ Bouncer
+ Bouncer1
+ Bouncer2
+ Bouncer3
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/Bouncer/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..a04c3784c
--- /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 000000000..554c0f2fe
--- /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 000000000..30ff64dd2
--- /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 000000000..cea9a3d3f
--- /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 000000000..0d38d6a1b
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/CrossFading/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/CrossFading/res/drawable-mdpi/ic_launcher.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/CrossFading/res/drawable-xhdpi/ic_launcher.png 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 000000000..9c5423db2
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/layout/activity_cross_fading.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..dbfca7ec1
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ CrossFading
+ CrossFading
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/CrossFading/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..e02694c91
--- /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 000000000..2406281ae
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/KeyframeAnimation/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/KeyframeAnimation/res/drawable-mdpi/ic_launcher.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/KeyframeAnimation/res/drawable-xhdpi/ic_launcher.png 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 000000000..4da3948b8
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/layout/activity_keyframe_animation.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..330dae2ba
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ KeyframeAnimation
+ KeyframeAnimation
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/KeyframeAnimation/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..9a6bbd017
--- /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 000000000..d9b55f5ae
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..8074c4c57
Binary files /dev/null and b/samples/devbytes/animation/LayoutTransChanging/res/drawable-hdpi/icon.png 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 000000000..1095584ec
Binary files /dev/null and b/samples/devbytes/animation/LayoutTransChanging/res/drawable-ldpi/icon.png 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 000000000..a07c69fa5
Binary files /dev/null and b/samples/devbytes/animation/LayoutTransChanging/res/drawable-mdpi/icon.png 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 000000000..3b5dd0df4
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/layout/main.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
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 000000000..d50ad1167
--- /dev/null
+++ b/samples/devbytes/animation/LayoutTransChanging/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ LayoutTransChanging
+ Add Item
+ Remove Item
+
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 000000000..e24033032
--- /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 000000000..16a0bf1e4
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/AndroidManifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/ListViewAnimations/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/ListViewAnimations/res/drawable-mdpi/ic_launcher.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/ListViewAnimations/res/drawable-xhdpi/ic_launcher.png 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 000000000..b8fc9cdb2
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/layout/activity_list_view_animations.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
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 000000000..139d283c1
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values-v11/styles.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
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 000000000..8ac452213
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
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 000000000..5b41f5b66
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ ListViewAnimations
+ ViewPropertyAnimator
+ Transient State
+
+
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 000000000..f9460a7e5
--- /dev/null
+++ b/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
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 000000000..69c027db1
--- /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 000000000..2d2cc683f
--- /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 cheeseList = new ArrayList();
+ 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 {
+
+ HashMap mIdMap = new HashMap();
+
+ public StableArrayAdapter(Context context, int textViewResourceId,
+ List 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 000000000..6cb909eda
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png 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 000000000..974581894
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg 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 000000000..db8731f01
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg 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 000000000..b240b3a02
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg 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 000000000..4de929221
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png 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 000000000..599c770b6
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..5ed396b1b
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ PictureViewer
+ PictureViewer
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/PictureViewer/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..e1cb4dd2f
--- /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 000000000..977d29ee6
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..6ae8ca0be
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/combo.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..c27c6af1e
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/fade.xml
@@ -0,0 +1,21 @@
+
+
+
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 000000000..aaac09a99
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/move.xml
@@ -0,0 +1,21 @@
+
+
+
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 000000000..7bbe0a9a2
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/scale.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
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 000000000..64fdc36d4
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/animator/spin.xml
@@ -0,0 +1,20 @@
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/PropertyAnimations/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/PropertyAnimations/res/drawable-mdpi/ic_launcher.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/PropertyAnimations/res/drawable-xhdpi/ic_launcher.png 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 000000000..add0a5454
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/layout/activity_property_animations.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..3a872d800
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+ PropertyAnimations
+ PropertyAnimations
+ Use Animation Resources
+ Alpha
+ Translate
+ Rotate
+ Scale
+ Set
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/PropertyAnimations/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..89480f62e
--- /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 000000000..d713f4c6d
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..2afcb6c9b
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/alpha_anim.xml
@@ -0,0 +1,18 @@
+
+
+
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 000000000..622bd32da
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/rotate_anim.xml
@@ -0,0 +1,19 @@
+
+
+
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 000000000..1b107050b
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/scale_anim.xml
@@ -0,0 +1,21 @@
+
+
+
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 000000000..567e3d5e3
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/set_anim.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
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 000000000..e33e8f10f
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/anim/translate_anim.xml
@@ -0,0 +1,19 @@
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/ViewAnimations/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/ViewAnimations/res/drawable-mdpi/ic_launcher.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/ViewAnimations/res/drawable-xhdpi/ic_launcher.png 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 000000000..3338135da
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/layout/activity_view_animations.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..a43f1afd8
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+ ViewAnimations
+ ViewAnimations
+ Alpha
+ Translate
+ Rotate
+ Scale
+ Set
+ Use Animation 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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/ViewAnimations/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..50d98a69b
--- /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 000000000..6f111eb17
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/AndroidManifest.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..8321f1f11
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_left.xml
@@ -0,0 +1,18 @@
+
+
+
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 000000000..c3f292027
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_in_right.xml
@@ -0,0 +1,18 @@
+
+
+
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 000000000..6c93cedbb
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_left.xml
@@ -0,0 +1,18 @@
+
+
+
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 000000000..2057345f5
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/anim/slide_out_right.xml
@@ -0,0 +1,18 @@
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/animation/WindowAnimations/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/animation/WindowAnimations/res/drawable-mdpi/ic_launcher.png 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 000000000..e1722f3df
Binary files /dev/null and b/samples/devbytes/animation/WindowAnimations/res/drawable-nodpi/thumbnail.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/animation/WindowAnimations/res/drawable-xhdpi/ic_launcher.png 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 000000000..38647529e
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/layout/activity_sub.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
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 000000000..709e53977
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_anim_sub.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
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 000000000..8d653ea65
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/layout/activity_window_animations.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..39fc4361f
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values/strings.xml
@@ -0,0 +1,25 @@
+
+
+
+ WindowAnimations
+ Sub-Activity
+ Settings
+ WindowAnimations
+ WindowAnimSubActivity
+ Hello world!
+ SubActivity
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/animation/WindowAnimations/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..ad2624894
--- /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 000000000..61b0a6803
--- /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 000000000..a5c76b102
--- /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 000000000..5ffcb29b2
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-mdpi/ic_launcher.png 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 000000000..23dc04a8e
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/a.jpg 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 000000000..b6beca25f
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/b.jpg 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 000000000..d60855497
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/c.jpg 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 000000000..f1ff9f5a5
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/d.jpg 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 000000000..580a0d17d
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/e.jpg 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 000000000..bc14d1217
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-nodpi/f.jpg 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/graphics/BitmapAllocation/res/drawable-xhdpi/ic_launcher.png 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 000000000..458178b53
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/layout/activity_bitmap_allocation.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..bf598f978
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ BitmapAllocation
+ BitmapAllocation
+ Reuse Bitmap
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapAllocation/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..cc6b1e00a
--- /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 000000000..f926a2785
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/graphics/BitmapScaling/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/graphics/BitmapScaling/res/drawable-mdpi/ic_launcher.png 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 000000000..9f5349a64
Binary files /dev/null and b/samples/devbytes/graphics/BitmapScaling/res/drawable-nodpi/jellybean_statue.jpg 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/graphics/BitmapScaling/res/drawable-xhdpi/ic_launcher.png 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 000000000..d9556fc5a
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/layout/activity_bitmap_scaling.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..466f6aeb6
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values/strings.xml
@@ -0,0 +1,22 @@
+
+
+
+ BitmapScaling
+ BitmapScaling
+ Original Image
+ Scaled Images
+
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/graphics/BitmapScaling/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..8ca5a3137
--- /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 000000000..ba48e97bd
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/AndroidManifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..96a442e5b
Binary files /dev/null and b/samples/devbytes/ui/ListViewDeletion/res/drawable-hdpi/ic_launcher.png 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 000000000..359047dfa
Binary files /dev/null and b/samples/devbytes/ui/ListViewDeletion/res/drawable-mdpi/ic_launcher.png 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 000000000..71c6d760f
Binary files /dev/null and b/samples/devbytes/ui/ListViewDeletion/res/drawable-xhdpi/ic_launcher.png 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 000000000..4b98347c6
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/layout/activity_list_view_deletion.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
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 000000000..139d283c1
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values-v11/styles.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
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 000000000..8ac452213
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
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 000000000..7801d600a
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ ListViewDeletion
+ Use Positions
+ Delete Selected
+
+
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 000000000..f9460a7e5
--- /dev/null
+++ b/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
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 000000000..4bdd858e8
--- /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 000000000..d3538231c
--- /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 mCheckedViews = new ArrayList();
+
+ @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 cheeseList = new ArrayList();
+ 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 {
+
+ HashMap mIdMap = new HashMap();
+
+ public StableArrayAdapter(Context context, int textViewResourceId,
+ List 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 000000000..219e0145f
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 000000000..fba1ff058
Binary files /dev/null and b/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png 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 000000000..72a445d04
Binary files /dev/null and b/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png 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 000000000..002e7b052
Binary files /dev/null and b/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png 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 000000000..b026db8ad
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
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 000000000..59194f42f
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values-large/dimens.xml
@@ -0,0 +1,21 @@
+
+
+
+ 8dp
+ 16dp
+ 16dp
+
+
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 000000000..c16b77bf8
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values-v11/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..0f1a1ef9c
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values-v14/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..dbe215a8e
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values/dimens.xml
@@ -0,0 +1,21 @@
+
+
+
+ 8dp
+ 8dp
+ 16dp
+
+
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 000000000..6a5e6d16e
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values/strings.xml
@@ -0,0 +1,23 @@
+
+
+
+ RequestDuringLayout
+ Button
+ Settings
+ Add
+ Remove
+ Layout
+
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 000000000..de01fbd2f
--- /dev/null
+++ b/samples/devbytes/ui/RequestDuringLayout/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
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 000000000..e6f22cf16
--- /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);
+ }
+
+ }
+
+}