Cached bitmaps will now have the same size as their ImageViews
This commit is contained in:
parent
40e0950c23
commit
616c247d84
|
@ -14,7 +14,10 @@
|
|||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="1dip"
|
||||
android:layout_marginRight="4dip"
|
||||
android:cropToPadding="true" />
|
||||
android:adjustViewBounds="true"
|
||||
android:cropToPadding="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/default_cover" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvNewEps"
|
||||
|
|
|
@ -25,7 +25,7 @@ public class FeedInfoActivity extends SherlockActivity {
|
|||
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
|
||||
private Feed feed;
|
||||
|
||||
|
||||
private ImageView imgvCover;
|
||||
private TextView txtvTitle;
|
||||
private TextView txtvDescription;
|
||||
|
@ -41,22 +41,32 @@ public class FeedInfoActivity extends SherlockActivity {
|
|||
FeedManager manager = FeedManager.getInstance();
|
||||
feed = manager.getFeed(feedId);
|
||||
if (feed != null) {
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "Language is " + feed.getLanguage());
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "Author is " + feed.getAuthor());
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Language is " + feed.getLanguage());
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Author is " + feed.getAuthor());
|
||||
imgvCover = (ImageView) findViewById(R.id.imgvCover);
|
||||
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
|
||||
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
|
||||
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
|
||||
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
|
||||
FeedImageLoader.getInstance().loadCoverBitmap(feed.getImage(), imgvCover);
|
||||
|
||||
imgvCover.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(
|
||||
feed.getImage(), imgvCover);
|
||||
}
|
||||
});
|
||||
|
||||
txtvTitle.setText(feed.getTitle());
|
||||
txtvDescription.setText(feed.getDescription());
|
||||
if (feed.getAuthor() != null) {
|
||||
txtvAuthor.setText(feed.getAuthor());
|
||||
}
|
||||
if (feed.getLanguage() != null) {
|
||||
txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
|
||||
txtvLanguage.setText(LangUtils.getLanguageString(feed
|
||||
.getLanguage()));
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Activity was started with invalid arguments");
|
||||
|
@ -64,27 +74,22 @@ public class FeedInfoActivity extends SherlockActivity {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = new MenuInflater(this);
|
||||
inflater.inflate(R.menu.feedinfo, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.support_item).setVisible(feed.getPaymentLink() != null);
|
||||
menu.findItem(R.id.support_item).setVisible(
|
||||
feed.getPaymentLink() != null);
|
||||
menu.findItem(R.id.share_link_item).setVisible(feed.getLink() != null);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
|
|
@ -39,8 +39,8 @@ public class FeedlistAdapter extends ArrayAdapter<Feed> {
|
|||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
Feed feed = getItem(position);
|
||||
final Holder holder;
|
||||
final Feed feed = getItem(position);
|
||||
|
||||
// Inflate Layout
|
||||
if (convertView == null) {
|
||||
|
@ -94,12 +94,14 @@ public class FeedlistAdapter extends ArrayAdapter<Feed> {
|
|||
holder.newEpisodes.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
holder.image.setTag(feed.getImage());
|
||||
/*if (PodcastApp.getInstance().isLargeScreen()) {
|
||||
imageLoader.loadCoverBitmap(feed.getImage(), holder.image);
|
||||
|
||||
} else {*/
|
||||
imageLoader.loadThumbnailBitmap(feed.getImage(), holder.image);
|
||||
//}
|
||||
holder.image.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
imageLoader.loadThumbnailBitmap(feed.getImage(), holder.image);
|
||||
}
|
||||
});
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ public class SearchlistAdapter extends ArrayAdapter<SearchResult> {
|
|||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
final Holder holder;
|
||||
SearchResult result = getItem(position);
|
||||
FeedComponent component = result.getComponent();
|
||||
|
||||
|
@ -48,21 +48,34 @@ public class SearchlistAdapter extends ArrayAdapter<SearchResult> {
|
|||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
if (component.getClass() == Feed.class) {
|
||||
Feed feed = (Feed) component;
|
||||
final Feed feed = (Feed) component;
|
||||
holder.title.setText(feed.getTitle());
|
||||
holder.subtitle.setVisibility(View.GONE);
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(feed.getImage(),
|
||||
holder.cover);
|
||||
holder.cover.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(
|
||||
feed.getImage(), holder.cover);
|
||||
}
|
||||
});
|
||||
|
||||
} else if (component.getClass() == FeedItem.class) {
|
||||
FeedItem item = (FeedItem) component;
|
||||
final FeedItem item = (FeedItem) component;
|
||||
holder.title.setText(item.getTitle());
|
||||
if (result.getSubtitle() != null) {
|
||||
holder.subtitle.setVisibility(View.VISIBLE);
|
||||
holder.subtitle.setText(result.getSubtitle());
|
||||
}
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(item.getFeed().getImage(),
|
||||
holder.cover);
|
||||
holder.cover.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(
|
||||
item.getFeed().getImage(), holder.cover);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return convertView;
|
||||
|
|
|
@ -17,32 +17,27 @@ import de.danoeh.antennapod.util.BitmapDecoder;
|
|||
public abstract class BitmapDecodeWorkerTask extends Thread {
|
||||
|
||||
protected int PREFERRED_LENGTH;
|
||||
|
||||
public static final int LENGTH_BASE_COVER = 200;
|
||||
public static final int LENGTH_BASE_THUMBNAIL = 100;
|
||||
|
||||
/** Can be thumbnail or cover */
|
||||
protected int imageType;
|
||||
|
||||
private static final String TAG = "BitmapDecodeWorkerTask";
|
||||
private ImageView target;
|
||||
protected Bitmap bitmap;
|
||||
private Bitmap decodedBitmap;
|
||||
|
||||
protected int baseLength;
|
||||
|
||||
protected String fileUrl;
|
||||
|
||||
private Handler handler;
|
||||
|
||||
public BitmapDecodeWorkerTask(Handler handler, ImageView target,
|
||||
String fileUrl, int length) {
|
||||
String fileUrl, int length, int imageType) {
|
||||
super();
|
||||
this.handler = handler;
|
||||
this.target = target;
|
||||
this.fileUrl = fileUrl;
|
||||
this.baseLength = length;
|
||||
this.PREFERRED_LENGTH = (int) (length * PodcastApp.getLogicalDensity() + 0.5f);
|
||||
if (PodcastApp.getInstance().isLargeScreen()) {
|
||||
this.PREFERRED_LENGTH *= 2.0;
|
||||
}
|
||||
this.PREFERRED_LENGTH = length;
|
||||
this.imageType = imageType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,9 +103,9 @@ public abstract class BitmapDecodeWorkerTask extends Thread {
|
|||
|
||||
protected void storeBitmapInCache(Bitmap bitmap) {
|
||||
FeedImageLoader loader = FeedImageLoader.getInstance();
|
||||
if (baseLength == LENGTH_BASE_COVER) {
|
||||
if (imageType == FeedImageLoader.IMAGE_TYPE_COVER) {
|
||||
loader.addBitmapToCoverCache(fileUrl, bitmap);
|
||||
} else if (baseLength == LENGTH_BASE_THUMBNAIL) {
|
||||
} else if (imageType == FeedImageLoader.IMAGE_TYPE_THUMBNAIL) {
|
||||
loader.addBitmapToThumbnailCache(fileUrl, bitmap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ public class FeedImageLoader {
|
|||
private static final String TAG = "FeedImageLoader";
|
||||
private static FeedImageLoader singleton;
|
||||
|
||||
public static final int LENGTH_BASE_COVER = 300;
|
||||
public static final int LENGTH_BASE_THUMBNAIL = 100;
|
||||
public static final int IMAGE_TYPE_THUMBNAIL = 0;
|
||||
public static final int IMAGE_TYPE_COVER = 1;
|
||||
|
||||
private static final String CACHE_DIR = "miroguide_thumbnails";
|
||||
private static final int CACHE_SIZE = 20 * 1024 * 1024;
|
||||
|
@ -45,7 +45,7 @@ public class FeedImageLoader {
|
|||
|
||||
// Use 1/8th of the available memory for this memory cache.
|
||||
final int coverCacheSize = 1024 * 1024 * memClass / 8;
|
||||
final int thumbnailCacheSize = 1024 * 1024 * memClass / 6;
|
||||
final int thumbnailCacheSize = 1024 * 1024 * memClass / 8;
|
||||
|
||||
private LruCache<String, Bitmap> coverCache;
|
||||
private LruCache<String, Bitmap> thumbnailCache;
|
||||
|
@ -103,6 +103,12 @@ public class FeedImageLoader {
|
|||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a bitmap from the cover cache. If the bitmap is not in the cache, it
|
||||
* will be loaded from the disk. This method should either be called if the
|
||||
* ImageView's size has already been set or inside a Runnable which is posted
|
||||
* to the ImageView's message queue.
|
||||
*/
|
||||
public void loadCoverBitmap(FeedImage image, ImageView target) {
|
||||
if (image != null && image.getFile_url() != null) {
|
||||
Bitmap bitmap = getBitmapFromCoverCache(image.getFile_url());
|
||||
|
@ -111,7 +117,8 @@ public class FeedImageLoader {
|
|||
} else {
|
||||
target.setImageResource(R.drawable.default_cover);
|
||||
FeedImageDecodeWorkerTask worker = new FeedImageDecodeWorkerTask(
|
||||
handler, target, image, LENGTH_BASE_COVER);
|
||||
handler, target, image, target.getHeight(),
|
||||
IMAGE_TYPE_COVER);
|
||||
executor.submit(worker);
|
||||
}
|
||||
} else {
|
||||
|
@ -119,6 +126,12 @@ public class FeedImageLoader {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a bitmap from the thumbnail cache. If the bitmap is not in the cache, it
|
||||
* will be loaded from the disk. This method should either be called if the
|
||||
* ImageView's size has already been set or inside a Runnable which is posted
|
||||
* to the ImageView's message queue.
|
||||
*/
|
||||
public void loadThumbnailBitmap(FeedImage image, ImageView target) {
|
||||
if (image != null && image.getFile_url() != null) {
|
||||
Bitmap bitmap = getBitmapFromThumbnailCache(image.getFile_url());
|
||||
|
@ -127,7 +140,8 @@ public class FeedImageLoader {
|
|||
} else {
|
||||
target.setImageResource(R.drawable.default_cover);
|
||||
FeedImageDecodeWorkerTask worker = new FeedImageDecodeWorkerTask(
|
||||
handler, target, image, LENGTH_BASE_THUMBNAIL);
|
||||
handler, target, image, target.getHeight(),
|
||||
IMAGE_TYPE_THUMBNAIL);
|
||||
executor.submit(worker);
|
||||
}
|
||||
} else {
|
||||
|
@ -135,7 +149,8 @@ public class FeedImageLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public void loadMiroGuideThumbnail(MiroGuideChannel channel, ImageView target) {
|
||||
public void loadMiroGuideThumbnail(MiroGuideChannel channel,
|
||||
ImageView target) {
|
||||
if (channel.getThumbnailUrl() != null) {
|
||||
Bitmap bitmap = getBitmapFromThumbnailCache(channel
|
||||
.getThumbnailUrl());
|
||||
|
@ -145,7 +160,7 @@ public class FeedImageLoader {
|
|||
target.setImageResource(R.drawable.default_cover);
|
||||
|
||||
executor.submit(new MiroGuideThumbnailDownloader(handler,
|
||||
target, channel, LENGTH_BASE_THUMBNAIL));
|
||||
target, channel, target.getHeight(), coverCacheSize));
|
||||
} else {
|
||||
target.setImageBitmap(bitmap);
|
||||
}
|
||||
|
@ -198,8 +213,8 @@ public class FeedImageLoader {
|
|||
protected FeedImage image;
|
||||
|
||||
public FeedImageDecodeWorkerTask(Handler handler, ImageView target,
|
||||
FeedImage image, int length) {
|
||||
super(handler, target, image.getFile_url(), length);
|
||||
FeedImage image, int length, int imageType) {
|
||||
super(handler, target, image.getFile_url(), length, imageType);
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
|
|||
private MiroGuideChannel miroChannel;
|
||||
|
||||
public MiroGuideThumbnailDownloader(Handler handler, ImageView target,
|
||||
MiroGuideChannel miroChannel, int length) {
|
||||
super(handler, target, miroChannel.getThumbnailUrl(), length);
|
||||
MiroGuideChannel miroChannel, int length, int imageType) {
|
||||
super(handler, target, miroChannel.getThumbnailUrl(), length, imageType);
|
||||
this.miroChannel = miroChannel;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,8 +83,15 @@ public class CoverFragment extends SherlockFragment {
|
|||
}
|
||||
|
||||
private void loadMediaInfo() {
|
||||
FeedImageLoader.getInstance().loadCoverBitmap(
|
||||
media.getItem().getFeed().getImage(), imgvCover);
|
||||
imgvCover.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
FeedImageLoader.getInstance().loadCoverBitmap(
|
||||
media.getItem().getFeed().getImage(), imgvCover);
|
||||
}
|
||||
});
|
||||
|
||||
txtvTitle.setText(media.getItem().getTitle());
|
||||
txtvFeed.setText(media.getItem().getFeed().getTitle());
|
||||
}
|
||||
|
|
|
@ -7,26 +7,12 @@ import android.util.Log;
|
|||
public class BitmapDecoder {
|
||||
private static final String TAG = "BitmapDecoder";
|
||||
|
||||
private static int calculateSampleSize(int preferredLength, int width,
|
||||
int height) {
|
||||
int max = Math.max(width, height);
|
||||
if (max < preferredLength) {
|
||||
return 1;
|
||||
} else {
|
||||
// find first sample size where max / sampleSize <
|
||||
// PREFERRED_LENGTH
|
||||
for (int sampleSize = 1, power = 0;; power++, sampleSize = (int) Math
|
||||
.pow(2, power)) {
|
||||
int newLength = max / sampleSize;
|
||||
if (newLength <= preferredLength) {
|
||||
if (newLength > 0) {
|
||||
return sampleSize;
|
||||
} else {
|
||||
return sampleSize - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static int calculateSampleSize(int preferredLength, int length) {
|
||||
int sampleSize = 1;
|
||||
if (length > preferredLength) {
|
||||
sampleSize = Math.round(((float) length / (float) preferredLength));
|
||||
}
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
public static Bitmap decodeBitmap(int preferredLength, String fileUrl) {
|
||||
|
@ -35,14 +21,13 @@ public class BitmapDecoder {
|
|||
BitmapFactory.decodeFile(fileUrl, options);
|
||||
int srcWidth = options.outWidth;
|
||||
int srcHeight = options.outHeight;
|
||||
int sampleSize = calculateSampleSize(preferredLength, srcWidth,
|
||||
srcHeight);
|
||||
|
||||
int length = Math.max(srcWidth, srcHeight);
|
||||
int sampleSize = calculateSampleSize(preferredLength, length);
|
||||
Log.d(TAG, "Using samplesize " + sampleSize);
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = sampleSize;
|
||||
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
options.inScaled = true;
|
||||
|
||||
|
||||
Bitmap decodedBitmap = BitmapFactory.decodeFile(fileUrl, options);
|
||||
if (decodedBitmap == null) {
|
||||
Log.i(TAG,
|
||||
|
@ -50,14 +35,6 @@ public class BitmapDecoder {
|
|||
+ fileUrl + ")");
|
||||
decodedBitmap = BitmapFactory.decodeFile(fileUrl);
|
||||
}
|
||||
if (decodedBitmap != null) {
|
||||
return decodedBitmap;
|
||||
/*
|
||||
return Bitmap.createScaledBitmap(decodedBitmap,
|
||||
preferredLength, preferredLength, false);
|
||||
*/
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return decodedBitmap;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue