android - Row background changes due recyclation. getView() implementation doesn't fix this -


i've been looking lot guides, tutorials , answers here on stack, still can't figure 1 out.

i have custom drawable state. if click on row in listview, gets highlighted , updates information in database. (that task (habit) has been performed). works great until start scrolling. i've learnt, required override getview() method , getitemviewtype() getviewtypecount().

how this? code habitscursoradapter getview() , other mentioned methods @ moment looks this.

public class habitscursoradapter extends cursoradapter {      private layoutinflater inflater;     private context context;  public static final int performed = 1; public static final int not_performed = 0;      public habitscursoradapter(context context, cursor c) {         super(context, c, 0);         inflater = layoutinflater.from(context);         this.context = context;     }      @override     public void bindview(view view, context context, cursor cursor) {          string habitname = cursor.getstring(cursor                 .getcolumnindexorthrow(sqlitehabithelper.column_name));         textview habitnametv = (textview) view.findviewbyid(r.id.habit_name);         habitnametv.settext(habitname);           /*******************   ok   ***********************/         imagebutton editbutton = (imagebutton) view.findviewbyid(r.id.habit_edit_button);         integer _id = cursor.getint(cursor.getcolumnindexorthrow(sqlitehabithelper.column_id));         editbutton.settag(r.id.edited_habit_id, _id);         view.settag(_id);          editbutton.setonclicklistener(new onclicklistener() {              @override             public void onclick(view v) {                 intent = new intent(habitscursoradapter.this.context,                         habitdetailactivity.class);                 i.putextra("_id", (integer) v.gettag(r.id.edited_habit_id));                 habitscursoradapter.this.context.startactivity(i);             }         });          imagebutton deletebutton = (imagebutton) view                 .findviewbyid(r.id.habit_history_button); // need rewrite deleting button         deletebutton.settag(r.id.edited_habit_id, _id);         deletebutton.setonclicklistener(new onclicklistener() {              @override             public void onclick(view v) {                 //itemized due debugging issue                 habitlistactivity hla = ((habitlistactivity) habitscursoradapter.this.context);                 object o = v.gettag(r.id.edited_habit_id);                 integer = (integer) o;                 long l = i.longvalue();                 hla.delete(l);             }         });         /*******************   ok   **********************/          habitlistitemview hv = (habitlistitemview) view;         hv.sethabitperformed(                 (1 == cursor.getint(cursor.getcolumnindexorthrow(sqlitehabithelper.column_performed))) ? true : false                     );         view.refreshdrawablestate();     }      @override     public view newview(context context, cursor c, viewgroup container) {         habitlistitemview v = (habitlistitemview) inflater.inflate(                 r.layout.habit_item_layout, container, false);         bindview(v, context, c);                 return v;     }      @override     public int getviewtypecount() {         return 2;     }      @override     public int getitemviewtype(int position) {          cursor c = (cursor) getitem(position);          c.movetoposition(position);         int value = c.getint(c.getcolumnindexorthrow(sqlitehabithelper.column_performed));         if(0 != value){             return performed;         }         return not_performed;      }      @override     public view getview(int position, view convertview, viewgroup parent) {         if (!mdatavalid) {             throw new illegalstateexception("this should called when cursor valid");         }         if (!mcursor.movetoposition(position)) {             throw new illegalstateexception("couldn't move cursor position " + position);         }         view v;         if (convertview == null) {             v = newview(mcontext, mcursor, parent);             return v;         } else {              mcursor.movetoposition(position);              habitlistitemview hv = (habitlistitemview) convertview;             int convertviewisperformed = hv.gethabitperformed() ? 1 : 0;             int actualitemperformed = getitemviewtype(position);               if(actualitemperformed == convertviewisperformed){                               v = convertview;                 bindview(v, mcontext, mcursor);                 return v;             }else{                 v = newview(mcontext, mcursor, parent);                 return v;             }                                }     } } 

and custom row view is:

public class habitlistitemview extends relativelayout {      private static final int[] state_habit_performed = { r.attr.state_habit_performed };      private boolean performed;      public habitlistitemview(context context) {         this(context, null);     }      public habitlistitemview(context context, attributeset attributeset) {         super(context, attributeset);         loadviews();     }      public habitlistitemview(context context, attributeset attributeset,             int defstyle) {         super(context, attributeset, defstyle);          loadviews();     }      private void loadviews() {          setbackgroundresource(r.drawable.habit_list_item_background);         }      @override     protected int[] oncreatedrawablestate(int extraspace) {          if (performed) {              final int[] drawablestate = super                     .oncreatedrawablestate(extraspace + 1);              mergedrawablestates(drawablestate, state_habit_performed);              return drawablestate;         } else {             return super.oncreatedrawablestate(extraspace);         }     }      public void sethabitperformed(boolean performed) {         this.performed = performed;         refreshdrawablestate(); }  public boolean gethabitperformed() {     return performed; }  } 

and onlistitemclick() in listfragment

    @override     public void onlistitemclick(listview l, view v, int position, long id) {          super.onlistitemclick(l, v, position, id);          habitlistitemview hv = (habitlistitemview) v;          contentvalues cv = new contentvalues();            string habitid = v.gettag().tostring();          sqlitedatabase db = dh.getwritabledatabase();         cursor cperfomed = db.query(sqlitehabithelper.table_habit,                  new string[]{sqlitehabithelper.column_id, sqlitehabithelper.column_performed},                  "_id = ?", new string[]{habitid}, null, null, null);         cperfomed.movetofirst();          int performed = cperfomed.getint(cperfomed.getcolumnindexorthrow(sqlitehabithelper.column_performed));         cperfomed.close();          cv.put(sqlitehabithelper.column_id, (integer) v.gettag());         cv.put(sqlitehabithelper.column_performed, (performed == 0) ? 1 : 0);          db.update(sqlitehabithelper.table_habit, cv, "_id = ?", new string[]{habitid});         db.close();         hv.sethabitperformed((performed == 0) ? true : false);       } 

a thorough explanation on how , when overriden methods called maybe me resolve issue. presume, newview , bindview called getview, believe can control overriden getview. getitemviewtype , getviewtypecount called methods did not implement , not understand why , how results used. maybe cause problems.

if more code required, i'll edit post according requirements.

any appreciated!

a friend of mine helped me sending me link

android: cursoradapter, listview , checkbox

i tried solution, however, did not work out checkboxes, background color.

i had modify getview() method accordingly:

public view getview(int position, view inview, viewgroup parent) {     if (inview == null) {         layoutinflater inflater = (layoutinflater) context                 .getsystemservice(context.layout_inflater_service);         inview = inflater.inflate(r.layout.habit_item_layout, null);     }      habitlistitemview hliv = (habitlistitemview) inview;          mcursor.movetoposition(position);     bindview(hliv, mcontext, mcursor);     hliv.sethabitperformed(habitperformed.get(position)); //line added      return inview; } 

and add adapter array, store, if should have background green or not.

public arraylist<boolean> habitperformed = new arraylist<boolean>(); 

and in fragment list in method onlistitemclick() added code modified array accordingly.

    if (hv.gethabitperformed()) {         adapter.habitperformed.set(position, true);     } else if (!hv.gethabitperformed()) {         adapter.habitperformed.set(position, false);     } 

this solved problem.


Comments

Popular posts from this blog

c++ - Function signature as a function template parameter -

How to call a javascript function after the page loads with a chrome extension? -

algorithm - What are some ways to combine a number of (potentially incompatible) sorted sub-sets of a total set into a (partial) ordering of the total set? -