diff options
author | Rohit Yengisetty <rohit@cyngn.com> | 2014-10-20 10:43:27 -0700 |
---|---|---|
committer | linus_lee <llee@cyngn.com> | 2014-11-20 12:51:33 -0800 |
commit | b820815576f5055853f4f7362776d6f6731850a2 (patch) | |
tree | dab8598832e185c4b8de65a8e53bfa6319b10964 | |
parent | 9a62dff96f7ad5db47464b6791831d8ec776764a (diff) | |
download | android_packages_apps_Eleven-b820815576f5055853f4f7362776d6f6731850a2.tar.gz android_packages_apps_Eleven-b820815576f5055853f4f7362776d6f6731850a2.tar.bz2 android_packages_apps_Eleven-b820815576f5055853f4f7362776d6f6731850a2.zip |
Eleven - change the artist detail view's hero image to be scaled and top-left aligned
https://cyanogen.atlassian.net/browse/MUSIC-107
Change-Id: If7904a1b9c26d306483fd9098de96ff5f30e3801
-rw-r--r-- | res/layout/artist_detail_header.xml | 2 | ||||
-rw-r--r-- | src/com/cyngn/eleven/cache/BitmapWorkerTask.java | 17 | ||||
-rw-r--r-- | src/com/cyngn/eleven/cache/ImageFetcher.java | 7 | ||||
-rw-r--r-- | src/com/cyngn/eleven/cache/ImageWorker.java | 54 | ||||
-rw-r--r-- | src/com/cyngn/eleven/cache/SimpleBitmapWorkerTask.java | 22 | ||||
-rw-r--r-- | src/com/cyngn/eleven/ui/fragments/ArtistDetailFragment.java | 20 | ||||
-rw-r--r-- | src/com/cyngn/eleven/utils/ImageUtils.java | 35 |
7 files changed, 153 insertions, 4 deletions
diff --git a/res/layout/artist_detail_header.xml b/res/layout/artist_detail_header.xml index 9f83cd9..dbe7458 100644 --- a/res/layout/artist_detail_header.xml +++ b/res/layout/artist_detail_header.xml @@ -7,7 +7,7 @@ android:id="@+id/hero" android:layout_width="match_parent" android:layout_height="220dp" - android:scaleType="centerCrop" /> + android:gravity="center" /> <TextView android:id="@+id/albums_label" diff --git a/src/com/cyngn/eleven/cache/BitmapWorkerTask.java b/src/com/cyngn/eleven/cache/BitmapWorkerTask.java index aa354f4..c340508 100644 --- a/src/com/cyngn/eleven/cache/BitmapWorkerTask.java +++ b/src/com/cyngn/eleven/cache/BitmapWorkerTask.java @@ -41,6 +41,8 @@ public abstract class BitmapWorkerTask<Params, Progress, Result> protected final Resources mResources; + protected boolean mScaleImgToView; + /** * The key used to store cached entries */ @@ -55,6 +57,19 @@ public abstract class BitmapWorkerTask<Params, Progress, Result> */ public BitmapWorkerTask(final String key, final ImageView imageView, final ImageType imageType, final Drawable fromDrawable, final Context context) { + this(key, imageView, imageType, fromDrawable, context, false); + } + + /** + * Constructor of <code>BitmapWorkerTask</code> + * @param key used for caching the image + * @param imageView The {@link ImageView} to use. + * @param imageType The type of image URL to fetch for. + * @param fromDrawable what drawable to transition from + * @param scaleImgToView flag to scale the bitmap to the image view bounds + */ + public BitmapWorkerTask(final String key, final ImageView imageView, final ImageType imageType, + final Drawable fromDrawable, final Context context, final boolean scaleImgToView) { mKey = key; mContext = context; @@ -66,6 +81,8 @@ public abstract class BitmapWorkerTask<Params, Progress, Result> // A transparent image (layer 0) and the new result (layer 1) mFromDrawable = fromDrawable; + + mScaleImgToView = scaleImgToView; } /** diff --git a/src/com/cyngn/eleven/cache/ImageFetcher.java b/src/com/cyngn/eleven/cache/ImageFetcher.java index 9d0f905..8a69057 100644 --- a/src/com/cyngn/eleven/cache/ImageFetcher.java +++ b/src/com/cyngn/eleven/cache/ImageFetcher.java @@ -117,6 +117,13 @@ public class ImageFetcher extends ImageWorker { } /** + * Used to fetch artist images. It also scales the image to fit the image view, if necessary. + */ + public void loadArtistImage(final String key, final ImageView imageView, boolean scaleImgToView) { + loadImage(key, key, null, -1, imageView, ImageType.ARTIST, scaleImgToView); + } + + /** * Used to fetch the current artist image. */ public void loadCurrentArtistImage(final ImageView imageView) { diff --git a/src/com/cyngn/eleven/cache/ImageWorker.java b/src/com/cyngn/eleven/cache/ImageWorker.java index fcc6ae0..65e0d7b 100644 --- a/src/com/cyngn/eleven/cache/ImageWorker.java +++ b/src/com/cyngn/eleven/cache/ImageWorker.java @@ -449,6 +449,60 @@ public abstract class ImageWorker { } /** + * Called to fetch the artist or album art. + * + * @param key The unique identifier for the image. + * @param artistName The artist name for the Last.fm API. + * @param albumName The album name for the Last.fm API. + * @param albumId The album art index, to check for missing artwork. + * @param imageView The {@link ImageView} used to set the cached + * {@link Bitmap}. + * @param imageType The type of image URL to fetch for. + * @param scaleImgToView config option to scale the image to the image view's dimensions + */ + protected void loadImage(final String key, final String artistName, final String albumName, + final long albumId, final ImageView imageView, final ImageType imageType, boolean scaleImgToView) { + if (key == null || mImageCache == null || imageView == null) { + return; + } + + // First, check the memory for the image + final Bitmap lruBitmap = mImageCache.getBitmapFromMemCache(key); + if (lruBitmap != null && imageView != null) { // Bitmap found in memory cache + // scale image if necessary + if (scaleImgToView) + imageView.setImageBitmap( ImageUtils.scaleBitmapForImageView(lruBitmap, imageView) ); + else + imageView.setImageBitmap(lruBitmap); + } else { + // if a background drawable hasn't been set, create one so that even if + // the disk cache is paused we see something + if (imageView.getBackground() == null) { + imageView.setBackgroundDrawable(getNewDefaultBitmapDrawable(imageType)); + } + + if (executePotentialWork(key, imageView) + && imageView != null && !mImageCache.isDiskCachePaused()) { + // cancel the old task if any + cancelWork(imageView); + + // Otherwise run the worker task + final SimpleBitmapWorkerTask bitmapWorkerTask = new SimpleBitmapWorkerTask(key, + imageView, imageType, mTransparentDrawable, mContext, scaleImgToView); + final AsyncTaskContainer asyncTaskContainer = new AsyncTaskContainer(bitmapWorkerTask); + imageView.setTag(asyncTaskContainer); + try { + ApolloUtils.execute(false, bitmapWorkerTask, + artistName, albumName, String.valueOf(albumId)); + } catch (RejectedExecutionException e) { + // Executor has exhausted queue space + } + } + } + } + + + /** * Called to fetch a playlist's top artist or cover art * @param playlistId playlist identifier * @param type of work to get (Artist or CoverArt) diff --git a/src/com/cyngn/eleven/cache/SimpleBitmapWorkerTask.java b/src/com/cyngn/eleven/cache/SimpleBitmapWorkerTask.java index 0e1c3bd..31e7d1a 100644 --- a/src/com/cyngn/eleven/cache/SimpleBitmapWorkerTask.java +++ b/src/com/cyngn/eleven/cache/SimpleBitmapWorkerTask.java @@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; import android.widget.ImageView; import com.cyngn.eleven.cache.ImageWorker.ImageType; +import com.cyngn.eleven.utils.ImageUtils; /** * The actual {@link android.os.AsyncTask} that will process the image. @@ -30,6 +31,20 @@ public class SimpleBitmapWorkerTask extends BitmapWorkerTask<String, Void, Trans } /** + * Constructor of <code>BitmapWorkerTask</code> + * + * @param key the key of the image to store to + * @param imageView The {@link ImageView} to use. + * @param imageType The type of image URL to fetch for. + * @param fromDrawable what drawable to transition from + * @param scaleImgToView flag to scale the bitmap to the image view bounds + */ + public SimpleBitmapWorkerTask(final String key, final ImageView imageView, final ImageType imageType, + final Drawable fromDrawable, final Context context, final boolean scaleImgToView) { + super(key, imageView, imageType, fromDrawable, context, scaleImgToView); + } + + /** * {@inheritDoc} */ @Override @@ -39,7 +54,12 @@ public class SimpleBitmapWorkerTask extends BitmapWorkerTask<String, Void, Trans } final Bitmap bitmap = getBitmapInBackground(params); - return createImageTransitionDrawable(bitmap); + if (mScaleImgToView) { + Bitmap scaledBitmap = ImageUtils.scaleBitmapForImageView(bitmap, getAttachedImageView()); + return createImageTransitionDrawable(scaledBitmap); + } + else + return createImageTransitionDrawable(bitmap); } /** diff --git a/src/com/cyngn/eleven/ui/fragments/ArtistDetailFragment.java b/src/com/cyngn/eleven/ui/fragments/ArtistDetailFragment.java index befc96e..474df34 100644 --- a/src/com/cyngn/eleven/ui/fragments/ArtistDetailFragment.java +++ b/src/com/cyngn/eleven/ui/fragments/ArtistDetailFragment.java @@ -1,5 +1,6 @@ package com.cyngn.eleven.ui.fragments; +import android.os.Build; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v7.widget.LinearLayoutManager; @@ -7,6 +8,7 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.ListView; import com.cyngn.eleven.Config; @@ -102,7 +104,21 @@ public class ArtistDetailFragment extends FadingBarFragment { private void setupHero(String artistName) { mHero = (ImageView)mHeader.findViewById(R.id.hero); mHero.setContentDescription(artistName); - ImageFetcher.getInstance(getActivity()).loadArtistImage(artistName, mHero); + // initiate loading the artist image + // since the artist image needs to be scaled to the image view bounds, we need to wait till the first layout + // traversal to be able to get the image view dimensions in the helper method that scales the image + mHero.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + mHero.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } else { + mHero.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + ImageFetcher.getInstance(getActivity()).loadArtistImage(mArtistName, mHero, true); + } + }); + } private void setupAlbumList() { @@ -214,4 +230,4 @@ public class ArtistDetailFragment extends FadingBarFragment { mSongAdapter.setCurrentlyPlayingTrack(MusicUtils.getCurrentTrack()); } -}
\ No newline at end of file +} diff --git a/src/com/cyngn/eleven/utils/ImageUtils.java b/src/com/cyngn/eleven/utils/ImageUtils.java index 58cbada..52163d3 100644 --- a/src/com/cyngn/eleven/utils/ImageUtils.java +++ b/src/com/cyngn/eleven/utils/ImageUtils.java @@ -245,4 +245,39 @@ public class ImageUtils { } return null; } + + /** + * Scale the bitmap to an image view. The bitmap will fill the image view bounds. The bitmap will be scaled + * while maintaining the aspect ratio and cropped if it exceeds the image-view bounds. + */ + public static Bitmap scaleBitmapForImageView(Bitmap src, ImageView imageView) { + if (src == null || imageView == null) { + return src; + } + // get bitmap properties + int srcHeight = src.getHeight(); + int srcWidth = src.getWidth(); + + // get image view bounds + int viewHeight = imageView.getHeight(); + int viewWidth = imageView.getWidth(); + + int deltaWidth = viewWidth - srcWidth; + int deltaHeight = viewHeight - srcHeight; + + if (deltaWidth <= 0 && deltaWidth <= 0) // nothing to do if src bitmap is bigger than image-view + return src; + + // scale bitmap along the dimension that is lacking the greatest + float scale = Math.max( ((float)viewWidth) / srcWidth, ((float)viewHeight) / srcHeight); + + // calculate the new bitmap dimensions + int dstHeight = (int) Math.ceil(srcHeight * scale); + int dstWidth = (int) Math.ceil(srcWidth * scale); + Bitmap scaledBitmap = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false); + Bitmap croppedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, viewWidth, viewHeight); + + return croppedBitmap; + + } } |