Commit 3ff1591c authored by Chet Haase's avatar Chet Haase Committed by Android Git Automerger
Browse files

am 28b127ec: New DevBytes animation demos

* commit '28b127ec':
  New DevBytes animation demos
parents 69abf615 28b127ec
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.activityanim"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.android.activityanim.ActivityAnimations"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.android.activityanim.PictureDetailsActivity"
android:label="@string/subactivity_name"
android:theme="@style/Transparent" >
</activity>
</application>
</manifest>
\ No newline at end of file
samples/devbytes/animation/ActivityAnimations/res/drawable-nodpi/p1.jpg

183 KB

samples/devbytes/animation/ActivityAnimations/res/drawable-nodpi/p2.jpg

105 KB

samples/devbytes/animation/ActivityAnimations/res/drawable-nodpi/p3.jpg

96.4 KB

samples/devbytes/animation/ActivityAnimations/res/drawable-nodpi/p4.jpg

222 KB

<!-- 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.
-->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:id="@+id/gridLayout" >
</GridLayout>
\ No newline at end of file
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/topLevelLayout">
<view
class="com.example.android.activityanim.ShadowLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/shadowLayout"
android:visibility="visible" >
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/imageView" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleType="centerInside" />
</view>
</FrameLayout>
\ No newline at end of file
<!-- 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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_slow"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/menu_slow_animations"
android:checkable="true"/>
</menu>
\ No newline at end of file
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">Activity Animations</string>
<string name="subactivity_name">PictureInfo!</string>
<string name="menu_slow_animations">Slow</string>
</resources>
\ No newline at end of file
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<style name="Transparent">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
</resources>
\ No newline at end of file
/*
* 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.activityanim;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.GridLayout;
import android.widget.ImageView;
/**
* This example shows how to create a custom activity animation when you want something more
* than window animations can provide. The idea is to disable window animations for the
* activities and to instead launch or return from the sub-activity immediately, but use
* property animations inside the activities to customize the transition.
*
* Watch the associated video for this demo on the DevBytes channel of developer.android.com
* or on the DevBytes playlist in the androiddevelopers channel on YouTube at
* https://www.youtube.com/playlist?list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0.
*/
public class ActivityAnimations extends Activity {
private static final String PACKAGE = "com.example.android.activityanim";
static float sAnimatorScale = 1;
GridLayout mGridLayout;
HashMap<ImageView, PictureData> mPicturesData = new HashMap<ImageView, PictureData>();
BitmapUtils mBitmapUtils = new BitmapUtils();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animations);
// Grayscale filter used on all thumbnails
ColorMatrix grayMatrix = new ColorMatrix();
grayMatrix.setSaturation(0);
ColorMatrixColorFilter grayscaleFilter = new ColorMatrixColorFilter(grayMatrix);
mGridLayout = (GridLayout) findViewById(R.id.gridLayout);
mGridLayout.setColumnCount(3);
mGridLayout.setUseDefaultMargins(true);
// add all photo thumbnails to layout
Resources resources = getResources();
ArrayList<PictureData> pictures = mBitmapUtils.loadPhotos(resources);
for (int i = 0; i < pictures.size(); ++i) {
PictureData pictureData = pictures.get(i);
BitmapDrawable thumbnailDrawable =
new BitmapDrawable(resources, pictureData.thumbnail);
thumbnailDrawable.setColorFilter(grayscaleFilter);
ImageView imageView = new ImageView(this);
imageView.setOnClickListener(thumbnailClickListener);
imageView.setImageDrawable(thumbnailDrawable);
mPicturesData.put(imageView, pictureData);
mGridLayout.addView(imageView);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_better_window_animations, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_slow) {
sAnimatorScale = item.isChecked() ? 1 : 5;
item.setChecked(!item.isChecked());
}
return super.onOptionsItemSelected(item);
}
/**
* When the user clicks a thumbnail, bundle up information about it and launch the
* details activity.
*/
private View.OnClickListener thumbnailClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Interesting data to pass across are the thumbnail size/location, the
// resourceId of the source bitmap, the picture description, and the
// orientation (to avoid returning back to an obsolete configuration if
// the device rotates again in the meantime)
int[] screenLocation = new int[2];
v.getLocationOnScreen(screenLocation);
PictureData info = mPicturesData.get(v);
Intent subActivity = new Intent(ActivityAnimations.this,
PictureDetailsActivity.class);
int orientation = getResources().getConfiguration().orientation;
subActivity.
putExtra(PACKAGE + ".orientation", orientation).
putExtra(PACKAGE + ".resourceId", info.resourceId).
putExtra(PACKAGE + ".left", screenLocation[0]).
putExtra(PACKAGE + ".top", screenLocation[1]).
putExtra(PACKAGE + ".width", v.getWidth()).
putExtra(PACKAGE + ".height", v.getHeight()).
putExtra(PACKAGE + ".description", info.description);
startActivity(subActivity);
// Override transitions: we don't want the normal window animation in addition
// to our custom one
overridePendingTransition(0, 0);
}
};
}
/*
* 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.activityanim;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.widget.ImageView;
public class BitmapUtils {
int[] mPhotos = {
R.drawable.p1,
R.drawable.p2,
R.drawable.p3,
R.drawable.p4
};
String[] mDescriptions = {
"This picture was taken while sunbathing in a natural hot spring, which was " +
"unfortunately filled with acid, which is a lasting memory from that trip, whenever I " +
"I look at my own skin.",
"I took this shot with a pinhole camera mounted on a tripod constructed out of " +
"soda straws. I felt that that combination best captured the beauty of the landscape " +
"in juxtaposition with the detritus of mankind.",
"I don't remember where or when I took this picture. All I know is that I was really " +
"drunk at the time, and I woke up without my left sock.",
"Right before I took this picture, there was a busload of school children right " +
"in my way. I knew the perfect shot was coming, so I quickly yelled 'Free candy!!!' " +
"and they scattered.",
};
static HashMap<Integer, Bitmap> sBitmapResourceMap = new HashMap<Integer, Bitmap>();
/**
* Load pictures and descriptions. A real app wouldn't do it this way, but that's
* not the point of this animation demo. Loading asynchronously is a better way to go
* for what can be time-consuming operations.
*/
public ArrayList<PictureData> loadPhotos(Resources resources) {
ArrayList<PictureData> pictures = new ArrayList<PictureData>();
for (int i = 0; i < 30; ++i) {
int resourceId = mPhotos[(int) (Math.random() * mPhotos.length)];
Bitmap bitmap = getBitmap(resources, resourceId);
Bitmap thumbnail = getThumbnail(bitmap, 200);
String description = mDescriptions[(int) (Math.random() * mDescriptions.length)];
pictures.add(new PictureData(resourceId, description, thumbnail));
}
return pictures;
}
/**
* Utility method to get bitmap from cache or, if not there, load it
* from its resource.
*/
static Bitmap getBitmap(Resources resources, int resourceId) {
Bitmap bitmap = sBitmapResourceMap.get(resourceId);
if (bitmap == null) {
bitmap = BitmapFactory.decodeResource(resources, resourceId);
sBitmapResourceMap.put(resourceId, bitmap);
}
return bitmap;
}
/**
* Create and return a thumbnail image given the original source bitmap and a max
* dimension (width or height).
*/
private Bitmap getThumbnail(Bitmap original, int maxDimension) {
int width = original.getWidth();
int height = original.getHeight();
int scaledWidth, scaledHeight;
if (width >= height) {
float scaleFactor = (float) maxDimension / width;
scaledWidth = 200;
scaledHeight = (int) (scaleFactor * height);
} else {
float scaleFactor = (float) maxDimension / height;
scaledWidth = (int) (scaleFactor * width);
scaledHeight = 200;
}
Bitmap thumbnail = Bitmap.createScaledBitmap(original, scaledWidth, scaledHeight, true);
return thumbnail;
}
}
/*
* 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.activityanim;
import android.graphics.Bitmap;
public class PictureData {
int resourceId;
String description;
Bitmap thumbnail;
public PictureData(int resourceId, String description, Bitmap thumbnail) {
this.resourceId = resourceId;
this.description = description;
this.thumbnail = thumbnail;
}
}
/*
* 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.activityanim;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
/**
* This sub-activity shows a zoomed-in view of a specific photo, along with the
* picture's text description. Most of the logic is for the animations that will
* be run when the activity is being launched and exited. When launching,
* the large version of the picture will resize from the thumbnail version in the
* main activity, colorizing it from the thumbnail's grayscale version at the
* same time. Meanwhile, the black background of the activity will fade in and
* the description will eventually slide into place. The exit animation runs all
* of this in reverse.
*
*/
public class PictureDetailsActivity extends Activity {
private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
private static final TimeInterpolator sAccelerator = new AccelerateInterpolator();
private static final String PACKAGE_NAME = "com.example.android.activityanim";
private static final int ANIM_DURATION = 500;
private BitmapDrawable mBitmapDrawable;
private ColorMatrix colorizerMatrix = new ColorMatrix();
ColorDrawable mBackground;
int mLeftDelta;
int mTopDelta;
float mWidthScale;
float mHeightScale;
private ImageView mImageView;
private TextView mTextView;
private FrameLayout mTopLevelLayout;
private ShadowLayout mShadowLayout;
private int mOriginalOrientation;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picture_info);
mImageView = (ImageView) findViewById(R.id.imageView);
mTopLevelLayout = (FrameLayout) findViewById(R.id.topLevelLayout);
mShadowLayout = (ShadowLayout) findViewById(R.id.shadowLayout);
mTextView = (TextView) findViewById(R.id.description);
// Retrieve the data we need for the picture/description to display and
// the thumbnail to animate it from
Bundle bundle = getIntent().getExtras();
Bitmap bitmap = BitmapUtils.getBitmap(getResources(),
bundle.getInt(PACKAGE_NAME + ".resourceId"));
String description = bundle.getString(PACKAGE_NAME + ".description");
final int thumbnailTop = bundle.getInt(PACKAGE_NAME + ".top");
final int thumbnailLeft = bundle.getInt(PACKAGE_NAME + ".left");
final int thumbnailWidth = bundle.getInt(PACKAGE_NAME + ".width");
final int thumbnailHeight = bundle.getInt(PACKAGE_NAME + ".height");
mOriginalOrientation = bundle.getInt(PACKAGE_NAME + ".orientation");
mBitmapDrawable = new BitmapDrawable(getResources(), bitmap);
mImageView.setImageDrawable(mBitmapDrawable);
mTextView.setText(description);
mBackground = new ColorDrawable(Color.BLACK);
mTopLevelLayout.setBackground(mBackground);
// Only run the animation if we're coming from the parent activity, not if
// we're recreated automatically by the window manager (e.g., device rotation)
if (savedInstanceState == null) {
ViewTreeObserver observer = mImageView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mImageView.getViewTreeObserver().removeOnPreDrawListener(this);
// Figure out where the thumbnail and full size versions are, relative
// to the screen and each other
int[] screenLocation = new int[2];
mImageView.getLocationOnScreen(screenLocation);
mLeftDelta = thumbnailLeft - screenLocation[0];
mTopDelta = thumbnailTop - screenLocation[1];
// Scale factors to make the large version the same size as the thumbnail
mWidthScale = (float) thumbnailWidth / mImageView.getWidth();
mHeightScale = (float) thumbnailHeight / mImageView.getHeight();
runEnterAnimation();
return true;
}
});
}
}
/**
* The enter animation scales the picture in from its previous thumbnail
* size/location, colorizing it in parallel. In parallel, the background of the
* activity is fading in. When the pictue is in place, the text description
* drops down.
*/
public void runEnterAnimation() {
final long duration = (long) (ANIM_DURATION * ActivityAnimations.sAnimatorScale);
// Set starting values for properties we're going to animate. These
// values scale and position the full size version down to the thumbnail
// size/location, from which we'll animate it back up
mImageView.setPivotX(0);
mImageView.setPivotY(0);
mImageView.setScaleX(mWidthScale);
mImageView.setScaleY(mHeightScale);
mImageView.setTranslationX(mLeftDelta);
mImageView.setTranslationY(mTopDelta);
// We'll fade the text in later
mTextView.setAlpha(0);
// Animate scale and translation to go from thumbnail to full size
mImageView.animate().setDuration(duration).
scaleX(1).scaleY(1).
translationX(0).translationY(0).
setInterpolator(sDecelerator).
withEndAction(new Runnable() {
public void run() {
// Animate the description in after the image animation
// is done. Slide and fade the text in from underneath
// the picture.
mTextView.setTranslationY(-mTextView.getHeight());
mTextView.animate().setDuration(duration/2).
translationY(0).alpha(1).
setInterpolator(sDecelerator);
}
});
// Fade in the black background
ObjectAnimator bgAnim = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
bgAnim.setDuration(duration);
bgAnim.start();
// Animate a color filter to take the image from grayscale to full color.
// This happens in parallel with the image scaling and moving into place.
ObjectAnimator colorizer = ObjectAnimator.ofFloat(PictureDetailsActivity.this,
"saturation", 0, 1);
colorizer.setDuration(duration);
colorizer.start();
// Animate a drop-shadow of the image
ObjectAnimator shadowAnim = ObjectAnimator.ofFloat(mShadowLayout, "shadowDepth", 0, 1);
shadowAnim.setDuration(duration);
shadowAnim.start();
}
/**
* The exit animation is basically a reverse of the enter animation, except that if
* the orientation has changed we simply scale the picture back into the center of
* the screen.
*
* @param endAction This action gets run after the animation completes (this is
* when we actually switch activities)
*/
public void runExitAnimation(final Runnable endAction) {
final long duration = (long) (ANIM_DURATION * ActivityAnimations.sAnimatorScale);
// No need to set initial values for the reverse animation; the image is at the
// starting size/location that we want to start from. Just animate to the
// thumbnail size/location that we retrieved earlier
// Caveat: configuration change invalidates thumbnail positions; just animate
// the scale around the center. Also, fade it out since it won't match up with
// whatever's actually in the center
final boolean fadeOut;
if (getResources().getConfiguration().orientation != mOriginalOrientation) {
mImageView.setPivotX(mImageView.getWidth() / 2);
mImageView.setPivotY(mImageView.getHeight() / 2);
mLeftDelta = 0;
mTopDelta = 0;
fadeOut = true;
} else {
fadeOut = false;
}
// First, slide/fade text out of the way
mTextView.animate().translationY(-mTextView.getHeight()).alpha(0).
setDuration(duration/2).setInterpolator(sAccelerator).
withEndAction(new Runnable() {
public void run() {
// Animate image back to thumbnail size/location
mImageView.animate().setDuration(duration).
scaleX(mWidthScale).scaleY(mHeightScale).
translationX(mLeftDelta).translationY(mTopDelta).
withEndAction(endAction);
if (fadeOut) {
mImageView.animate().alpha(0);
}
// Fade out background
ObjectAnimator bgAnim = ObjectAnimator.ofInt(mBackground, "alpha", 0);
bgAnim.setDuration(duration);
bgAnim.start();
// Animate the shadow of the image
ObjectAnimator shadowAnim = ObjectAnimator.ofFloat(mShadowLayout,
"shadowDepth", 1, 0);
shadowAnim.setDuration(duration);
shadowAnim.start();
// Animate a color filter to take the image back to grayscale,
// in parallel with the image scaling and moving into place.
ObjectAnimator colorizer =
ObjectAnimator.ofFloat(PictureDetailsActivity.this,
"saturation", 1, 0);
colorizer.setDuration(duration);
colorizer.start();
}
});
}
/**
* Overriding this method allows us to run our exit animation first, then exiting
* the activity when it is complete.
*/
@Override
public void onBackPressed() {
runExitAnimation(new Runnable() {
public void run() {
// *Now* go ahead and exit the activity
finish();
}
});
}
/**
* This is called by the colorizing animator. It sets a saturation factor that is then
* passed onto a filter on the picture's drawable.
* @param value
*/
public void setSaturation(float value) {
colorizerMatrix.setSaturation(value);
ColorMatrixColorFilter colorizerFilter = new ColorMatrixColorFilter(colorizerMatrix);
mBitmapDrawable.setColorFilter(colorizerFilter);
}
@Override
public void finish() {
super.finish();
// override transitions to skip the standard window animations
overridePendingTransition(0, 0);
}
}
/*
* 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.activityanim;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.BlurMaskFilter.Blur;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
/**
* This custom layout paints a drop shadow behind all children. The size and opacity
* of the drop shadow is determined by a "depth" factor that can be set and animated.
*/
public class ShadowLayout extends RelativeLayout {
Paint mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
float mShadowDepth;
Bitmap mShadowBitmap;
static final int BLUR_RADIUS = 6;
static final RectF sShadowRectF = new RectF(0, 0, 200, 200);
static final Rect sShadowRect = new Rect(0, 0, 200 + 2 * BLUR_RADIUS, 200 + 2 * BLUR_RADIUS);
static RectF tempShadowRectF = new RectF(0, 0, 0, 0);
public ShadowLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ShadowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShadowLayout(Context context) {
super(context);
init();
}
/**
* Called by the constructors - sets up the drawing parameters for the drop shadow.
*/
private void init() {
mShadowPaint.setColor(Color.BLACK);
mShadowPaint.setStyle(Style.FILL);
setWillNotDraw(false);
mShadowBitmap = Bitmap.createBitmap(sShadowRect.width(),
sShadowRect.height(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(mShadowBitmap);
mShadowPaint.setMaskFilter(new BlurMaskFilter(BLUR_RADIUS, Blur.NORMAL));
c.translate(BLUR_RADIUS, BLUR_RADIUS);
c.drawRoundRect(sShadowRectF, sShadowRectF.width() / 40,
sShadowRectF.height() / 40, mShadowPaint);
}
/**
* The "depth" factor determines the offset distance and opacity of the shadow (shadows that
* are further away from the source are offset greater and are more translucent).
* @param depth
*/
public void setShadowDepth(float depth) {
if (depth != mShadowDepth) {
mShadowDepth = depth;
mShadowPaint.setAlpha((int) (100 + 150 * (1 - mShadowDepth)));
invalidate(); // We need to redraw when the shadow attributes change
}
}
/**
* Overriding onDraw allows us to draw shadows behind every child of this container.
* onDraw() is called to draw a layout's content before the children are drawn, so the
* shadows will be drawn first, behind the children (which is what we want).
*/
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < getChildCount(); ++i) {
View child = getChildAt(i);
if (child.getVisibility() != View.VISIBLE || child.getAlpha() == 0) {
continue;
}
int depthFactor = (int) (80 * mShadowDepth);
canvas.save();
canvas.translate(child.getLeft() + depthFactor,
child.getTop() + depthFactor);
canvas.concat(child.getMatrix());
tempShadowRectF.right = child.getWidth();
tempShadowRectF.bottom = child.getHeight();
canvas.drawBitmap(mShadowBitmap, sShadowRect, tempShadowRectF, mShadowPaint);
canvas.restore();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.anticipation"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.android.anticipation.Anticipation"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
samples/devbytes/animation/Anticipation/res/drawable-hdpi/ic_launcher.png

9.18 KB

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment