Порядок сортировки не работает с listView и загрузчиком курсора

У меня есть listView, который заполняется курсором из загрузчика курсора и использует контент-провайдера. Я хочу сортировать listView так, чтобы он был организован, например, самые последние элементы добавлены в верхней части спискаView. ListView всегда появляется в том же порядке, и я не могу изменить этот порядок.

Я пробовал использовать порядок сортировки и менял его, и независимо от того, что он установлен, listView всегда показывает позиции в тех же позициях. Используя порядок сортировки, подобный этому,

CursorLoader loader = new CursorLoader (List.this, Database.CONTENT_URI, projection, null, null, LocationsTable.TIME_STAMP + " ASC"); 

Я попытался сортировать другие столбцы, кроме TIME_STAMP, но результат всегда один и тот же. Порядок элементов в списке никогда не изменяется. Даже изменение ASC в DESC не влияет.

Как установить порядок или позицию элементов, отображаемых в listView, заполненном курсоромAdapter?

Еще несколько примеров кода из класса listview

Из метода onCreate

  adapter = new ViewAdapter(this, null, 0); // sets array adapter to listview listViewOne.setAdapter(adapter); getLoaderManager().initLoader(LOADER_ID_ONE, null, this); 

Три метода обратного вызова LoaderCallbacks<Cursor>

  @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String projection[] = new String[]{LocationsTable._ID, LocationsTable.LATITUDE, LocationsTable.LONGITUDE, LocationsTable.LAND_ADDRESS, LocationsTable.LAST_NAME, LocationsTable.FIRST_NAME, LocationsTable.LOCATION_IMAGE, LocationsTable.TIME_STAMP }; CursorLoader loader = new CursorLoader (List.this, Database.CONTENT_URI, projection, null, null, LocationsTable.TIME_STAMP + " ASC"); return loader; } // onCreateLoader @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { adapter.swapCursor(cursor); } // onLoadFinished @Override public void onLoaderReset(Loader<Cursor> arg0) { adapter.swapCursor(null); } // onLoaderReset 

Это строка, используемая для создания таблицы в базе данных, расширяет ContentProvider

  private static final String SQL_QUERY_CREATE = "CREATE TABLE " + LocationsTable.TABLE_NAME + " (" + LocationsTable._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + LocationsTable.LATITUDE + " TEXT NOT NULL, " + LocationsTable.LONGITUDE + " TEXT NOT NULL, " + LocationsTable.LAND_ADDRESS + " TEXT, " + LocationsTable.LAST_NAME + " TEXT, " + LocationsTable.FIRST_NAME + " TEXT, " + LocationsTable.LAST_NAME_ALT + " TEXT, " + LocationsTable.FIRST_NAME_ALT + " TEXT, " + LocationsTable.CONTACT_ADDRESS + " TEXT, " + LocationsTable.PHONE_NUMBER + " TEXT, " + LocationsTable.MOBILE_NUMBER + " TEXT, " + LocationsTable.EMAIL + " TEXT, " + LocationsTable.LOCATION_IMAGE + " TEXT, " + LocationsTable.TIME_STAMP_IMAGE + " INTEGER, " + LocationsTable.TIME_STAMP + " INTEGER " + ");"; 

