blob: a189f5847067cc599e437c176d926213ad3f30cf [file] [log] [blame]
/*
* Copyright (C) 2012 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.android.contacts.util;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.util.Log;
import android.widget.ImageView;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.model.Contact;
import java.util.Arrays;
/**
* Initialized with a target ImageView. When provided with a compressed image
* (i.e. a byte[]), it appropriately updates the ImageView's Drawable.
*/
public class ImageViewDrawableSetter {
private ImageView mTarget;
private byte[] mCompressed;
private Drawable mPreviousDrawable;
private int mDurationInMillis = 0;
private static final String TAG = "ImageViewDrawableSetter";
public ImageViewDrawableSetter() {
}
public ImageViewDrawableSetter(ImageView target) {
mTarget = target;
}
public void setupContactPhoto(Contact contactData, ImageView photoView) {
setTarget(photoView);
setCompressedImage(contactData.getPhotoBinaryData());
}
public void setTransitionDuration(int durationInMillis) {
mDurationInMillis = durationInMillis;
}
public ImageView getTarget() {
return mTarget;
}
/**
* Re-initialize to use new target. As a result, the next time a new image
* is set, it will immediately be applied to the target (there will be no
* fade transition).
*/
protected void setTarget(ImageView target) {
if (mTarget != target) {
mTarget = target;
mCompressed = null;
mPreviousDrawable = null;
}
}
protected byte[] getCompressedImage() {
return mCompressed;
}
protected Bitmap setCompressedImage(byte[] compressed) {
if (mPreviousDrawable == null) {
// If we don't already have a drawable, skip the exit-early test
// below; otherwise we might not end up setting the default image.
} else if (mPreviousDrawable != null && Arrays.equals(mCompressed, compressed)) {
// TODO: the worst case is when the arrays are equal but not
// identical. This takes about 1ms (more with high-res photos). A
// possible optimization is to sparsely sample chunks of the arrays
// to compare.
return previousBitmap();
}
final Drawable newDrawable = (compressed == null)
? defaultDrawable()
: decodedBitmapDrawable(compressed);
// Remember this for next time, so that we can check if it changed.
mCompressed = compressed;
// If we don't have a new Drawable, something went wrong... bail out.
if (newDrawable == null) return previousBitmap();
if (mPreviousDrawable == null || mDurationInMillis == 0) {
// Set the new one immediately.
mTarget.setImageDrawable(newDrawable);
} else {
// Set up a transition from the previous Drawable to the new one.
final Drawable[] beforeAndAfter = new Drawable[2];
beforeAndAfter[0] = mPreviousDrawable;
beforeAndAfter[1] = newDrawable;
final TransitionDrawable transition = new TransitionDrawable(beforeAndAfter);
mTarget.setImageDrawable(transition);
transition.startTransition(mDurationInMillis);
}
// Remember this for next time, so that we can transition from it to the
// new one.
mPreviousDrawable = newDrawable;
return previousBitmap();
}
private Bitmap previousBitmap() {
return (mPreviousDrawable == null)
? null
: ((BitmapDrawable) mPreviousDrawable).getBitmap();
}
/**
* Obtain the default drawable for a contact when no photo is available.
*/
private Drawable defaultDrawable() {
Resources resources = mTarget.getResources();
final int resId = ContactPhotoManager.getDefaultAvatarResId(true, false);
try {
return resources.getDrawable(resId);
} catch (NotFoundException e) {
Log.wtf(TAG, "Cannot load default avatar resource.");
return null;
}
}
private BitmapDrawable decodedBitmapDrawable(byte[] compressed) {
Resources rsrc = mTarget.getResources();
Bitmap bitmap = BitmapFactory.decodeByteArray(compressed, 0, compressed.length);
return new BitmapDrawable(rsrc, bitmap);
}
}