Created
July 7, 2015 09:36
-
-
Save rfreitas/ab46edbdc41500b20357 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.text.Normalizer; | |
import android.database.Cursor; | |
import android.database.CursorWrapper; | |
import android.util.Log; | |
//by Ricardo derfreitas@gmail.com | |
//ref: https://gist.github.com/ramzes642/5400792 (the position retrieved is not correct) | |
//ref: http://stackoverflow.com/a/7343721/689223 (doesn't do string filtering) | |
//the two code bases were merged to get the best of both worlds | |
//also added was an option to remove accents from UTF strings | |
public class FilterCursorWrapper extends CursorWrapper { | |
private static final String TAG = FilterCursorWrapper.class.getSimpleName(); | |
private String filter; | |
private int column; | |
private int[] filterMap; | |
private int mPos = -1; | |
private int mCount = 0; | |
public FilterCursorWrapper(Cursor cursor,String filter,int column) { | |
super(cursor); | |
this.filter = deAccent(filter).toLowerCase(); | |
Log.d(TAG, "filter:"+this.filter); | |
this.column = column; | |
int count = super.getCount(); | |
if (this.filter != "") { | |
this.filterMap = new int[count]; | |
int filteredCount = 0; | |
for (int i=0;i<count;i++) { | |
super.moveToPosition(i); | |
if (deAccent(this.getString(this.column)).toLowerCase().contains(this.filter)){ | |
this.filterMap[filteredCount] = i; | |
filteredCount++; | |
} | |
} | |
this.mCount = filteredCount; | |
} else { | |
this.filterMap = new int[count]; | |
this.mCount = count; | |
for (int i=0;i<count;i++) { | |
this.filterMap[i] = i; | |
} | |
} | |
this.moveToFirst(); | |
} | |
public int getCount() { return this.mCount; } | |
@Override | |
public boolean moveToPosition(int position) { | |
Log.d(TAG,"moveToPosition:"+position); | |
// Make sure position isn't past the end of the cursor | |
final int count = getCount(); | |
if (position >= count) { | |
mPos = count; | |
return false; | |
} | |
// Make sure position isn't before the beginning of the cursor | |
if (position < 0) { | |
mPos = -1; | |
return false; | |
} | |
final int realPosition = filterMap[position]; | |
// When moving to an empty position, just pretend we did it | |
boolean moved = realPosition == -1 ? true : super.moveToPosition(realPosition); | |
if (moved) { | |
mPos = position; | |
} else { | |
mPos = -1; | |
} | |
Log.d(TAG,"end moveToPosition:"+position); | |
return moved; | |
} | |
@Override | |
public final boolean move(int offset) { | |
return moveToPosition(mPos + offset); | |
} | |
@Override | |
public final boolean moveToFirst() { | |
return moveToPosition(0); | |
} | |
@Override | |
public final boolean moveToLast() { | |
return moveToPosition(getCount() - 1); | |
} | |
@Override | |
public final boolean moveToNext() { | |
return moveToPosition(mPos + 1); | |
} | |
@Override | |
public final boolean moveToPrevious() { | |
return moveToPosition(mPos - 1); | |
} | |
@Override | |
public final boolean isFirst() { | |
return mPos == 0 && getCount() != 0; | |
} | |
@Override | |
public final boolean isLast() { | |
int cnt = getCount(); | |
return mPos == (cnt - 1) && cnt != 0; | |
} | |
@Override | |
public final boolean isBeforeFirst() { | |
if (getCount() == 0) { | |
return true; | |
} | |
return mPos == -1; | |
} | |
@Override | |
public final boolean isAfterLast() { | |
if (getCount() == 0) { | |
return true; | |
} | |
return mPos == getCount(); | |
} | |
@Override | |
public int getPosition() { | |
return mPos; | |
} | |
//added by Ricardo | |
//ref: http://stackoverflow.com/a/22612054/689223 | |
//other: http://stackoverflow.com/questions/8523631/remove-accents-from-string | |
//other: http://stackoverflow.com/questions/15190656/easy-way-to-remove-utf-8-accents-from-a-string | |
public static String deAccent(String str) { | |
//return StringUtils.stripAccents(str);//this method from apache.commons respects chinese characters, but it's slower than flattenToAscii | |
return flattenToAscii(str); | |
} | |
//ref: http://stackoverflow.com/a/15191508/689223 | |
//this is the fastest method using the normalizer found yet, the ones using Regex are too slow | |
public static String flattenToAscii(String string) { | |
char[] out = new char[string.length()]; | |
string = Normalizer.normalize(string, Normalizer.Form.NFD); | |
int j = 0; | |
for (int i = 0, n = string.length(); i < n; ++i) { | |
char c = string.charAt(i); | |
if (c <= '\u007F') out[j++] = c; | |
} | |
return new String(out); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment