问题
I use CursorLoader to query a result, which is not the order that I want to show in the ListFramgenet. How to sort it ?
I use this to set the adapter:
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_2, null,
new String[] { "name", "distance"},
new int[] { android.R.id.text1, android.R.id.text2 }, 0);
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
Create loader :
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
Uri.withAppendedPath(TraceTable.CONTENT_URI, "latest"),
MEMBERS_PROJECTION,
null,
null,
null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.changeCursor(data);
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
Well, there are latitude and longitude the queried results. I want to calculate the distance between my location and these results. and sort by distance asc.
How to sort it? Any answer will be appricated
回答1:
It's actually quite easy:
from this:
new CursorLoader(getActivity(),
Uri.withAppendedPath(TraceTable.CONTENT_URI, "latest"),
MEMBERS_PROJECTION,
null,
null,
null);
to this:
// You could have them calculated in the projection like this:
String[] projection = { COLUMN1 + " * " + COLUMN2 + " as data", // Whatever your calculations are
COLUMN1, COLUMN2, COLUMN3, etc.. };
new CursorLoader(getActivity(),
Uri.withAppendedPath(TraceTable.CONTENT_URI, "latest"),
projection,
null,
null,
"data ASC");
Remember that if you have some method in your provider that does a check to the projection and rise an exception, you would have to comment it out for the moment you are doing the test or add the new column (the one you do the calculation with) to your official projection array.
回答2:
What you're looking for is supplying a sortOrder
argument something like the following:
(the ORDER BY
at the start of this is implicait and you do not include it, simply included here for clarity)
ORDER BY 6366000*acos(cos(lat_a / (180/3.14169))*cos(lng_a / (180/3.14169))*cos(lat_b / (180/3.14169))*cos(lng_b / (180/3.14169)) + t2 + t3) ASC
(for this I took the answer here and inlined it - except I didn't bother with t2 and t3, because it's not going to work anyway)
Unfortunately, this is impossible in standard SQLite - there are no operators sin
, or cos
- or even a square root or power operator (after seeing your comment about only requiring a more simple calculation).
You can add your own functions, but that's a somewhat more complicated route.
Depending on how many rows you have, you might be alright to just read them all and then sort them yourself.
回答3:
Provide the column names you want to sort on as the last parameter of the CursorLoader() constructor as a string. If you have more than one column to sort by, separate with a comma. If you want ascending as opposed to descending, add DESC after the column name. So pretty much what you would add after 'ORDER BY' in regular SQL syntax.
EDIT: To answer your comment below.
Yes and no. I believe you could use that as your sort order but SQLite does not have a sqrt or power function. However you can define your own SQLite functions or use a 3rd party extension. If you don't want to go that route, you'll have to use your own custom adapter instead of SimpleCursorAdapter, e.g. you would get the cursor results and then sort them in code into another data stucture which would become the datasource of your adapter.
回答4:
Just add ContactsContract.Contacts.SORT_KEY_PRIMARY
.
来源:https://stackoverflow.com/questions/20686415/how-to-sort-the-cursorloader-results