Separate MediaView from MediaAdapter
This commit is contained in:
parent
e94c40bdcb
commit
95a7a32e35
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
278
src/org/kreed/vanilla/MediaView.java
Normal file
278
src/org/kreed/vanilla/MediaView.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user