Some times we need a list view with interactive items like EditText , Radio Buttons ,Check Box etc on its rows. But When the no of items in the list view is large and we have to scroll the list to navigate up and down one problem arises.Suppose we are at the top of the list and filled the edit text with some text and changed the state of the check box.When we scroll down and again scroll back to the top we see that the changes made in the edit text and in the check box has lost.
viewHolder.scores=(EditText) view.findViewById(R.id.score); viewHolder.scores.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { Model element=(Model)viewHolder.scores.getTag(); element.setScore(s.toString()); } public void beforeTextChanged(CharSequence s, int start, int count,int after) { } public void afterTextChanged(Editable s) { } }); and save the state of the CheckBox when it is changed as follows: viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check); viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { Model element = (Model) viewHolder.checkbox.getTag(); element.setSelected(buttonView.isChecked()); } }); We will keep the data of list row items in Model class below public class Model { private String name; private boolean selected; private String score; public Model(String name) { this.name = name; selected = false; score=""; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isSelected() { return selected; } public void setSelected(boolean selected) { this.selected = selected; } public String getScore() { return score; } public void setScore(String score) { this.score = score; } }
When the the list items draws itself first time we will keep them in a view holder class along with the data and state of the items and later fetch that view and its data from the holder whenever it redraws itself.
This is the holder class which we will use to keep the views
static class ViewHolder { protected TextView text; protected CheckBox checkbox; protected EditText scores; } The whole things happen in the Adapter's getView method as follows: public class InteractiveListViewAdapter extends ArrayAdapter<Model> { private final List<Model> list; private final Activity context; public InteractiveArrayAdapter(Activity context, List<Model> list) { super(context, R.layout.rowbuttonlayout, list); this.context = context; this.list = list; } static class ViewHolder { protected TextView text; protected CheckBox checkbox; protected EditText scores; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = null; if (convertView == null) { LayoutInflater inflator = context.getLayoutInflater(); view = inflator.inflate(R.layout.rowbuttonlayout, null); final ViewHolder viewHolder = new ViewHolder(); viewHolder.text = (TextView) view.findViewById(R.id.label); viewHolder.scores=(EditText) view.findViewById(R.id.score); viewHolder.scores.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { Model element=(Model)viewHolder.scores.getTag(); element.setScore(s.toString()); } public void beforeTextChanged(CharSequence s, int start, int count,int after) { } public void afterTextChanged(Editable s) { } }); viewHolder.checkbox = (CheckB ox) view.findViewById(R.id.check); viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { Model element = (Model) viewHolder.checkbox.getTag(); element.setSelected(buttonView.isChecked()); } }); viewHolder.checkbox.setTag(list.get(position)); viewHolder.scores.setTag(list.get(position)); view.setTag(viewHolder); } else { view = convertView; ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position)); ((ViewHolder) view.getTag()).scores.setTag(list.get(position)); } ViewHolder holder = (ViewHolder) view.getTag(); holder.text.setText(list.get(position).getName()); holder.scores.setText(list.get(position).getScore()); holder.checkbox.setChecked(list.get(position).isSelected()); return view; } }
And here we have done.