Removed search button on main tab, it was redundant, added Exit button. Removed Help and Settings from remaining tabs. Start redesign of the Download tab

This commit is contained in:
Joshua Bahnsen 2012-05-29 18:11:58 -07:00
parent feca33c9ac
commit 97890e8929
9 changed files with 330 additions and 385 deletions

View File

@ -189,12 +189,13 @@
a:layout_alignParentLeft="true" a:layout_alignParentLeft="true"
a:layout_toLeftOf="@+id/download_control_layout" a:layout_toLeftOf="@+id/download_control_layout"
> >
<FrameLayout <FrameLayout
a:id="@+id/download_album_art_layout" a:id="@+id/download_album_art_layout"
a:layout_width="fill_parent" a:layout_width="fill_parent"
a:layout_height="fill_parent" a:layout_height="fill_parent"
a:background="@drawable/album_art_background"> a:background="@drawable/pinstripe_tile" >
<ImageView <ImageView
a:id="@+id/download_album_art_image" a:id="@+id/download_album_art_image"
a:layout_width="wrap_content" a:layout_width="wrap_content"

View File

@ -9,14 +9,14 @@
a:layout_width="fill_parent" a:layout_width="fill_parent"
a:layout_height="0dip" a:layout_height="0dip"
a:layout_weight="1"> a:layout_weight="1">
<RelativeLayout <RelativeLayout
a:id="@+id/download_album_art_layout" a:id="@+id/download_album_art_layout"
a:orientation="vertical" a:layout_width="fill_parent"
a:layout_width="fill_parent" a:layout_height="fill_parent"
a:layout_height="fill_parent" a:layout_weight="1"
a:layout_weight="1" a:background="@drawable/pinstripe_tile"
a:background="@drawable/album_art_background"> a:orientation="vertical" >
<ImageButton <ImageButton
a:id="@+id/download_repeat" a:id="@+id/download_repeat"

View File

@ -52,7 +52,7 @@
a:scaleType="center" a:scaleType="center"
a:showAsAction="ifRoom|withText" a:showAsAction="ifRoom|withText"
a:src="@drawable/ic_menu_help" /> a:src="@drawable/ic_menu_help" />
<ImageButton <ImageButton
a:id="@+id/action_button_4" a:id="@+id/action_button_4"
a:layout_width="wrap_content" a:layout_width="wrap_content"
@ -63,8 +63,8 @@
a:padding="5dp" a:padding="5dp"
a:scaleType="center" a:scaleType="center"
a:showAsAction="ifRoom|withText" a:showAsAction="ifRoom|withText"
a:src="@drawable/ic_menu_settings" /> a:src="@drawable/ic_menu_exit" />
<ImageButton <ImageButton
a:id="@+id/action_button_1" a:id="@+id/action_button_1"
a:layout_width="wrap_content" a:layout_width="wrap_content"
@ -75,8 +75,8 @@
a:padding="5dp" a:padding="5dp"
a:scaleType="center" a:scaleType="center"
a:showAsAction="ifRoom|withText" a:showAsAction="ifRoom|withText"
a:src="@drawable/ic_menu_search" /> a:src="@drawable/ic_menu_shuffle" />
<ImageButton <ImageButton
a:id="@+id/action_button_2" a:id="@+id/action_button_2"
a:layout_width="wrap_content" a:layout_width="wrap_content"
@ -87,6 +87,6 @@
a:padding="5dp" a:padding="5dp"
a:scaleType="center" a:scaleType="center"
a:showAsAction="ifRoom|withText" a:showAsAction="ifRoom|withText"
a:src="@drawable/ic_menu_shuffle" /> a:src="@drawable/ic_menu_settings" />
</RelativeLayout> </RelativeLayout>

View File

