Make limiters work again

This commit is contained in:
Christopher Eby 2010-03-17 18:04:23 -05:00
parent ab543e3871
commit 6bbd34952a
4 changed files with 96 additions and 73 deletions

View File

@ -40,24 +40,20 @@ public class MediaAdapter extends BaseAdapter implements Filterable {
private List<Song> mObjects; private List<Song> mObjects;
private Song[] mAllObjects; private Song[] mAllObjects;
private ArrayFilter mFilter; private ArrayFilter mFilter;
private int mLimiterField = -1; private SongData mLimiter;
private Song mLimiterMedia; private CharSequence mPublishedFilter;
private CharSequence mLastFilter; private int mPublishedLimiter;
private int mPrimaryField; private int mPrimaryField;
private int mSecondaryField; private int mSecondaryField;
public MediaAdapter(Context context, Song[] allObjects, int primaryField, int secondaryField) public MediaAdapter(Context context, Song[] allObjects, int primaryField, int secondaryField, View.OnClickListener expanderListener)
{ {
mContext = context; mContext = context;
mAllObjects = allObjects; mAllObjects = allObjects;
mPrimaryField = primaryField; mPrimaryField = primaryField;
mSecondaryField = secondaryField; mSecondaryField = secondaryField;
} mExpanderListener = expanderListener;
public void setExpanderListener(View.OnClickListener listener)
{
mExpanderListener = listener;
} }
@Override @Override
@ -116,29 +112,41 @@ public class MediaAdapter extends BaseAdapter implements Filterable {
} }
private class ArrayFilter extends Filter { private class ArrayFilter extends Filter {
class ArrayFilterResults extends FilterResults {
public int limiterHash;
public ArrayFilterResults(List<Song> list, int limiterHash)
{
values = list;
count = list.size();
this.limiterHash = limiterHash;
}
}
@Override @Override
protected FilterResults performFiltering(CharSequence filter) protected FilterResults performFiltering(CharSequence filter)
{ {
FilterResults results = new FilterResults(); List<Song> list;
int limiterHash = mLimiter == null ? 0 : mLimiter.hashCode();
boolean noFilter = filter == null || filter.length() == 0; if (filter != null && filter.length() == 0)
filter = null;
if (mLastFilter.equals(filter)) { if ((filter == null && mPublishedFilter == null || mPublishedFilter != null && mPublishedFilter.equals(filter)) && mPublishedLimiter == limiterHash) {
results.values = mObjects; list = mObjects;
results.count = mObjects.size(); } else if (filter == null && mLimiter == null) {
} else if (noFilter && mLimiterField == -1) { list = Arrays.asList(mAllObjects);
results.values = Arrays.asList(mAllObjects);
results.count = mAllObjects.length;
} else { } else {
Matcher[] matchers = null; Matcher[] matchers = null;
if (!noFilter) { if (filter != null) {
String[] words = filter.toString().split("\\s+"); String[] words = filter.toString().split("\\s+");
matchers = new Matcher[words.length]; matchers = new Matcher[words.length];
for (int i = words.length; --i != -1; ) for (int i = words.length; --i != -1; )
matchers[i] = createMatcher(words[i]); matchers[i] = createMatcher(words[i]);
} }
int limiterId = mLimiterField == -1 ? 0 : mLimiterMedia.getFieldId(mLimiterField); int limiterField = mLimiter == null ? -1 : mLimiter.field;
int limiterId = mLimiter == null ? -1 : mLimiter.media.getFieldId(limiterField);
int count = mAllObjects.length; int count = mAllObjects.length;
ArrayList<Song> newValues = new ArrayList<Song>(); ArrayList<Song> newValues = new ArrayList<Song>();
@ -148,10 +156,10 @@ public class MediaAdapter extends BaseAdapter implements Filterable {
for (int i = 0; i != count; ++i) { for (int i = 0; i != count; ++i) {
Song song = mAllObjects[i]; Song song = mAllObjects[i];
if (mLimiterField != -1 && song.getFieldId(mLimiterField) != limiterId) if (limiterField != -1 && song.getFieldId(limiterField) != limiterId)
continue; continue;
if (!noFilter) { if (filter != null) {
for (int j = matchers.length; --j != -1; ) { for (int j = matchers.length; --j != -1; ) {
if (matchers[j].reset(song.artist).find()) if (matchers[j].reset(song.artist).find())
continue; continue;
@ -168,19 +176,20 @@ public class MediaAdapter extends BaseAdapter implements Filterable {
newValues.trimToSize(); newValues.trimToSize();
results.values = newValues; list = newValues;
results.count = newValues.size();
} }
return results; return new ArrayFilterResults(list, limiterHash);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
protected void publishResults(CharSequence constraint, FilterResults results) protected void publishResults(CharSequence filter, FilterResults results)
{ {
mObjects = (List<Song>)results.values; mObjects = (List<Song>)results.values;
mLastFilter = constraint; mPublishedFilter = filter == null || filter.length() == 0 ? null : filter;
mPublishedLimiter = ((ArrayFilterResults)results).limiterHash;
if (results.count == 0) if (results.count == 0)
notifyDataSetInvalidated(); notifyDataSetInvalidated();
else else
@ -194,22 +203,15 @@ public class MediaAdapter extends BaseAdapter implements Filterable {
notifyDataSetInvalidated(); notifyDataSetInvalidated();
} }
public void setLimiter(int field, Song media) public void setLimiter(SongData limiter)
{ {
mLimiterField = field; mLimiter = limiter;
mLimiterMedia = media; getFilter().filter(mPublishedFilter);
getFilter().filter(mLastFilter);
} }
public int getLimiterField() public SongData getLimiter()
{ {
return mLimiterField; return mLimiter;
}
public Song getLimiterMedia()
{
return mLimiterMedia;
} }
public int getCount() public int getCount()

View File

@ -139,28 +139,18 @@ public class MediaView extends ViewGroup {
if (mSecondaryLine != null) if (mSecondaryLine != null)
mSecondaryLine.setText(song.getField(secondaryField)); mSecondaryLine.setText(song.getField(secondaryField));
if (mExpander != null) { if (mExpander != null) {
ExpanderData data = null; SongData data = null;
try { try {
data = (ExpanderData)mExpander.getTag(); data = (SongData)mExpander.getTag();
} catch (ClassCastException e) { } catch (ClassCastException e) {
} }
if (data == null) { if (data == null) {
data = new ExpanderData(primaryField); data = new SongData(primaryField, null);
mExpander.setTag(data); mExpander.setTag(data);
} }
data.media = song; data.media = song;
} }
} }
public static class ExpanderData {
public ExpanderData(int field)
{
this.field = field;
}
public int field;
public Song media;
}
} }

View File

@ -302,3 +302,30 @@ public class Song implements Parcelable {
return result; return result;
} }
} }
class SongData {
public SongData(int field, Song media)
{
this.field = field;
this.media = media;
}
public SongData(SongData other)
{
this.field = other.field;
this.media = other.media;
}
public SongData()
{
}
@Override
public int hashCode()
{
return (field << 29) + media.getFieldId(field);
}
public int field;
public Song media;
}

View File

@ -53,7 +53,8 @@ public class SongSelector extends TabActivity implements AdapterView.OnItemClick
private TabHost mTabHost; private TabHost mTabHost;
private TextView mTextFilter; private TextView mTextFilter;
private View mClearButton; private View mClearButton;
private ViewGroup mLimiters;
private ViewGroup mLimiterViews;
private int mDefaultAction; private int mDefaultAction;
private boolean mDefaultIsLastAction; private boolean mDefaultIsLastAction;
@ -73,10 +74,7 @@ public class SongSelector extends TabActivity implements AdapterView.OnItemClick
ListView view = (ListView)findViewById(id); ListView view = (ListView)findViewById(id);
view.setOnItemClickListener(this); view.setOnItemClickListener(this);
view.setOnCreateContextMenuListener(this); view.setOnCreateContextMenuListener(this);
view.setAdapter(new MediaAdapter(SongSelector.this, songs, lineA, lineB, this));
MediaAdapter adapter = new MediaAdapter(SongSelector.this, songs, lineA, lineB);
adapter.setExpanderListener(this);
view.setAdapter(adapter);
} }
@Override @Override
@ -102,7 +100,7 @@ public class SongSelector extends TabActivity implements AdapterView.OnItemClick
mClearButton = findViewById(R.id.clear_button); mClearButton = findViewById(R.id.clear_button);
mClearButton.setOnClickListener(this); mClearButton.setOnClickListener(this);
mLimiters = (ViewGroup)findViewById(R.id.limiter_layout); mLimiterViews = (ViewGroup)findViewById(R.id.limiter_layout);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
int inputType; int inputType;
@ -180,37 +178,36 @@ public class SongSelector extends TabActivity implements AdapterView.OnItemClick
private void updateLimiterViews() private void updateLimiterViews()
{ {
if (mLimiters == null) if (mLimiterViews == null)
return; return;
mLimiters.removeAllViews(); mLimiterViews.removeAllViews();
MediaAdapter adapter = getAdapter(mTabHost.getCurrentTab()); MediaAdapter adapter = getAdapter(mTabHost.getCurrentTab());
if (adapter == null) if (adapter == null)
return; return;
int field = adapter.getLimiterField(); SongData limiter = adapter.getLimiter();
if (field == -1) if (limiter == null)
return; return;
Song media = adapter.getLimiterMedia();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.leftMargin = 5; params.leftMargin = 5;
for (int i = Song.FIELD_ARTIST; i <= field; ++i) { for (int i = Song.FIELD_ARTIST; i <= limiter.field; ++i) {
PaintDrawable background = new PaintDrawable(Color.GRAY); PaintDrawable background = new PaintDrawable(Color.GRAY);
background.setCornerRadius(5); background.setCornerRadius(5);
TextView view = new TextView(this); TextView view = new TextView(this);
view.setSingleLine(); view.setSingleLine();
view.setEllipsize(TextUtils.TruncateAt.MARQUEE); view.setEllipsize(TextUtils.TruncateAt.MARQUEE);
view.setText(media.getField(i) + " | X"); view.setText(limiter.media.getField(i) + " | X");
view.setTextColor(Color.WHITE); view.setTextColor(Color.WHITE);
view.setBackgroundDrawable(background); view.setBackgroundDrawable(background);
view.setLayoutParams(params); view.setLayoutParams(params);
view.setPadding(5, 2, 5, 2); view.setPadding(5, 2, 5, 2);
view.setTag(new MediaView.ExpanderData(i)); view.setTag(new SongData(i, null));
view.setOnClickListener(this); view.setOnClickListener(this);
mLimiters.addView(view); mLimiterViews.addView(view);
} }
} }
@ -224,9 +221,9 @@ public class SongSelector extends TabActivity implements AdapterView.OnItemClick
if (view == mClearButton) { if (view == mClearButton) {
mTextFilter.setText(""); mTextFilter.setText("");
} else { } else {
MediaView.ExpanderData data = null; SongData data = null;
try { try {
data = (MediaView.ExpanderData)view.getTag(); data = (SongData)view.getTag();
} catch (ClassCastException e) { } catch (ClassCastException e) {
} }
@ -234,18 +231,25 @@ public class SongSelector extends TabActivity implements AdapterView.OnItemClick
return; return;
if (view instanceof TextView) { if (view instanceof TextView) {
int newField = data.field == Song.FIELD_ARTIST ? -1 : data.field - 1; SongData limiter = getAdapter(mTabHost.getCurrentTab()).getLimiter();
for (int i = mTabHost.getChildCount(); --i != -1; ) { int field = data.field - 1;
if (limiter.field == 0)
limiter = null;
else
limiter.field = field;
for (int i = 3; --i != -1; ) {
MediaAdapter adapter = getAdapter(i); MediaAdapter adapter = getAdapter(i);
if (adapter.getLimiterField() >= data.field) SongData currentLimiter = adapter.getLimiter();
adapter.setLimiter(newField, adapter.getLimiterMedia()); if (currentLimiter != null && currentLimiter.field > field)
adapter.setLimiter(limiter);
} }
updateLimiterViews(); updateLimiterViews();
} else { } else {
SongData limiter = new SongData(data);
for (int i = data.field; i != 3; ++i) { for (int i = data.field; i != 3; ++i) {
MediaAdapter adapter = getAdapter(i); MediaAdapter adapter = getAdapter(i);
adapter.setLimiter(data.field, data.media);
adapter.hideAll(); adapter.hideAll();
adapter.setLimiter(limiter);
} }
mTabHost.setCurrentTab(data.field); mTabHost.setCurrentTab(data.field);
} }