Sort order not working with listView and cursor loader
Asked Answered
B

1

6

I have a listView that is populated by a cursor from a cursor loader, and using content provider. I want to sort the listView so that it is arranged for example the most recent items are added at the top of the listView. The listView always comes up in the same order and I am not able to change this order.

I tried using sort order and changing it and no matter what it is set to the listView always shows the items in the same positions. Using the sort order like this,

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

I have tried to sort by other columns besides TIME_STAMP but the result is always the same. the order of the items in the list never changes. even changing ASC to DESC has no effect.

How can I set the order or position of items that are displayed in the listView that is populated with a cursorAdapter?

some more code samples from the listview class

From the onCreate method

    adapter = new ViewAdapter(this, null, 0);

// sets array adapter to listview
listViewOne.setAdapter(adapter);

getLoaderManager().initLoader(LOADER_ID_ONE, null, this);

Three callback methods of 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

This is the string used to create the table in the database extends 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 " + ");";

The cursor adapter class

 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);

}

} 

CONTENT PROVIDER CLASS full code here

 // 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
Banana answered 29/4, 2014 at 8:47 Comment(3)
Just in case - to get most recent items use DESC instead of ASCMizzen
Also, please provide code of your ContentProviderMizzen
i just added the code for the content provider class, Database that extends ContentProviderBanana
M
9

It seems that you're not delivering sorting-order parameter to database connection instance itself, so result doesn't gets sorted. Make sure that you're delegating all parameters in ContentProvider#query method to SQLiteDatabase.

So, your SQLiteQueryBuilder#build method should look like this:

Cursor queryCursor = builder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
Mizzen answered 29/4, 2014 at 9:4 Comment(2)
@Banana yep, fixed that :)Mizzen
YES!!! IT WORKS NOW. you are correct that I did not deliver the sort parameter to the SQL database and that was the problem.Banana

© 2022 - 2024 — McMap. All rights reserved.