@ -118,20 +118,8 @@ public class MainActivity extends SubsonicTabActivity {
// Title: Subsonic // Title: Subsonic
setTitle(R.string.common_appname); setTitle(R.string.common_appname);
// Button 1: search // Button 1: shuffle
ImageButton actionSearchButton = (ImageButton)findViewById(R.id.action_button_1); ImageButton actionShuffleButton = (ImageButton)findViewById(R.id.action_button_1);
actionSearchButton.setImageResource(R.drawable.ic_menu_search);
actionSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SearchActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_REQUEST_SEARCH, true);
Util.startActivityWithoutTransition(MainActivity.this, intent);
}
});
// Button 2: shuffle
ImageButton actionShuffleButton = (ImageButton)findViewById(R.id.action_button_2);
actionShuffleButton.setImageResource(R.drawable.ic_menu_shuffle); actionShuffleButton.setImageResource(R.drawable.ic_menu_shuffle);
actionShuffleButton.setOnClickListener(new View.OnClickListener() { actionShuffleButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -141,7 +129,17 @@ public class MainActivity extends SubsonicTabActivity {
Util.startActivityWithoutTransition(MainActivity.this, intent); Util.startActivityWithoutTransition(MainActivity.this, intent);
} }
}); });
// Button 2: settings
ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_2);
actionSettingsButton.setImageResource(R.drawable.ic_menu_settings);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
}
});
// Button 3: help // Button 3: help
ImageButton actionHelpButton = (ImageButton)findViewById(R.id.action_button_3); ImageButton actionHelpButton = (ImageButton)findViewById(R.id.action_button_3);
actionHelpButton.setImageResource(R.drawable.ic_menu_help); actionHelpButton.setImageResource(R.drawable.ic_menu_help);
@ -151,14 +149,14 @@ public class MainActivity extends SubsonicTabActivity {
startActivity(new Intent(MainActivity.this, HelpActivity.class)); startActivity(new Intent(MainActivity.this, HelpActivity.class));
} }
}); });
// Button 4: settings // Button 4: exit
ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_4); ImageButton actionSearchButton = (ImageButton)findViewById(R.id.action_button_4);
actionSettingsButton.setImageResource(R.drawable.ic_menu_settings); actionSearchButton.setImageResource(R.drawable.ic_menu_exit);
actionSettingsButton.setOnClickListener(new View.OnClickListener() { actionSearchButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
startActivity(new Intent(MainActivity.this, SettingsActivity.class)); exit();
} }
}); });

View File

@ -138,8 +138,14 @@ public class SearchActivity extends SubsonicTabActivity {
// Button 1: gone // Button 1: gone
findViewById(R.id.action_button_1).setVisibility(View.GONE); findViewById(R.id.action_button_1).setVisibility(View.GONE);
// Button 2: search // Button 2: gone
final ImageButton actionSearchButton = (ImageButton)findViewById(R.id.action_button_2); findViewById(R.id.action_button_2).setVisibility(View.GONE);
// Button 3: gone
findViewById(R.id.action_button_3).setVisibility(View.GONE);
// Button 4: search
final ImageButton actionSearchButton = (ImageButton)findViewById(R.id.action_button_4);
actionSearchButton.setImageResource(R.drawable.ic_menu_search); actionSearchButton.setImageResource(R.drawable.ic_menu_search);
actionSearchButton.setOnClickListener(new View.OnClickListener() { actionSearchButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -147,26 +153,6 @@ public class SearchActivity extends SubsonicTabActivity {
onSearchRequested(); onSearchRequested();
} }
}); });
// Button 3: help
ImageButton actionHelpButton = (ImageButton)findViewById(R.id.action_button_3);
actionHelpButton.setImageResource(R.drawable.ic_menu_help);
actionHelpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SearchActivity.this, HelpActivity.class));
}
});
// Button 4: settings
ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_4);
actionSettingsButton.setImageResource(R.drawable.ic_menu_settings);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SearchActivity.this, SettingsActivity.class));
}
});
onNewIntent(getIntent()); onNewIntent(getIntent());
} }

View File

