Android - Why would Switch button on CursorAdaptor reset button immediately after a change -
i trying update boolean value in database table, based on switch. listview holds list of languages "install" switch button each. cursoradapter displaying list , switches. i've set oncheckedchangelisteners each switch. when select 1 of switches, briefly shows being switched on, reverts "off." in logging, see value set "true" , sent databaseprovider update database. thereafter, see log output value false, sent databaseprovider in update.
cursoradapter:
public static class viewholder { public final textview nameview; public final switch installswitch; public viewholder(view view) { nameview = (textview) view.findviewbyid(r.id.language_textview); installswitch = (switch) view.findviewbyid(r.id.installed_switch); } } public languageadapter(context context, cursor c, int flags) { super(context, c, flags); } @override public view newview(context context, cursor cursor, viewgroup parent) { view view = layoutinflater.from(context).inflate(r.layout.list_item_language, parent, false); viewholder viewholder = new viewholder(view); view.settag(viewholder); return view; } @override public void bindview(view view, context context, final cursor cursor) { viewholder viewholder = (viewholder) view.gettag(); long languageid = cursor.getlong(0); string word = cursor.getstring(1); boolean langinstalled = boolean.parseboolean(cursor.getstring(2)); viewholder.nameview.settext(word); viewholder.installswitch.setchecked(langinstalled); viewholder.installswitch.settag(languageid); viewholder.installswitch.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) { long languageid = (long) buttonview.gettag(); contentvalues cv = new contentvalues(); cv.put(translationcontract.languageentry.column_installed, ischecked); log.d(log_tag, "onchecked, langid: " + languageid + " ischecked: " + ischecked); buttonview.getcontext().getcontentresolver().update(translationcontract.languageentry.content_uri, cv, translationcontract.languageentry._id+"=?", new string[] {string.valueof(languageid)}); } }); } databaseprovider:
public int update( uri uri, contentvalues values, string selection, string[] selectionargs) { final sqlitedatabase db = mopenhelper.getwritabledatabase(); final int match = surimatcher.match(uri); int rowsupdated; switch (match) { case languages: rowsupdated = db.update(languageentry.table_name, values, selection, selectionargs); log.d(log_tag, "updating languages: " + values.tostring()); break; } log:
07-13 21:39:32.785 languageadapter﹕ onchecked, langid: 2 ischecked: true 07-13 21:39:32.800 databaseprovider﹕ updating languages: installed=true 07-13 21:39:32.813 languageadapter﹕ onchecked, langid: 2 ischecked: false 07-13 21:39:32.825 databaseprovider﹕ updating languages: installed=false
after more digging, i've discovered 2 issues:
first, oncheckchanged seems called twice always, perhaps android bug? see following posts: oncheckedchanged fired multiple times, listview checkbox , checkbox changes value twice
instead, use onclicklistener.
the second issue here incorrect handling of boolean values between db cursor , java code. sqlite doesn't have native boolean type, values stored , returned integers 0 or 1. need evaluated , converted java boolean value.
the corrected code be:
@override public void bindview(view view, context context, final cursor cursor) { viewholder viewholder = (viewholder) view.gettag(); long languageid = cursor.getlong(0); string word = cursor.getstring(1); boolean langinstalled = cursor.getint(2)>0; //convert db 1 or 0 java boolean viewholder.nameview.settext(word); viewholder.installswitch.setchecked(langinstalled); viewholder.installswitch.settag(languageid); viewholder.installswitch.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { compoundbutton button = (compoundbutton) v; long languageid = (long) button.gettag(); boolean ischecked = button.ischecked(); int dbboolean = 0; if (button.ischecked()) { dbboolean = 1; } contentvalues cv = new contentvalues(); cv.put(translationcontract.languageentry.column_installed, dbboolean); button.getcontext().getcontentresolver().update(translationcontract.languageentry.content_uri, cv, translationcontract.languageentry._id + "=?", new string[]{string.valueof(languageid)}); notifydatasetchanged(); } }); }
Comments
Post a Comment