Separate MediaView from MediaAdapter

This commit is contained in:
Christopher Eby 2011-09-21 16:27:36 -05:00
parent e94c40bdcb
commit 95a7a32e35
3 changed files with 365 additions and 298 deletions

View File

@ -24,22 +24,11 @@ package org.kreed.vanilla;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
@ -55,7 +44,7 @@ import java.io.Serializable;
* as limiting. Limiting is separate from filtering; a new filter will not
* erase an active filter. Limiting is intended to allow only media belonging
* to a specific group to be displayed, e.g. only songs from a certain artist.
* See MediaView.getLimiter and setLimiter for details.
* See getLimiter and setLimiter for details.
*/
public class MediaAdapter extends CursorAdapter implements SectionIndexer {
/**
@ -67,17 +56,17 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
* MediaUtils.FIELD_* constants. Determines which content provider to query for
* media and what fields to display.
*/
int mType;
private int mType;
/**
* The URI of the content provider backing this adapter.
*/
Uri mStore;
private Uri mStore;
/**
* The fields to use from the content provider. The last field will be
* displayed in the MediaView, as will the first field if there are
* multiple fields. Other fields will be used for searching.
*/
String[] mFields;
private String[] mFields;
/**
* The collation keys corresponding to each field. If provided, these are
* used to speed up sorting and filtering.
@ -86,7 +75,7 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
/**
* If true, show an expand arrow next the the text in each view.
*/
boolean mExpandable;
private boolean mExpandable;
/**
* A limiter is used for filtering. The intention is to restrict items
* displayed in the list to only those of a specific artist or album, as
@ -154,16 +143,6 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
default:
throw new IllegalArgumentException("Invalid value for type: " + type);
}
if (mPaint == null) {
Resources res = activity.getResources();
mExpander = BitmapFactory.decodeResource(res, R.drawable.expander_arrow);
mTextSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, res.getDisplayMetrics());
mPaint = new Paint();
mPaint.setTextSize(mTextSize);
mPaint.setAntiAlias(true);
}
}
/**
@ -263,6 +242,15 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
mActivity.changeCursor(this, cursor);
}
/**
* Return the type of media represented by this adapter. One of
* MediaUtils.TYPE_*.
*/
public int getMediaType()
{
return mType;
}
/**
* Set the limiter for the adapter. A limiter is intended to restrict
* displayed media to only those that are children of a given parent
@ -285,6 +273,42 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
return mLimiter;
}
/**
* Builds a limiter based off of the media represented by the given row.
*
* @param view The row to create the limiter from.
* @see MediaAdapter#getLimiter()
* @see MediaAdapter#setLimiter(MediaAdapter.Limiter)
*/
public Limiter getLimiter(MediaView view)
{
long id = view.getMediaId();
String[] fields;
String selection = null;
switch (mType) {
case MediaUtils.TYPE_ARTIST: {
fields = new String[] { view.getTitle() };
String field = MediaStore.Audio.Media.ARTIST_ID;
selection = String.format("%s=%d", field, id);
break;
}
case MediaUtils.TYPE_ALBUM: {
fields = new String[] { view.getSubTitle(), view.getTitle() };
String field = MediaStore.Audio.Media.ALBUM_ID;
selection = String.format("%s=%d", field, id);
break;
}
case MediaUtils.TYPE_GENRE:
fields = new String[] { view.getTitle() };
break;
default:
throw new IllegalStateException("getLimiter() is not supported for media type: " + mType);
}
return new MediaAdapter.Limiter(id, mType, selection, fields);
}
@Override
public void changeCursor(Cursor cursor)
{
@ -317,7 +341,7 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
@Override
public void bindView(View view, Context context, Cursor cursor)
{
((MediaView)view).updateMedia(cursor);
((MediaView)view).updateMedia(cursor, mFields.length > 1);
}
/**
@ -326,256 +350,7 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
return new MediaView(context);
}
/**
* The text size used for the text in all views.
*/
static int mTextSize;
/**
* The expander arrow bitmap used in all views that have expanders.
*/
static Bitmap mExpander;
/**
* The paint object, cached for reuse.
*/
static Paint mPaint;
/**
* The cached measured view height.
*/
int mViewHeight = -1;
/**
* The cached dash effect that separates the expander arrow and the text.
*/
DashPathEffect mDashEffect;
/**
* The cached divider gradient that separates each view from other views.
*/
RadialGradient mDividerGradient;
/**
* Single view that paints one or two text fields and an optional arrow
* to the right side.
*/
public class MediaView extends View {
/**
* The MediaStore id of the media represented by this view.
*/
private long mId;
/**
* The primary text field in the view, displayed on the upper line.
*/
private String mTitle;
/**
* The secondary text field in the view, displayed on the lower line.
*/
private String mSubTitle;
/**
* True if the last touch event was over the expander arrow.
*/
private boolean mExpanderPressed;
/**
* Construct a MediaView.
*
* @param context A Context to use.
*/
public MediaView(Context context)
{
super(context);
if (mViewHeight == -1)
mViewHeight = measureHeight();
}
/**
* Measure the height. Ideally this is cached and should only be called
* once.
*/
private int measureHeight()
{
int expanderHeight;
int textHeight;
if (mExpandable)
expanderHeight = mExpander.getHeight() + (int)mTextSize;
else
expanderHeight = 0;
if (mFields.length > 1)
textHeight = (int)(7 * mTextSize / 2);
else
textHeight = (int)(2 * mTextSize);
return Math.max(expanderHeight, textHeight);
}
/**
* Request the cached height and maximum width from the layout.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mViewHeight);
}
/**
* Draw the view on the given canvas.
*/
@Override
public void onDraw(Canvas canvas)
{
if (mTitle == null)
return;
int width = getWidth();
int height = getHeight();
int padding = mTextSize / 2;
Paint paint = mPaint;
if (mExpandable) {
Bitmap expander = mExpander;
width -= padding * 4 + expander.getWidth();
if (mDashEffect == null)
mDashEffect = new DashPathEffect(new float[] { 3, 3 }, 0);
paint.setColor(Color.GRAY);
paint.setPathEffect(mDashEffect);
canvas.drawLine(width, padding, width, height - padding, paint);
paint.setPathEffect(null);
canvas.drawBitmap(expander, width + padding * 2, (height - expander.getHeight()) / 2, paint);
}
canvas.save();
canvas.clipRect(padding, 0, width - padding, height);
int allocatedHeight;
if (mSubTitle != null) {
allocatedHeight = height / 2 - padding * 3 / 2;
paint.setColor(Color.GRAY);
canvas.drawText(mSubTitle, padding, height / 2 + padding / 2 + (allocatedHeight - mTextSize) / 2 - paint.ascent(), paint);
} else {
allocatedHeight = height - padding * 2;
}
paint.setColor(Color.WHITE);
canvas.drawText(mTitle, padding, padding + (allocatedHeight - mTextSize) / 2 - paint.ascent(), paint);
width = getWidth();
if (mDividerGradient == null)
mDividerGradient = new RadialGradient(width / 2, height, width / 2, Color.WHITE, Color.BLACK, Shader.TileMode.CLAMP);
paint.setShader(mDividerGradient);
canvas.restore();
canvas.drawLine(0, height, width, height, paint);
paint.setShader(null);
}
/**
* Returns the MediaStore id of the media represented by this view.
*/
public final long getMediaId()
{
return mId;
}
/**
* Returns the type of media contained in the adapter containing this
* view. Will be one of the Song.TYPE_* constants.
*/
public int getMediaType()
{
return mType;
}
/**
* Returns the title of this view, the primary/upper field.
*/
public final String getTitle()
{
return mTitle;
}
/**
* Returns true if the expander arrow was pressed in the last touch
* event.
*/
public final boolean isExpanderPressed()
{
return mExpanderPressed;
}
/**
* Returns true if views has expander arrows displayed.
*/
public final boolean hasExpanders()
{
return mExpandable;
}
/**
* Update the fields in this view with the data from the given Cursor.
*
* @param cursor A cursor moved to the correct position. The first
* column must be the id of the media, the second the primary field.
* If this adapter contains more than one field, the third column
* must contain the secondary field.
*/
public final void updateMedia(Cursor cursor)
{
mId = cursor.getLong(0);
mTitle = cursor.getString(1);
if (mFields.length > 1)
mSubTitle = cursor.getString(2);
invalidate();
}
/**
* Builds a limiter based off of the media represented by this view.
*
* @see MediaAdapter#getLimiter()
* @see MediaAdapter#setLimiter(MediaAdapter.Limiter)
*/
public final Limiter getLimiter()
{
String[] fields;
String field;
switch (mType) {
case MediaUtils.TYPE_ARTIST:
fields = new String[] { mTitle };
field = MediaStore.Audio.Media.ARTIST_ID;
break;
case MediaUtils.TYPE_ALBUM:
fields = new String[] { mSubTitle, mTitle };
field = MediaStore.Audio.Media.ALBUM_ID;
break;
case MediaUtils.TYPE_GENRE:
fields = new String[] { mTitle };
field = null;
break;
default:
throw new IllegalStateException("getLimiter() is not supported for media type: " + mType);
}
return new Limiter(mId, mType, field, fields);
}
/**
* Update mExpanderPressed.
*/
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (mExpandable)
mExpanderPressed = event.getX() > getWidth() - mExpander.getWidth() - 2 * mTextSize;
return false;
}
return new MediaView(context, this, mExpandable);
}
/**
@ -589,12 +364,12 @@ public class MediaAdapter extends CursorAdapter implements SectionIndexer {
public final int type;
public final String selection;
public Limiter(long id, int type, String field, String[] names)
public Limiter(long id, int type, String selection, String[] names)
{
this.type = type;
this.names = names;
this.id = id;
selection = field == null ? null : String.format("%s=%d", field, id);
this.selection = selection;
}
}
}

View File

@ -0,0 +1,278 @@
/*
* Copyright (C) 2010, 2011 Christopher Eby <kreed@kreed.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.kreed.vanilla;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
/**
* Single view that paints one or two text fields and an optional arrow
* to the right side.
*/
public final class MediaView extends View {
/**
* The expander arrow bitmap used in all views that have expanders.
*/
private static Bitmap sExpander;
/**
* The paint object, cached for reuse.
*/
private static Paint sPaint;
/**
* The cached dash effect that separates the expander arrow and the text.
*/
private static DashPathEffect sDashEffect;
/**
* The cached divider gradient that separates each view from other views.
*/
private static RadialGradient sDividerGradient;
/**
* The text size used for the text in all views.
*/
private static int sTextSize;
public static void init(Context context)
{
Resources res = context.getResources();
sExpander = BitmapFactory.decodeResource(res, R.drawable.expander_arrow);
sTextSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, res.getDisplayMetrics());
sDashEffect = new DashPathEffect(new float[] { 3, 3 }, 0);
sDividerGradient = null;
sPaint = new Paint();
sPaint.setTextSize(sTextSize);
sPaint.setAntiAlias(true);
}
/**
* The MediaAdapter that owns this view.
*/
private MediaAdapter mOwner;
/**
* The MediaStore id of the media represented by this view.
*/
private long mId;
/**
* The primary text field in the view, displayed on the upper line.
*/
private String mTitle;
/**
* The secondary text field in the view, displayed on the lower line.
*/
private String mSubTitle;
/**
* True if the last touch event was over the expander arrow.
*/
private boolean mExpanderPressed;
/**
* True if the expander should be shown.
*/
private boolean mExpandable;
/**
* The cached measured view height.
*/
private int mViewHeight;
/**
* Construct a MediaView.
*
* @param context A Context to use.
* @param owner The MediaAdapter that owns this view.
* @param expandable True if the expander should be shown.
*/
public MediaView(Context context, MediaAdapter owner, boolean expandable)
{
super(context);
mOwner = owner;
mExpandable = expandable;
mViewHeight = (int)(7 * sTextSize / 2);
if (expandable)
mViewHeight = Math.max(mViewHeight, sExpander.getHeight() + sTextSize);
}
/**
* Request the cached height and maximum width from the layout.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mViewHeight);
}
/**
* Draw the view on the given canvas.
*/
@Override
public void onDraw(Canvas canvas)
{
if (mTitle == null)
return;
int width = getWidth();
int height = getHeight();
int padding = sTextSize / 2;
Paint paint = sPaint;
if (mExpandable) {
Bitmap expander = sExpander;
width -= padding * 4 + expander.getWidth();
paint.setColor(Color.GRAY);
paint.setPathEffect(sDashEffect);
canvas.drawLine(width, padding, width, height - padding, paint);
paint.setPathEffect(null);
canvas.drawBitmap(expander, width + padding * 2, (height - expander.getHeight()) / 2, paint);
}
canvas.save();
canvas.clipRect(padding, 0, width - padding, height);
int allocatedHeight;
if (mSubTitle != null) {
allocatedHeight = height / 2 - padding * 3 / 2;
paint.setColor(Color.GRAY);
canvas.drawText(mSubTitle, padding, height / 2 + padding / 2 + (allocatedHeight - sTextSize) / 2 - paint.ascent(), paint);
} else {
allocatedHeight = height - padding * 2;
}
paint.setColor(Color.WHITE);
canvas.drawText(mTitle, padding, padding + (allocatedHeight - sTextSize) / 2 - paint.ascent(), paint);
canvas.restore();
width = getWidth();
if (sDividerGradient == null)
sDividerGradient = new RadialGradient(width / 2, 1, width / 2, Color.WHITE, Color.BLACK, Shader.TileMode.CLAMP);
paint.setShader(sDividerGradient);
canvas.drawLine(0, height - 1, width, height - 1, paint);
paint.setShader(null);
}
/**
* Returns the MediaAdapter that owns this view.
*/
public MediaAdapter getOwner()
{
return mOwner;
}
/**
* Returns the type of media this view represents.
*
* @return One of MediaUtils.TYPE_*.
*/
public int getMediaType()
{
return mOwner.getMediaType();
}
/**
* Returns the MediaStore id of the media represented by this view.
*/
public long getMediaId()
{
return mId;
}
/**
* Returns the title of this view, the primary/upper field.
*/
public String getTitle()
{
return mTitle;
}
/**
* Returns the secondary text in the view, displayed on the lower line.
*/
public String getSubTitle()
{
return mSubTitle;
}
/**
* Returns true if the expander arrow was pressed in the last touch
* event.
*/
public boolean isExpanderPressed()
{
return mExpanderPressed;
}
/**
* Returns true if views has expander arrows displayed.
*/
public boolean hasExpanders()
{
return mExpandable;
}
/**
* Update the fields in this view with the data from the given Cursor.
*
* @param cursor A cursor moved to the correct position. The first
* column must be the id of the media, the second the primary field.
* If this adapter contains more than one field, the third column
* must contain the secondary field.
* @param useSecondary True if the secondary field should be read.
*/
public void updateMedia(Cursor cursor, boolean useSecondary)
{
mId = cursor.getLong(0);
mTitle = cursor.getString(1);
if (useSecondary)
mSubTitle = cursor.getString(2);
invalidate();
}
/**
* Update mExpanderPressed.
*/
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (mExpandable)
mExpanderPressed = event.getX() > getWidth() - sExpander.getWidth() - 2 * sTextSize;
return false;
}
}