@ -170,8 +170,14 @@ public class SelectAlbumActivity extends SubsonicTabActivity {
getMusicDirectory(id, name); getMusicDirectory(id, name);
} }
// Button 1: play all // Button 1: gone
playAllButton = (ImageButton) findViewById(R.id.action_button_1); findViewById(R.id.action_button_1).setVisibility(View.GONE);
// Button 2: gone
findViewById(R.id.action_button_2).setVisibility(View.GONE);
// Button 3: play all
playAllButton = (ImageButton) findViewById(R.id.action_button_3);
playAllButton.setImageResource(R.drawable.ic_menu_play_all); playAllButton.setImageResource(R.drawable.ic_menu_play_all);
playAllButton.setVisibility(View.GONE); playAllButton.setVisibility(View.GONE);
playAllButton.setOnClickListener(new View.OnClickListener() { playAllButton.setOnClickListener(new View.OnClickListener() {
@ -181,8 +187,8 @@ public class SelectAlbumActivity extends SubsonicTabActivity {
} }
}); });
// Button 2: refresh // Button 4: refresh
ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_2); ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_4);
refreshButton.setImageResource(R.drawable.ic_menu_refresh); refreshButton.setImageResource(R.drawable.ic_menu_refresh);
refreshButton.setOnClickListener(new View.OnClickListener() { refreshButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -190,26 +196,6 @@ public class SelectAlbumActivity extends SubsonicTabActivity {
refresh(); refresh();
} }
}); });
// Button 3: help
ImageButton actionHelpButton = (ImageButton)findViewById(R.id.action_button_3);
actionHelpButton.setImageResource(R.drawable.ic_menu_help);
actionHelpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SelectAlbumActivity.this, HelpActivity.class));
}
});
// Button 4: settings
ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_4);
actionSettingsButton.setImageResource(R.drawable.ic_menu_settings);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SelectAlbumActivity.this, SettingsActivity.class));
}
});
} }
private void playAll() { private void playAll() {

View File

@ -76,8 +76,14 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter
setTitle(Util.isOffline(this) ? R.string.music_library_label_offline : R.string.music_library_label); setTitle(Util.isOffline(this) ? R.string.music_library_label_offline : R.string.music_library_label);
// Button 1: shuffle // Button 1: gone
ImageButton shuffleButton = (ImageButton) findViewById(R.id.action_button_1); findViewById(R.id.action_button_1).setVisibility(View.GONE);
// Button 2: gone
findViewById(R.id.action_button_2).setVisibility(View.GONE);
// Button 3: shuffle
ImageButton shuffleButton = (ImageButton) findViewById(R.id.action_button_3);
shuffleButton.setImageResource(R.drawable.ic_menu_shuffle); shuffleButton.setImageResource(R.drawable.ic_menu_shuffle);
shuffleButton.setOnClickListener(new View.OnClickListener() { shuffleButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -88,8 +94,8 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter
} }
}); });
// Button 2: refresh // Button 4: refresh
ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_2); ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_4);
refreshButton.setImageResource(R.drawable.ic_menu_refresh); refreshButton.setImageResource(R.drawable.ic_menu_refresh);
refreshButton.setOnClickListener(new View.OnClickListener() { refreshButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -97,26 +103,8 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter
refresh(); refresh();
} }
}); });
// Button 3: help
ImageButton actionHelpButton = (ImageButton)findViewById(R.id.action_button_3);
actionHelpButton.setImageResource(R.drawable.ic_menu_help);
actionHelpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SelectArtistActivity.this, HelpActivity.class));
}
});
// Button 4: settings
ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_4);
actionSettingsButton.setImageResource(R.drawable.ic_menu_settings);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SelectArtistActivity.this, SettingsActivity.class));
}
});
musicFolders = null; musicFolders = null;
load(); load();

View File