Класс адаптера курсора

  public class ViewAdapter extends CursorAdapter { LayoutInflater inflater; LatAndLngString latAndLng; public ViewAdapter(Context context, Cursor cursor, int b) { super(context, cursor, b); inflater = LayoutInflater.from(context); } // ViewAdapter constructor @Override public void bindView(View view, final Context context, Cursor cursor) { TextView textViewOne = (TextView) view.findViewById(R.id.textView1); // address TextView textViewTwo = (TextView) view.findViewById(R.id.textView2); // last name TextView textViewThree = (TextView) view.findViewById(R.id.textView3); // first name final Button buttonOne = (Button) view.findViewById(R.id.button1); final ImageView imageViewOne = (ImageView) view.findViewById(R.id.imageView1); final ImageView imageViewTwo = (ImageView) view.findViewById(R.id.imageView2); textViewOne.setText(cursor.getString(cursor.getColumnIndex(LocationsTable.LAND_ADDRESS))); textViewTwo.setText(cursor.getString(cursor.getColumnIndex(LocationsTable.LAST_NAME))); textViewThree.setText(cursor.getString(cursor.getColumnIndex(LocationsTable.FIRST_NAME))); String latitude = cursor.getString(cursor.getColumnIndex(LocationsTable.LATITUDE)); String longitude = cursor.getString(cursor.getColumnIndex(LocationsTable.LONGITUDE)); String imagePath = cursor.getString(cursor.getColumnIndex(LocationsTable.LOCATION_IMAGE)); long timeStampImage = cursor.getLong(cursor.getColumnIndex(LocationsTable.TIME_STAMP)); if(imagePath != null){ int widthInDP = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics()); int heightInDP = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()); Bitmap sizedBitmap = ImageUtil.createReducedBitmap(imagePath, widthInDP, heightInDP); imageViewTwo.setImageBitmap(sizedBitmap); } textViewOne.setMaxLines(1); textViewTwo.setMaxLines(2); textViewThree.setMaxLines(3); final LatAndLngString latAndLng = new LatAndLngString(latitude, longitude); buttonOne.setTag(latAndLng); imageViewOne.setTag(latAndLng); imageViewTwo.setTag(latAndLng); // go to register page to edit fields buttonOne.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { ((Button) view).setAlpha(0.3f); LatAndLngString latAndLngRow = (LatAndLngString) buttonOne.getTag(); Intent intent = new Intent(List.this, Register.class); intent.putExtra("latitude", String.valueOf(latAndLngRow.latitude)); intent.putExtra("longitude", String.valueOf(latAndLngRow.longitude)); intent.putExtra("origin", 1); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); List.this.startActivity(intent); return true; } else if (event.getAction() == MotionEvent.ACTION_UP) { ((Button) view).setAlpha(1.0f); return true; } return false; } }); // go to map page to display map imageViewOne.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { ((ImageView) view).setAlpha(0.3f); LatAndLngString latAndLngRow = (LatAndLngString) buttonOne.getTag(); Intent intent = new Intent(List.this, Map.class); intent.putExtra("latitude", String.valueOf(latAndLngRow.latitude)); intent.putExtra("longitude", String.valueOf(latAndLngRow.longitude)); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra("showMarker", true); List.this.startActivity(intent); return true; } else if (event.getAction() == MotionEvent.ACTION_UP) { ((ImageView) view).setAlpha(1.0f); return true; } return false; } }); // set image for button imageViewTwo.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { ((ImageView) view).setAlpha(0.3f); LatAndLngString latAndLngRow = (LatAndLngString) view.getTag(); Intent intent = new Intent(List.this, ImageSelector.class); intent.putExtra("latitude", String.valueOf(latAndLngRow.latitude)); intent.putExtra("longitude", String.valueOf(latAndLngRow.longitude)); List.this.startActivity(intent); return true; } else if (event.getAction() == MotionEvent.ACTION_UP) { ((ImageView) view).setAlpha(1.0f); return true; } return false; } }); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return inflater.inflate(R.layout.listview_row, parent, false); } } 

СОДЕРЖАНИЕ ПОСТАВЩИКОВ КЛАСС полный код здесь

  // application package name // import statements public class Database extends ContentProvider { private static final UriMatcher sUriMatcher; private static final int LOCATIONS_ALL = 1; private static final int LOCATIONS_ONE = 2; public static final String AUTHORITY = "com.xxx.realestatelocator.Locations"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/locations"); public static final String DATABASE_NAME = "locations.db"; public static final int DATABASE_VERSION = 1; public static final String CONTENT_TYPE_NOTES_ALL = "vnd.android.cursor.dir/vnd.realestate.locations"; public static final String CONTENT_TYPE_NOTES_ONE = "vnd.android.cursor.item/vnd.realestate.locations"; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(AUTHORITY, "locations", LOCATIONS_ALL); sUriMatcher.addURI(AUTHORITY, "locations/#", LOCATIONS_ONE); } // Map table columns private static final HashMap<String, String> sNotesColumnProjectionMap; private DatabaseHelper mDbHelper; static { sNotesColumnProjectionMap = new HashMap<String, String>(); sNotesColumnProjectionMap.put(LocationsTable._ID, LocationsTable._ID); sNotesColumnProjectionMap.put(LocationsTable.LATITUDE, LocationsTable.LATITUDE); sNotesColumnProjectionMap.put(LocationsTable.LONGITUDE, LocationsTable.LONGITUDE); sNotesColumnProjectionMap.put(LocationsTable.LAND_ADDRESS, LocationsTable.LAND_ADDRESS); sNotesColumnProjectionMap.put(LocationsTable.LAST_NAME, LocationsTable.LAST_NAME); sNotesColumnProjectionMap.put(LocationsTable.FIRST_NAME, LocationsTable.FIRST_NAME); sNotesColumnProjectionMap.put(LocationsTable.LAST_NAME_ALT, LocationsTable.LAST_NAME_ALT); sNotesColumnProjectionMap.put(LocationsTable.FIRST_NAME_ALT, LocationsTable.FIRST_NAME_ALT); sNotesColumnProjectionMap.put(LocationsTable.CONTACT_ADDRESS, LocationsTable.CONTACT_ADDRESS); sNotesColumnProjectionMap.put(LocationsTable.PHONE_NUMBER, LocationsTable.PHONE_NUMBER); sNotesColumnProjectionMap.put(LocationsTable.MOBILE_NUMBER, LocationsTable.MOBILE_NUMBER); sNotesColumnProjectionMap.put(LocationsTable.EMAIL, LocationsTable.EMAIL); sNotesColumnProjectionMap.put(LocationsTable.LOCATION_IMAGE, LocationsTable.LOCATION_IMAGE); sNotesColumnProjectionMap.put(LocationsTable.TIME_STAMP_IMAGE, LocationsTable.TIME_STAMP_IMAGE); sNotesColumnProjectionMap.put(LocationsTable.TIME_STAMP, LocationsTable.TIME_STAMP); } public class LocationsTable implements BaseColumns { public static final String TABLE_NAME = "tbl_locations"; public static final String _ID = "_id"; public static final String LATITUDE = "latitude"; public static final String LONGITUDE = "longitude"; public static final String LAND_ADDRESS = "land_address"; public static final String LAST_NAME = "last_name"; public static final String FIRST_NAME = "first_name"; public static final String LAST_NAME_ALT = "last_name_alt"; public static final String FIRST_NAME_ALT = "first_name_alt"; public static final String CONTACT_ADDRESS = "contact_address"; public static final String PHONE_NUMBER = "phone_number"; public static final String MOBILE_NUMBER = "mobile_number"; public static final String EMAIL = "email_address"; public static final String LOCATION_IMAGE = "location_image"; public static final String TIME_STAMP_IMAGE = "time_stamp_image"; public static final String TIME_STAMP = "time_stamp"; } // LocationsTable inner class private static class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } private static final String SQL_QUERY_CREATE = "CREATE TABLE " + LocationsTable.TABLE_NAME + " (" + LocationsTable._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + LocationsTable.LATITUDE + " TEXT NOT NULL, " + LocationsTable.LONGITUDE + " TEXT NOT NULL, " + LocationsTable.LAND_ADDRESS + " TEXT, " + LocationsTable.LAST_NAME + " TEXT, " + LocationsTable.FIRST_NAME + " TEXT, " + LocationsTable.LAST_NAME_ALT + " TEXT, " + LocationsTable.FIRST_NAME_ALT + " TEXT, " + LocationsTable.CONTACT_ADDRESS + " TEXT, " + LocationsTable.PHONE_NUMBER + " TEXT, " + LocationsTable.MOBILE_NUMBER + " TEXT, " + LocationsTable.EMAIL + " TEXT, " + LocationsTable.LOCATION_IMAGE + " TEXT, " + LocationsTable.TIME_STAMP_IMAGE + " INTEGER, " + LocationsTable.TIME_STAMP + " INTEGER " + ");"; private static final String SQL_QUERY_DROP = "DROP TABLE IF EXISTS " + LocationsTable.TABLE_NAME + ";"; @Override public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_QUERY_CREATE); } // onCreate @Override public void onUpgrade(SQLiteDatabase db, int oldVer, int newVer) { db.execSQL(SQL_QUERY_DROP); onCreate(db); } // onUpgrade } // DatabaseHelper inner class @Override public boolean onCreate() { if(mDbHelper == null) { mDbHelper = new DatabaseHelper(getContext()); } return false; } @Override public String getType(Uri arg0) { return null; } // getType // insert one new row, full row @Override public Uri insert(Uri uri, ContentValues values) { if (sUriMatcher.match(uri) != LOCATIONS_ALL) { throw new IllegalArgumentException(" Unknown URI: " + uri); } SQLiteDatabase db = mDbHelper.getWritableDatabase(); long rowId = db.insert(LocationsTable.TABLE_NAME, null, values); if (rowId > 0) { Uri notesUri = ContentUris.withAppendedId(CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(notesUri, null); return notesUri; } throw new IllegalArgumentException("<Illegal>Unknown URI: " + uri); } // insert @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) { case LOCATIONS_ALL: builder.setTables(LocationsTable.TABLE_NAME); builder.setProjectionMap(sNotesColumnProjectionMap); break; case LOCATIONS_ONE: builder.setTables(LocationsTable.TABLE_NAME); builder.setProjectionMap(sNotesColumnProjectionMap); builder.appendWhere(LocationsTable._ID + " = " + uri.getLastPathSegment()); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } SQLiteDatabase db = mDbHelper.getReadableDatabase(); Cursor queryCursor = builder.query(db, projection, selection, selectionArgs, null, null, null); queryCursor.setNotificationUri(getContext().getContentResolver(), uri); return queryCursor; } // query @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { SQLiteDatabase db = mDbHelper.getWritableDatabase(); int count = 0; switch (sUriMatcher.match(uri)) { case LOCATIONS_ALL: count = db.update(LocationsTable.TABLE_NAME, values, where, whereArgs); break; case LOCATIONS_ONE: String rowId = uri.getLastPathSegment(); count = db.update(LocationsTable.TABLE_NAME, values, LocationsTable._ID + " = " + rowId + (!TextUtils.isEmpty(where) ? " AND (" + ")" : ""), whereArgs); default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } // update // delete @Override public int delete(Uri uri, String where, String[] whereArgs) { SQLiteDatabase db = mDbHelper.getWritableDatabase(); int count = 0; switch (sUriMatcher.match(uri)) { case LOCATIONS_ALL: count = db.delete(LocationsTable.TABLE_NAME, where, whereArgs); break; case LOCATIONS_ONE: String rowId = uri.getPathSegments().get(1); count = db.delete(LocationsTable.TABLE_NAME, LocationsTable._ID + " = " + rowId + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } // delete } // Database 

    Кажется, что вы не доставляете параметр порядка сортировки самому экземпляру подключения к базе данных, поэтому результат не сортируется. Убедитесь, что вы делегируете все параметры в методе SQLiteDatabase ContentProvider#query SQLiteDatabase .

    Итак, ваш SQLiteQueryBuilder#build должен выглядеть так:

     Cursor queryCursor = builder.query(db, projection, selection, selectionArgs, null, null, sortOrder);