Search code examples
androidsqliteandroid-listviewandroid-sqliteandroid-cursoradapter

android-How to use CursorAdapter to fill listView and recycling them


I used to fill listView with arrayAdapter and recycle them to do faster and reduce ram usage . I want to do the same with CursorAdapter ,I mean I want to read data( lots of data , about 500 rows ) with images and show them . What is the best way to do this ? What should I do and where I can learn what to do . I've searched but I'm really confuse now ,I'm a new to android.

Thanks


Solution

  • Here is an Example with comments to show you how to recycle the views in CursorAdapter that has 2 textViews as an Item in the List.

    here is the class ViewHolder to hold the elements and call them once.

    public class ViewHolder {
    
        TextView tvTitle, tvGenre;
        public ViewHolder(View row)
        {
            tvTitle = (TextView) row.findViewById(R.id.tvTitle);
            tvGenre = (TextView) row.findViewById(R.id.tvGenre);
        }
    
    
    }
    

    in your newView

    @Override
    public View newView(Context context, Cursor arg1, ViewGroup arg2) {
        // TODO Auto-generated method stub
    
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View row = inflater.inflate(R.layout.list_row, arg2, false);
    
        //create an instance of the holder
        ViewHolder holder = new ViewHolder(row);
        //add it to the Tag, so if it not null get the elements from tag.   
        row.setTag(holder);
    
        return row;
    } 
    

    in your bindView

    Override
    public void bindView(View v, Context context, Cursor c) {
        // TODO Auto-generated method stub
    
        //create an instance of the class and assign its value from view tag
        ViewHolder holder = (ViewHolder) v.getTag();
    
        //use the holder to assign values to the elements   
        holder.tvTitle.setText(c.getString(c.getColumnIndex(DatabaseHolder.TITLE_KEY)));
        holder.tvGenre.setText(c.getString(c.getColumnIndex(DatabaseHolder.GENRE_KEY)));
    
    }
    

    Hope this example is clear to you, change it according to your Item.

    ...

    update: Based on demanding DatabaseHolder class

    public class DatabaseHolder {

    private final static String DATABASE_NAME = "MoviesDatabase";
    private final static String TABLE_NAME = "MoviesTable";
    private final static int VERSION = 1;
    
    public final static String ID_KEY = "_id";
    public final static String TITLE_KEY = "title";
    public final static String GENRE_KEY = "genre";
    public final static String DESC_KEY = "description";
    
    public final static String[] COLUMNS = {ID_KEY, TITLE_KEY, GENRE_KEY, DESC_KEY};
    
    private Context  context;
    private SQLiteDatabase myDB;
    private OpenHelper helper;
    
    public DatabaseHolder(Context context)
    {
        this.context = context;
    }
    
    public class OpenHelper extends SQLiteOpenHelper {
    
        Context context;
    
        public OpenHelper(Context context) {
            super(context, TABLE_NAME, null, VERSION);
            // TODO Auto-generated constructor stub
            this.context = context;
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
    
            try {
                db.execSQL("CREATE TABLE "+ TABLE_NAME +" ( " +
                        ID_KEY + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                        TITLE_KEY + " TEXT(32) NOT NULL, " +
                        GENRE_KEY + " TEXT(32) NOT NULL, " +
                        DESC_KEY + " TEXT(512) NOT NULL);"
                        );
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                Message.message(context, "Failed"+e);
            }
    
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    
    
    }
    
    public DatabaseHolder open()
    {
        helper = new OpenHelper(context);
        myDB = helper.getWritableDatabase();
        return this;
    }
    
    public long insertMovie(String title, String genre, String desc) {
    
        ContentValues cv = new ContentValues();
    
        cv.put(TITLE_KEY, title);
        cv.put(GENRE_KEY, genre);
        cv.put(DESC_KEY, desc);
    
        return myDB.insert(TABLE_NAME, null, cv);
    
    }
    
    public Cursor getAllRowCursor() {
    
        Cursor c = myDB.query(TABLE_NAME, COLUMNS, null, null, null, null, null);
    
        if (c != null)
            c.moveToFirst();
    
        return c;
    }
    
    public Cursor getSpecificRows(int id) {
    
        String where = ID_KEY + " = " + id;
        Cursor c = myDB.query(TABLE_NAME, COLUMNS, where, null, null, null, null);
    
        if (c != null)
            c.moveToFirst();
    
        return c;
    
    }
    
    public Cursor getFilteredRows(String result)
    {
        result = "'" + result.trim() + "%'";
        String where = TITLE_KEY + " LIKE " + result;
        Cursor c = myDB.query(TABLE_NAME, COLUMNS, where, null, null, null, null);
    
        if (c != null)
            c.moveToFirst();
    
        return c;
    
    
    }
    
    public void truncate() {
        // TODO Auto-generated method stub
    
        myDB.delete(TABLE_NAME, null, null);
    }
    }