@ -60,12 +60,17 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt
// Title: Playlists // Title: Playlists
setTitle(R.string.playlist_label); setTitle(R.string.playlist_label);
// Button 1: gone // Button 1: gone
ImageButton searchButton = (ImageButton)findViewById(R.id.action_button_1); findViewById(R.id.action_button_1).setVisibility(View.GONE);
searchButton.setVisibility(View.GONE);
// Button 2: refresh // Button 2: gone
ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_2); findViewById(R.id.action_button_2).setVisibility(View.GONE);
// Button 3: gone
findViewById(R.id.action_button_3).setVisibility(View.GONE);
// Button 4: refresh
ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_4);
refreshButton.setImageResource(R.drawable.ic_menu_refresh); refreshButton.setImageResource(R.drawable.ic_menu_refresh);
refreshButton.setOnClickListener(new View.OnClickListener() { refreshButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -73,26 +78,6 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt
refresh(); refresh();
} }
}); });
// Button 3: help
ImageButton actionHelpButton = (ImageButton)findViewById(R.id.action_button_3);
actionHelpButton.setImageResource(R.drawable.ic_menu_help);
actionHelpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SelectPlaylistActivity.this, HelpActivity.class));
}
});
// Button 4: settings
ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_4);
actionSettingsButton.setImageResource(R.drawable.ic_menu_settings);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SelectPlaylistActivity.this, SettingsActivity.class));
}
});
load(); load();
} }

View File

