android - listview with a custom adapter - every other item element are duplicates -
i have come accross bit of weird problem (i think) listview , customadapter.
the problem have different view elements every item in listview, such edittext fields among others. whenever have more 2 items in listview, entries these elements in every other item.
let me give example: - adding 8 items listview. - enter value in first textfield - same value repeats in textfields: 3, 5 , 7 - if enter value in second item's textfield, value repeated in textfield of item number: 4, 6 , 8
i hope can see problem now.
here of relevant code problem:
first, code customadapter (createprogramadapter):
public class createprogramadapter extends baseadapter { private layoutinflater inflater; private arraylist<trainingpass> trainingpasses; private list<trainingpass> items; private int layoutresourceid; private context context; public createprogramadapter(context context, list<trainingpass> items) { this.context = context; this.items = items; this.inflater = layoutinflater.from(this.context); } @override public int getcount() { return items.size(); } @override public trainingpass getitem(int position) { return items.get(position); } @override public long getitemid(int position) { return position; } @override public view getview(int position, view convertview, viewgroup parent) { view view; trainingpassholder holder; if(convertview == null) { view = inflater.inflate(r.layout.adapter_createprogram_trainingpasses_item, parent, false); holder = new trainingpassholder(); view.settag(holder); } else { view = convertview; holder = (trainingpassholder)view.gettag(); } holder.trainingpass = this.getitem(position); holder.trainingpass.trainingpassid = position + 1; holder.trainingpasscontainer = (relativelayout) view.findviewbyid(r.id.trainingpasscontainer); holder.trainingpassheadlineshowhide = (textview) view.findviewbyid(r.id.trainingpass_headline); holder.noexercisesyet = (textview) view.findviewbyid(r.id.txt_no_exercises_yet); holder.exercisesearchfield = (edittext) view.findviewbyid(r.id.trainingpass_exercise_searchfield); holder.trainingpasssetslistview = (listview) view.findviewbyid(r.id.trainingpass_sets_listview); holder.exerciseslistview = (listview) view.findviewbyid(r.id.exercises_listview); holder.addsetbutton = (button) view.findviewbyid(r.id.add_set_button); holder.addexercisebutton = (button) view.findviewbyid(r.id.add_exercise_button); holder.deletetrainingpass = (button) view.findviewbyid(r.id.delete_trainingpass_button); holder.donetrainingpass = (button) view.findviewbyid(r.id.done_trainingpass_button); setupitems(holder); return view; } private void setupitems(trainingpassholder trainingpassholder) { final trainingpassholder holder = trainingpassholder; int trainingpassid = trainingpassholder.trainingpass.trainingpassid; textview showhide = holder.trainingpassheadlineshowhide; button addset = holder.addsetbutton; button deletetrainingpass = holder.deletetrainingpass; final edittext exercisenamefield = holder.exercisesearchfield; // set title of trainingpass showhide.settext("trainingpass " + trainingpassid); // set name of exercise if (trainingpassholder.trainingpass.tempexercisename != null) { system.out.println(holder.trainingpass.tempexercisename); exercisenamefield.settext(holder.trainingpass.tempexercisename); } else { exercisenamefield.settext(""); } // add 1 default set exercise if (holder.sets.size() == 0) { holder.sets.add(1); } /* set adapter sets of listview trainingpass */ final trainingpasssetsadapter createprogramadapter = new trainingpasssetsadapter(context, holder.sets); holder.trainingpasssetslistview.setadapter(createprogramadapter); exercisenamefield.setonkeylistener(new view.onkeylistener() { @override public boolean onkey(view v, int keycode, keyevent event) { holder.trainingpass.tempexercisename = exercisenamefield.gettext().tostring(); return false; } }); /* show / hide trainingpass */ showhide.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { if (holder.trainingpass.visible) { holder.trainingpass.visible = false; holder.trainingpasscontainer.setvisibility(view.gone); } else { holder.trainingpass.visible = true; holder.trainingpasscontainer.setvisibility(view.visible); } } }); /* add set listview */ addset.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { holder.sets.add(1); createprogramadapter.notifydatasetchanged(); } }); /* delete training pass */ deletetrainingpass.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { items.remove(holder.trainingpass); notifydatasetchanged(); } }); } private static class trainingpassholder { arraylist<integer> sets = new arraylist<integer>(); trainingpass trainingpass; relativelayout trainingpasscontainer; textview trainingpassheadlineshowhide; textview noexercisesyet; edittext exercisesearchfield; listview trainingpasssetslistview; listview exerciseslistview; button addsetbutton; button addexercisebutton; button deletetrainingpass; button donetrainingpass; } }
and here code class trainingpass:
public class trainingpass { public string trainingpassname; public arraylist<exercise> exercises; public int trainingpassid; public boolean visible = false; public string tempexercisename; public trainingpass() { exercises = new arraylist<exercise>(); } public void addexercise(exercise exercise ) { exercises.add(exercise); } }
an code activity class createprogramactivity:
public class createprogramactivity extends customactivity { private arraylist<trainingpass> trainingpasses; private createprogramadapter createprogramadapter; private listview trainingpasseslistview; @override protected void oncreate(bundle savedinstancestate) { settheme(r.style.apptheme); super.oncreate(savedinstancestate); setcontentview(r.layout.activity_create_program); trainingpasses = new arraylist<trainingpass>(); trainingpasseslistview = (listview)findviewbyid(r.id.listview_trainingpasses); createprogramadapter = new createprogramadapter(createprogramactivity.this, trainingpasses); trainingpasseslistview.setadapter(createprogramadapter); } public void addtrainingpass(view v) { trainingpass trainingpass = new trainingpass(); trainingpasses.add(trainingpass); createprogramadapter.notifydatasetchanged(); } public void addtrainingpasshelp(view v) { toast.maketext(this, "add training pass help!", toast.length_short).show(); } public void createprogram(view v) { toast.maketext(this, "create program", toast.length_short).show(); } }
here xml layout createprogramactivity, containing parent listview:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.mobileplatformexam.activities.createprogramactivity" android:id="@+id/relativelayoutcreateprogram"> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="add training pass" android:id="@+id/btn_add_trainingpass" android:layout_alignparenttop="true" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_toleftof="@+id/btn_add_trainingpass_help" android:layout_tostartof="@+id/btn_add_trainingpass_help" android:onclick="addtrainingpass"/> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="\?" android:id="@+id/btn_add_trainingpass_help" android:layout_alignparenttop="true" android:layout_alignparentright="true" android:layout_alignparentend="true" android:onclick="addtrainingpasshelp"/> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="create program" android:id="@+id/btn_create_program" android:layout_alignparentbottom="true" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_alignright="@+id/btn_add_trainingpass_help" android:layout_alignend="@+id/btn_add_trainingpass_help" android:onclick="createprogram"/> <listview android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listview_trainingpasses" android:layout_above="@+id/btn_create_program" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_below="@+id/btn_add_trainingpass" /> </relativelayout>
and lastly, here xml layout item of parent listview:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:orientation="horizontal" android:padding="10dp"> <textview android:id="@+id/trainingpass_headline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_alignparentstart="false" android:layout_alignparenttop="true" android:text="trainingpass" android:textsize="16dp" android:textcolor="@android:color/white" android:background="@android:color/holo_blue_dark" android:height="35dp" android:gravity="center_vertical" android:paddingleft="10dp" android:textisselectable="true" android:textstyle="bold" android:layout_alignparentright="true" android:layout_alignparentend="true" /> <imageview android:id="@+id/trainingpass_showhide_imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/holo_blue_dark" android:height="25dp" android:minwidth="50dp" android:layout_alignparentright="true" android:layout_alignparentend="true" android:padding="7dp" android:layout_alignbottom="@+id/trainingpass_headline" android:src="@mipmap/arrows_up_down" android:layout_alignparenttop="true" /> <relativelayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@+id/trainingpass_headline" android:layout_alignleft="@+id/trainingpass_headline" android:layout_alignstart="@+id/trainingpass_headline" android:id="@+id/trainingpasscontainer" android:background="@color/blue_bg_neutral" android:visibility="visible" android:paddingbottom="10dp"> <edittext android:id="@+id/trainingpass_exercise_searchfield" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="name of exercise" android:padding="6dp" android:layout_alignparenttop="true" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_alignparentright="true" android:layout_alignparentend="true" android:background="@color/blue_bg_inputfield" android:layout_margin="10dp" /> <relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@+id/trainingpass_exercise_searchfield" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:id="@+id/sets_container" android:background="@color/blue_bg_inputfield" android:padding="10dp" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_margintop="10dp"> <textview android:id="@+id/txt_sets_for_exercise" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="sets exercise" android:textsize="14dp" android:textcolor="@android:color/black" android:paddingright="30dp" android:paddingleft="0dp" android:paddingtop="0dp" android:paddingbottom="10dp" android:textstyle="bold" android:layout_alignparenttop="true" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_alignright="@+id/add_set_button" android:layout_alignend="@+id/add_set_button" /> <listview android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/trainingpass_sets_listview" android:nestedscrollingenabled="true" android:layout_alignparentright="true" android:layout_alignparentend="true" android:layout_aligntop="@+id/txt_no_sets" android:layout_alignbottom="@+id/txt_no_sets" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="add set" android:id="@+id/add_set_button" android:layout_below="@+id/trainingpass_sets_listview" android:layout_alignparentright="true" android:layout_alignparentend="true" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="add exercise" android:id="@+id/add_exercise_button" android:layout_below="@+id/add_set_button" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_alignparentright="true" android:layout_alignparentend="true" /> <textview android:id="@+id/txt_no_sets" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="no sets yet" android:textsize="14dp" android:textcolor="@android:color/black" android:paddingright="30dp" android:paddingleft="10dp" android:paddingtop="20dp" android:paddingbottom="10dp" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_alignparentright="true" android:layout_alignparentend="true" android:layout_below="@+id/txt_sets_for_exercise" android:visibility="invisible" /> </relativelayout> <relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignparentright="true" android:layout_alignparentend="true" android:layout_below="@+id/sets_container" android:id="@+id/exercises_container" android:background="@color/blue_bg_inputfield" android:padding="10dp" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_margintop="10dp"> <textview android:id="@+id/txt_exercises" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="exercises" android:textsize="14dp" android:textcolor="@android:color/black" android:paddingright="30dp" android:paddingleft="0dp" android:paddingtop="0dp" android:paddingbottom="10dp" android:textstyle="bold" android:layout_alignparenttop="true" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_alignright="@+id/txt_no_exercises_yet" android:layout_alignend="@+id/txt_no_exercises_yet" /> <textview android:id="@+id/txt_no_exercises_yet" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="no exercises yet" android:textsize="14dp" android:textcolor="@android:color/black" android:paddingright="30dp" android:paddingleft="10dp" android:paddingtop="20dp" android:paddingbottom="10dp" android:layout_below="@+id/txt_exercises" android:layout_alignparentright="true" android:layout_alignparentend="true" android:layout_alignparentleft="true" android:layout_alignparentstart="true" /> <listview android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/exercises_listview" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_below="@+id/txt_exercises" android:layout_alignbottom="@+id/txt_no_exercises_yet" /> </relativelayout> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="delete" android:id="@+id/delete_trainingpass_button" android:layout_alignright="@+id/exercises_container" android:layout_alignend="@+id/exercises_container" android:layout_below="@+id/exercises_container" android:background="@color/btn_red" android:layout_marginleft="10dp" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="done" android:id="@+id/done_trainingpass_button" android:layout_below="@+id/exercises_container" android:layout_alignleft="@+id/exercises_container" android:layout_alignstart="@+id/exercises_container" android:layout_tostartof="@+id/delete_trainingpass_button" android:background="@color/btn_green" android:layout_marginright="10dp" /> </relativelayout> </relativelayout>
i hope can see problem is.
any appreciated.
i think behavior predictable adapter utilizes views replacing content new data. didn't set new text value edittext in getview() method edittext old value, entered. try add textwatcher edittext , save entered value in corresponding instance of trainingpass object. , in getview() method have add of holder.exercisesearchfield.settext(). if corresponding trainingpass object contains entered value have set edittext, otherwise have set empty string.