View File

@ -106,6 +106,8 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
{
super.onCreate(state);
MediaView.init(this);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
if (settings.getBoolean("controls_in_selector", false)) {
setContentView(R.layout.song_selector_controls);
@ -147,11 +149,12 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
mLimiterViews = (ViewGroup)findViewById(R.id.limiter_layout);
mArtistAdapter = setupView(R.id.artist_list, new MediaAdapter(this, MediaUtils.TYPE_ARTIST, true, null));
mAlbumAdapter = setupView(R.id.album_list, new MediaAdapter(this, MediaUtils.TYPE_ALBUM, true, state == null ? null : (MediaAdapter.Limiter)state.getSerializable("limiter_albums")));
mSongAdapter = setupView(R.id.song_list, new MediaAdapter(this, MediaUtils.TYPE_SONG, false, state == null ? null : (MediaAdapter.Limiter)state.getSerializable("limiter_songs")));
mPlaylistAdapter = setupView(R.id.playlist_list, new MediaAdapter(this, MediaUtils.TYPE_PLAYLIST, false, null));
mGenreAdapter = setupView(R.id.genre_list, new MediaAdapter(this, MediaUtils.TYPE_GENRE, true, state == null ? null : (MediaAdapter.Limiter)state.getSerializable("limiter_genres")));
mArtistAdapter = setupView(R.id.artist_list, MediaUtils.TYPE_ARTIST, true, null);
mAlbumAdapter = setupView(R.id.album_list, MediaUtils.TYPE_ALBUM, true, state == null ? null : (MediaAdapter.Limiter)state.getSerializable("limiter_albums"));
mSongAdapter = setupView(R.id.song_list, MediaUtils.TYPE_SONG, false, state == null ? null : (MediaAdapter.Limiter)state.getSerializable("limiter_songs"));
mPlaylistAdapter = setupView(R.id.playlist_list, MediaUtils.TYPE_PLAYLIST, false, null);
mGenreAdapter = setupView(R.id.genre_list, MediaUtils.TYPE_GENRE, true, state == null ? null : (MediaAdapter.Limiter)state.getSerializable("limiter_genres"));
// These should be in the same order as MediaUtils.TYPE_*
mAdapters = new MediaAdapter[] { mArtistAdapter, mAlbumAdapter, mSongAdapter, mPlaylistAdapter, mGenreAdapter };
getContentResolver().registerContentObserver(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, true, mPlaylistObserver);
@ -239,7 +242,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
* @param view The MediaView to get type/id data from
* @param action One of SongSelector.ACTION_*
*/
private void pickSongs(MediaAdapter.MediaView view, int action)
private void pickSongs(MediaView view, int action)
{
PlaybackService service = PlaybackService.get(this);
int type = view.getMediaType();
@ -275,9 +278,15 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
mLastActedId = id;
}
private void expand(MediaAdapter.MediaView view)
/**
* "Expand" the view by setting the limiter from the given view and
* switching to the appropriate tab.
*
* @param view The view to expand from.
*/
private void expand(MediaView view)
{
mTabHost.setCurrentTab(setLimiter(view.getLimiter()));
mTabHost.setCurrentTab(setLimiter(view.getOwner().getLimiter(view)));
}
/**
@ -317,7 +326,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
public void onItemClick(AdapterView<?> list, View view, int pos, long id)
{
MediaAdapter.MediaView mediaView = (MediaAdapter.MediaView)view;
MediaView mediaView = (MediaView)view;
if (mediaView.isExpanderPressed())
expand(mediaView);
else if (id == mLastActedId)
@ -444,7 +453,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
@Override
public void onCreateContextMenu(ContextMenu menu, View listView, ContextMenu.ContextMenuInfo absInfo)
{
MediaAdapter.MediaView view = (MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)absInfo).targetView;
MediaView view = (MediaView)((AdapterView.AdapterContextMenuInfo)absInfo).targetView;
int type = view.getMediaType();
int id = (int)view.getMediaId();
@ -521,13 +530,13 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
switch (id) {
case MENU_EXPAND:
expand((MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView);
expand((MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView);
break;
case MENU_ENQUEUE:
pickSongs((MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView, ACTION_ENQUEUE);
pickSongs((MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView, ACTION_ENQUEUE);
break;
case MENU_PLAY:
pickSongs((MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView, ACTION_PLAY);
pickSongs((MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView, ACTION_PLAY);
break;
case MENU_NEW_PLAYLIST: {
NewPlaylistDialog dialog = new NewPlaylistDialog(this, null, R.string.create);
@ -538,7 +547,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
break;
}
case MENU_RENAME_PLAYLIST: {
MediaAdapter.MediaView view = (MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
MediaView view = (MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
NewPlaylistDialog dialog = new NewPlaylistDialog(this, view.getTitle(), R.string.rename);
Message message = mHandler.obtainMessage(MSG_RENAME_PLAYLIST, view.getMediaType(), (int)view.getMediaId());
message.obj = dialog;
@ -547,7 +556,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
break;
}
case MENU_DELETE: {
MediaAdapter.MediaView view = (MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
MediaView view = (MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
type = view.getMediaType();
if (type != MediaUtils.TYPE_PLAYLIST)
Toast.makeText(this, R.string.deleting, Toast.LENGTH_SHORT).show();
@ -557,7 +566,7 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
break;
}
case MENU_EDIT:
MediaAdapter.MediaView view = (MediaAdapter.MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
MediaView view = (MediaView)((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).targetView;
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
intent.putExtra("playlist", String.valueOf(view.getMediaId()));
@ -599,17 +608,22 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
* Hook up a ListView to this Activity and the supplied adapter
*
* @param id The id of the ListView
* @param adapter The adapter to be used
* @param type The media type for the adapter.
* @param expandable True if the rows are expandable.
* @param limiter The initial limiter to set on the adapter.
*/
private MediaAdapter setupView(int id, MediaAdapter adapter)
private MediaAdapter setupView(int id, int type, boolean expandable, MediaAdapter.Limiter limiter)
{
ListView view = (ListView)findViewById(id);
view.setOnItemClickListener(this);
view.setOnCreateContextMenuListener(this);
view.setAdapter(adapter);
view.setCacheColorHint(Color.BLACK);
view.setDivider(null);
view.setFastScrollEnabled(true);
MediaAdapter adapter = new MediaAdapter(this, type, expandable, limiter);
view.setAdapter(adapter);
return adapter;
}