@ -1,252 +1,253 @@
/* /*
This file is part of Subsonic. This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Subsonic is distributed in the hope that it will be useful, Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>. along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009 (C) Sindre Mehus Copyright 2009 (C) Sindre Mehus
*/ */
package net.sourceforge.subsonic.androidapp.util; package net.sourceforge.subsonic.androidapp.util;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.LinearGradient; import android.graphics.LinearGradient;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Shader; import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable; import android.graphics.drawable.TransitionDrawable;
import android.os.Handler; import android.os.Handler;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import net.sourceforge.subsonic.androidapp.R; import net.sourceforge.subsonic.androidapp.R;
import net.sourceforge.subsonic.androidapp.domain.MusicDirectory; import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
import net.sourceforge.subsonic.androidapp.service.MusicService; import net.sourceforge.subsonic.androidapp.service.MusicService;
import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory; import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
/** /**
* Asynchronous loading of images, with caching. * Asynchronous loading of images, with caching.
* <p/> * <p/>
* There should normally be only one instance of this class. * There should normally be only one instance of this class.
* *
* @author Sindre Mehus * @author Sindre Mehus
*/ */
public class ImageLoader implements Runnable { public class ImageLoader implements Runnable {
private static final String TAG = ImageLoader.class.getSimpleName(); private static final String TAG = ImageLoader.class.getSimpleName();
private static final int CONCURRENCY = 5; private static final int CONCURRENCY = 5;
private final LRUCache<String, Drawable> cache = new LRUCache<String, Drawable>(100); private final LRUCache<String, Drawable> cache = new LRUCache<String, Drawable>(100);
private final BlockingQueue<Task> queue; private final BlockingQueue<Task> queue;
private final int imageSizeDefault; private final int imageSizeDefault;
private final int imageSizeLarge; private final int imageSizeLarge;
private Drawable largeUnknownImage; private Drawable largeUnknownImage;
public ImageLoader(Context context) { public ImageLoader(Context context) {
queue = new LinkedBlockingQueue<Task>(500); queue = new LinkedBlockingQueue<Task>(500);
// Determine the density-dependent image sizes. // Determine the density-dependent image sizes.
imageSizeDefault = context.getResources().getDrawable(R.drawable.unknown_album).getIntrinsicHeight(); imageSizeDefault = context.getResources().getDrawable(R.drawable.unknown_album).getIntrinsicHeight();
DisplayMetrics metrics = context.getResources().getDisplayMetrics(); DisplayMetrics metrics = context.getResources().getDisplayMetrics();
imageSizeLarge = (int) Math.round(Math.min(metrics.widthPixels, metrics.heightPixels) * 0.6); /*imageSizeLarge = (int) Math.round(Math.min(metrics.widthPixels, metrics.heightPixels) * 0.6);*/
imageSizeLarge = (int) Math.round(Math.min(metrics.widthPixels, metrics.heightPixels));
for (int i = 0; i < CONCURRENCY; i++) {
new Thread(this, "ImageLoader").start(); for (int i = 0; i < CONCURRENCY; i++) {
} new Thread(this, "ImageLoader").start();
}
createLargeUnknownImage(context);
} createLargeUnknownImage(context);
}
private void createLargeUnknownImage(Context context) {
BitmapDrawable drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.unknown_album_large); private void createLargeUnknownImage(Context context) {
Bitmap bitmap = Bitmap.createScaledBitmap(drawable.getBitmap(), imageSizeLarge, imageSizeLarge, true); BitmapDrawable drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.unknown_album_large);
bitmap = createReflection(bitmap); Bitmap bitmap = Bitmap.createScaledBitmap(drawable.getBitmap(), imageSizeLarge, imageSizeLarge, true);
largeUnknownImage = Util.createDrawableFromBitmap(context, bitmap); bitmap = createReflection(bitmap);
} largeUnknownImage = Util.createDrawableFromBitmap(context, bitmap);
}
public void loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
if (entry == null || entry.getCoverArt() == null) { public void loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
setUnknownImage(view, large); if (entry == null || entry.getCoverArt() == null) {
return; setUnknownImage(view, large);
} return;
}
int size = large ? imageSizeLarge : imageSizeDefault;
Drawable drawable = cache.get(getKey(entry.getCoverArt(), size)); int size = large ? imageSizeLarge : imageSizeDefault;
if (drawable != null) { Drawable drawable = cache.get(getKey(entry.getCoverArt(), size));
setImage(view, drawable, large); if (drawable != null) {
return; setImage(view, drawable, large);
} return;
}
if (!large) {
setUnknownImage(view, large); if (!large) {
} setUnknownImage(view, large);
queue.offer(new Task(view, entry, size, large, large, crossfade)); }
} queue.offer(new Task(view, entry, size, false, large, crossfade));
}
private String getKey(String coverArtId, int size) {
return coverArtId + size; private String getKey(String coverArtId, int size) {
} return coverArtId + size;
}
private void setImage(View view, Drawable drawable, boolean crossfade) {
if (view instanceof TextView) { private void setImage(View view, Drawable drawable, boolean crossfade) {
// Cross-fading is not implemented for TextView since it's not in use. It would be easy to add it, though. if (view instanceof TextView) {
TextView textView = (TextView) view; // Cross-fading is not implemented for TextView since it's not in use. It would be easy to add it, though.
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null); TextView textView = (TextView) view;
} else if (view instanceof ImageView) { textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
ImageView imageView = (ImageView) view; } else if (view instanceof ImageView) {
if (crossfade) { ImageView imageView = (ImageView) view;
if (crossfade) {
Drawable existingDrawable = imageView.getDrawable();
if (existingDrawable == null) { Drawable existingDrawable = imageView.getDrawable();
Bitmap emptyImage = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); if (existingDrawable == null) {
existingDrawable = new BitmapDrawable(emptyImage); Bitmap emptyImage = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
} existingDrawable = new BitmapDrawable(emptyImage);
}
Drawable[] layers = new Drawable[]{existingDrawable, drawable};
Drawable[] layers = new Drawable[]{existingDrawable, drawable};
TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
imageView.setImageDrawable(transitionDrawable); TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
transitionDrawable.startTransition(250); imageView.setImageDrawable(transitionDrawable);
} else { transitionDrawable.startTransition(250);
imageView.setImageDrawable(drawable); } else {
} imageView.setImageDrawable(drawable);
} }
} }
}
private void setUnknownImage(View view, boolean large) {
if (large) { private void setUnknownImage(View view, boolean large) {
setImage(view, largeUnknownImage, false); if (large) {
} else { setImage(view, largeUnknownImage, false);
if (view instanceof TextView) { } else {
((TextView) view).setCompoundDrawablesWithIntrinsicBounds(R.drawable.unknown_album, 0, 0, 0); if (view instanceof TextView) {
} else if (view instanceof ImageView) { ((TextView) view).setCompoundDrawablesWithIntrinsicBounds(R.drawable.unknown_album, 0, 0, 0);
((ImageView) view).setImageResource(R.drawable.unknown_album); } else if (view instanceof ImageView) {
} ((ImageView) view).setImageResource(R.drawable.unknown_album);
} }
} }
}
public void clear() {
queue.clear(); public void clear() {
} queue.clear();
}
@Override
public void run() { @Override
while (true) { public void run() {
try { while (true) {
Task task = queue.take(); try {
task.execute(); Task task = queue.take();
} catch (Throwable x) { task.execute();
Log.e(TAG, "Unexpected exception in ImageLoader.", x); } catch (Throwable x) {
} Log.e(TAG, "Unexpected exception in ImageLoader.", x);
} }
} }
}
private Bitmap createReflection(Bitmap originalImage) {
private Bitmap createReflection(Bitmap originalImage) {
int width = originalImage.getWidth();
int height = originalImage.getHeight(); int width = originalImage.getWidth();
int height = originalImage.getHeight();
// The gap we want between the reflection and the original image
final int reflectionGap = 4; // The gap we want between the reflection and the original image
final int reflectionGap = 4;
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix(); // This will not scale but will flip on the Y axis
matrix.preScale(1, -1); Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// Create a Bitmap with the flip matix applied to it.
// We only want the bottom half of the image // Create a Bitmap with the flip matix applied to it.
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false); // We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Bitmap.Config.ARGB_8888); // Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Bitmap.Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection // Create a new Canvas with the bitmap that's big enough for
Canvas canvas = new Canvas(bitmapWithReflection); // the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null); // Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint defaultPaint = new Paint(); // Draw in the gap
canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint); Paint defaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
// Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); // Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
// Create a shader that is a linear gradient that covers the reflection
Paint paint = new Paint(); // Create a shader that is a linear gradient that covers the reflection
LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, Paint paint = new Paint();
bitmapWithReflection.getHeight() + reflectionGap, 0x70000000, 0xff000000, LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0,
Shader.TileMode.CLAMP); bitmapWithReflection.getHeight() + reflectionGap, 0x70000000, 0xff000000,
Shader.TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader); // Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); // Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);
return bitmapWithReflection;
} return bitmapWithReflection;
}
private class Task {
private final View view; private class Task {
private final MusicDirectory.Entry entry; private final View view;
private final Handler handler; private final MusicDirectory.Entry entry;
private final int size; private final Handler handler;
private final boolean reflection; private final int size;
private final boolean saveToFile; private final boolean reflection;
private final boolean crossfade; private final boolean saveToFile;
private final boolean crossfade;
public Task(View view, MusicDirectory.Entry entry, int size, boolean reflection, boolean saveToFile, boolean crossfade) {
this.view = view; public Task(View view, MusicDirectory.Entry entry, int size, boolean reflection, boolean saveToFile, boolean crossfade) {
this.entry = entry; this.view = view;
this.size = size; this.entry = entry;
this.reflection = reflection; this.size = size;
this.saveToFile = saveToFile; this.reflection = reflection;
this.crossfade = crossfade; this.saveToFile = saveToFile;
handler = new Handler(); this.crossfade = crossfade;
} handler = new Handler();
}
public void execute() {
try { public void execute() {
MusicService musicService = MusicServiceFactory.getMusicService(view.getContext()); try {
Bitmap bitmap = musicService.getCoverArt(view.getContext(), entry, size, saveToFile, null); MusicService musicService = MusicServiceFactory.getMusicService(view.getContext());
Bitmap bitmap = musicService.getCoverArt(view.getContext(), entry, size, saveToFile, null);
if (reflection) {
bitmap = createReflection(bitmap); if (reflection) {
} bitmap = createReflection(bitmap);
}
final Drawable drawable = Util.createDrawableFromBitmap(view.getContext(), bitmap);
cache.put(getKey(entry.getCoverArt(), size), drawable); final Drawable drawable = Util.createDrawableFromBitmap(view.getContext(), bitmap);
cache.put(getKey(entry.getCoverArt(), size), drawable);
handler.post(new Runnable() {
@Override handler.post(new Runnable() {
public void run() { @Override
setImage(view, drawable, crossfade); public void run() {
} setImage(view, drawable, crossfade);
}); }
} catch (Throwable x) { });
Log.e(TAG, "Failed to download album art.", x); } catch (Throwable x) {
} Log.e(TAG, "Failed to download album art.", x);
} }
} }
} }
}