listview - Android: Refresh cursorloader from a second activity -
have day. i'm learning android development i'm creating simple crud application, right have main activity has listview (marcaactivity) next code:
package com.example.crudapp.activity; import android.app.activity; import android.app.loadermanager; import android.content.cursorloader; import android.content.intent; import android.content.loader; import android.database.cursor; import android.net.uri; import android.os.bundle; import android.view.menu; import android.view.menuitem; import android.view.view; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.listview; import com.example.crudapp.marcacursoradapter; import com.example.crudapp.r; import com.example.crudapp.cp.marcacp; public class marcaactivity extends activity implements loadermanager.loadercallbacks<cursor> { marcacursoradapter crsadap; listview lstmarcas; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_marca); lstmarcas = (listview)findviewbyid(r.id.lstmarcas); lstmarcas.setonitemclicklistener(new onitemclicklistener() { @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { intent = new intent(marcaactivity.this, marcadetailactivity.class); uri todouri = uri.parse(marcacp.content_uri + "/" + arg3); i.putextra("det", todouri); i.putextra("action", "existing"); startactivity(i); } }); getloadermanager().initloader(0, null, this); filldata(); } protected void onrestoreinstancestate(bundle savedinstancestate) { getloadermanager().restartloader(0, null, this); } @override public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case r.id.insertmnu: intent = new intent(this, marcadetailactivity.class); i.putextra("action", "new"); startactivityforresult(i, 0); return true; } return super.onoptionsitemselected(item); } @override public boolean oncontextitemselected(menuitem item) { /*switch (item.) { case delete_id: adaptercontextmenuinfo info = (adaptercontextmenuinfo) item .getmenuinfo(); uri uri = uri.parse(marcacp.content_uri + "/" + info.id); getcontentresolver().delete(uri, null, null); filldata(); return true; }*/ return super.oncontextitemselected(item); } private void filldata() { crsadap = new marcacursoradapter(this, r.layout.template_marcas, null , new string[]{marcacp.marca.nombre, marcacp.marca.ranking}, new int[]{r.id.nommarca, r.id.rankmarca}); lstmarcas.setadapter(crsadap); } @override public boolean oncreateoptionsmenu(menu menu) { // inflate menu; adds items action bar if present. getmenuinflater().inflate(r.menu.marca, menu); return true; } @override public loader<cursor> oncreateloader(int arg0, bundle arg1) { return new cursorloader(this, marcacp.content_uri, new string[]{marcacp.marca.id, marcacp.marca.nombre, marcacp.marca.codigo, marcacp.marca.ranking}, null, null, null); } @override public void onloadfinished(loader<cursor> arg0, cursor arg1) { crsadap.swapcursor(arg1); } @override public void onloaderreset(loader<cursor> arg0) { crsadap.swapcursor(null); } }
then, have activity manages detail view can update or add items, called marcadetailactivity:
package com.example.crudapp.activity; import android.app.activity; import android.content.contentvalues; import android.content.intent; import android.database.cursor; import android.net.uri; import android.os.bundle; import android.view.menu; import android.view.view; import android.widget.button; import android.widget.edittext; import android.widget.spinner; import android.widget.textview; import android.widget.toast; import com.example.crudapp.marcacursoradapter; import com.example.crudapp.r; import com.example.crudapp.cp.marcacp; public class marcadetailactivity extends activity { marcacursoradapter crsadap; private integer idreg; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.detalle_marca); bundle extras = getintent().getextras(); if(extras != null && extras.get("action").equals("existing")) //invocamos filldata filldata((uri)extras.get("det")); else cleanform(); } public void cleanform() { ((button)findviewbyid(r.id.todo_edit_button)).setvisibility(view.invisible); ((button)findviewbyid(r.id.todo_insert_button)).setvisibility(view.visible); } public void filldata(uri uri) { string[] projection = { marcacp.marca.codigo, marcacp.marca.clasificacion, marcacp.marca.nombre, marcacp.marca.ranking}; //builder. cursor cur = getcontentresolver().query(uri, projection, null, null, null); if(cur != null) { cur.movetofirst(); ((edittext)findviewbyid(r.id.detnombre)).settext(cur.getstring(cur.getcolumnindex(marcacp.marca.nombre))); ((edittext)findviewbyid(r.id.detcodigo)).settext(cur.getstring(cur.getcolumnindex(marcacp.marca.codigo))); setidreg(cur.getint(cur.getcolumnindex(marcacp.marca.id))); ((edittext)findviewbyid(r.id.todo_edit_button)).setvisibility(view.visible); ((edittext)findviewbyid(r.id.todo_insert_button)).setvisibility(view.invisible); string clasif = cur.getstring(cur.getcolumnindex(marcacp.marca.clasificacion)); int rank = cur.getint(cur.getcolumnindex(marcacp.marca.ranking)); spinner sprnk = ((spinner)findviewbyid(r.id.detranking)); spinner spclasf = ((spinner)findviewbyid(r.id.detclasificacion)); //buscamos setear los spinners en sus valores for(short ps = 0; ps < sprnk.getcount(); ps++) { string tmprnk = (string)sprnk.getitematposition(ps); if(tmprnk.equalsignorecase("" + rank)) sprnk.setselection(ps); } //buscamos setear los spinners en sus valores for(short ps = 0; ps < spclasf.getcount(); ps++) { string tmpclas = (string)spclasf.getitematposition(ps); if(tmpclas.equalsignorecase(clasif)) spclasf.setselection(ps); } cur.close(); } } private boolean validate() { boolean res = true; return res; } public void guardar(view view) { if(validate()) { contentvalues cv = new contentvalues(); cv.put(marcacp.marca.clasificacion, (string)((spinner)findviewbyid(r.id.detclasificacion)).getselecteditem() ); cv.put(marcacp.marca.codigo, ((textview)findviewbyid(r.id.detcodigo)).gettext().tostring() ); cv.put(marcacp.marca.nombre, ((textview)findviewbyid(r.id.detnombre)).gettext().tostring() ); cv.put(marcacp.marca.ranking, integer.parseint("" + ((spinner)findviewbyid(r.id.detranking)).getselecteditem() )); getcontentresolver().insert(marcacp.content_uri, cv); } toast.maketext(marcadetailactivity.this, "registro registrado", toast.length_short).show(); //refrescamos el grid y cerramos la actividad //((marcaactivity)this.getcallingactivity()).refrescarlista() //getloadermanager().restartloader(0, null, marcaactivity.class); this.finish(); } public void regresar() { intent = new intent(marcadetailactivity.this, marcaactivity.class); i.putextra("refresh", true); startactivity(i); } public void actualizar(view view) { if(validate()) { contentvalues cv = new contentvalues(); cv.put(marcacp.marca.clasificacion, (string)((spinner)findviewbyid(r.id.detclasificacion)).getselecteditem() ); cv.put(marcacp.marca.codigo, (string)((textview)findviewbyid(r.id.detcodigo)).gettext() ); cv.put(marcacp.marca.nombre, (string)((textview)findviewbyid(r.id.detnombre)).gettext() ); cv.put(marcacp.marca.id, getidreg() ); cv.put(marcacp.marca.ranking, integer.parseint("" + ((spinner)findviewbyid(r.id.detranking)).getselecteditem() )); getcontentresolver().update(marcacp.content_uri, cv, null, null); } } @override public boolean oncreateoptionsmenu(menu menu) { // inflate menu; adds items action bar if present. getmenuinflater().inflate(r.menu.marca, menu); return true; } public integer getidreg() { return idreg; } public void setidreg(integer idreg) { this.idreg = idreg; } }
as can see in method guardar of marcadetailactivity, first insert item using custom content provider, use toast show confirm message, , finishing activity, when that, listview isn't refreshed via cursorloader. read here (stackoverflow) , in other pages have call
getloadermanager().restartloader(list_id, null, this);
but in examples found stuff (inserting data in database , refreshing list) in same activity, in case have activity list , second activity inserts item, think have call restartloader detail activity, don't know how or if that's right way this. thinking saving reference list activity in extras when create intent call detail activity , have public method calls restartloader don't know if best approach. what's best way refresh cursor loader detail activity?
and there's content provider, marcacp:
package com.example.crudapp.cp; import android.content.contentprovider; import android.content.contentvalues; import android.content.urimatcher; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import android.database.sqlite.sqlitequerybuilder; import android.net.uri; import android.text.textutils; import com.example.crudapp.util.connhandler; public class marcacp extends contentprovider { private static final int todos = 10; private static final int todo_id = 20; public static final uri content_uri = uri.parse("content://provider.marcacp/marcas"); private static final urimatcher surimatcher = new urimatcher(urimatcher.no_match); static { surimatcher.adduri("provider.marcacp", "marcas", todos); surimatcher.adduri("provider.marcacp", "marcas" + "/#", todo_id); } public static class marca { public static final string tabla = "marca"; public static final string id = "_id"; public static final string codigo = "codigo"; public static final string nombre = "nombre"; public static final string clasificacion = "clasificacion"; public static final string ranking = "ranking"; } private connhandler conn; sqlitedatabase dbobj; @override public int delete(uri uri, string selection, string[] selectionargs) { int uritype = surimatcher.match(uri); int rowsdeleted = 0; switch (uritype) { case todos: rowsdeleted = dbobj.delete(marca.tabla, selection, selectionargs); break; case todo_id: string id = uri.getlastpathsegment(); if (textutils.isempty(selection)) { rowsdeleted = dbobj.delete(marca.tabla, marca.id + " = " + id, null); } else { rowsdeleted = dbobj.delete(marca.tabla, marca.id + " =" + id + " , " + selection, selectionargs); } break; default: throw new illegalargumentexception("unknown uri: " + uri); } getcontext().getcontentresolver().notifychange(uri, null); return rowsdeleted; } @override public string gettype(uri uri) { // todo auto-generated method stub return null; } @override public uri insert(uri uri, contentvalues values) { int uritype = surimatcher.match(uri); long id = 0; switch (uritype) { case todos: id = dbobj.insert(marca.tabla, null, values); break; default: throw new illegalargumentexception("unknown uri: " + uri); } getcontext().getcontentresolver().notifychange(uri, null); return uri.parse("marca/" + id); } @override public boolean oncreate() { conn = new connhandler(getcontext()); dbobj = conn.getdb(); return true; } @override public cursor query(uri uri, string[] projection, string selection, string[] selectionargs, string sortorder) { // uisng sqlitequerybuilder instead of query() method sqlitequerybuilder querybuilder = new sqlitequerybuilder(); checkcolumns(projection); querybuilder.settables(marca.tabla); int uritype = surimatcher.match(uri); switch (uritype) { case todos: break; case todo_id: // digamos para ver el detalle de un registro querybuilder.appendwhere(marca.id + " = " + uri.getlastpathsegment()); break; default: throw new illegalargumentexception("unknown urix: " + uri); } cursor cur = querybuilder.query(dbobj, projection, selection, selectionargs, null, null, sortorder); return cur; } @override public int update(uri uri, contentvalues values, string selection, string[] selectionargs) { int uritype = surimatcher.match(uri); int rowsupdated = 0; switch (uritype) { case todos: rowsupdated = dbobj.update(marca.tabla, values, selection, selectionargs); break; case todo_id: string id = uri.getlastpathsegment(); if (textutils.isempty(selection)) { rowsupdated = dbobj.update(marca.tabla, values, marca.id + " =" + id, null); } else { rowsupdated = dbobj.update(marca.tabla, values, marca.id + " =" + id + " , " + selection, selectionargs); } break; default: throw new illegalargumentexception("unknown uri: " + uri); } getcontext().getcontentresolver().notifychange(uri, null); return rowsupdated; } private void checkcolumns(string[] projection) { /*string[] available = { todotable.column_category, todotable.column_summary, todotable.column_description, todotable.column_id }; if (projection != null) { hashset<string> requestedcolumns = new hashset<string>(arrays.aslist(projection)); hashset<string> availablecolumns = new hashset<string>(arrays.aslist(available)); // check if columns requested available if (!availablecolumns.containsall(requestedcolumns)) { throw new illegalargumentexception("unknown columns in projection"); } }*/ } }
it's registered in androidmanifest.xml:
<provider android:name=".cp.marcacp" android:authorities="provider.marcacp" />
regards.
try getcontentresolver().notifychange(marcacp.content_uri, null, false)
second activity before finishing it.
Comments
Post a Comment