Reputation: 33
I'm working on an app where users fill reports and polls. In an activity I have a ListView where children contain EditTexts, Checkbox and TextView.
The problem with EditTexts and Checkbox was that when scrolling, the content that they have is lost. I was able to fix the Checkbox problem by saving the check status in an array, but I can't fix the problem with EditTexts. I know that there are some questions about this particular issue but the solutions that they provided doesn't seem to work. So here is my adapter:
public class DiveProfileAdapter extends ArrayAdapter<DiveProfile> {
private Context mContext;
private List<DiveProfile> mTasks;
ViewHolder holder;
private ArrayList<Boolean> itemChecked = new ArrayList<>(); //for saving checkbox values
public DiveProfileAdapter(Context context, List<DiveProfile> objects) {
super(context, R.layout.row_dive_profile_divers_list_item, objects);
this.mContext = context;
this.mTasks = objects;
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false); // initializes all items value with false
}
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mLayoutInflater = LayoutInflater.from(mContext);
convertView = mLayoutInflater.inflate(R.layout.row_dive_profile_divers_list_item, null);
holder = new ViewHolder();
holder.diverAttended = (CheckBox) convertView.findViewById(R.id.diver_attended_checkbox);
holder.diveTime = (EditText) convertView.findViewById(R.id.dive_time_edit_text);
holder.depth = (EditText) convertView.findViewById(R.id.depth_edit_text);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
final DiveProfile diverObjectTask = mTasks.get(position);
holder.diverAttended.setChecked(diverObjectTask.isDiverAttended());
holder.diveTime.setText(diverObjectTask.getDiveTime());
holder.diverAttended.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v.findViewById(R.id.diver_attended_checkbox);
if (cb.isChecked()) {
itemChecked.set(position, true);
// do some operations here
} else if (!cb.isChecked()) {
itemChecked.set(position, false);
// do some operations here
}
}
});
holder.diverAttended.setChecked(itemChecked.get(position)); // this will Check or Uncheck the
holder.diveTime.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String txt = setDiveTimeDialog();
holder.diveTime.setText(txt);
mTasks.get(position).setCurrentText(txt); //add the setter to the current item's position
}
});
holder.diveTime.setText(diverObjectTask.getCurrentText());
return convertView;
}
static class ViewHolder {
CheckBox diverAttended;
EditText diveTime;
EditText depth;
}
private String setDiveTimeDialog() {
//final String[] items = finItems;
final String[] items = getContext().getResources().getStringArray(R.array.certification_level_items);
// Create list dialog with required parameters - context, title, and our array of items to fill the list.
CustomListDialog.Builder builder = new CustomListDialog.Builder(getContext(), "Dive Time", items);
// Now again we can use some extra methods on the builder to customise it more.
builder.titleAlignment(BaseDialog.Alignment.LEFT);
builder.itemAlignment(BaseDialog.Alignment.LEFT);
builder.titleColor(getContext().getResources().getColor(R.color.primary_color));
// Now we can build our dialog.
CustomListDialog customListDialog = builder.build();
// Finally we can show it.
customListDialog.show();
customListDialog.setListClickListener(new CustomListDialog.ListClickListener() {
@Override
public void onListItemSelected(int i, String[] strings, String s) {
result = s;
}
});
return result;
}
}
Upvotes: 2
Views: 1123
Reputation: 10948
You should do something like this :
final DiveProfile diverObjectTask = mTasks.get(position);
holder.diveTime.setText(diverObjectTask.getDiveTie());
//also set your CheckBox value
Those values become empty because you dont set it in the getView
(getView
automatically getting called when the list scrolled)
UPDATE
Looking at your problem, i think the easiest way is to create new variables in DiveProfile
class, such as boolean isSelected
and String currentText
.
After that, theres no need to use separate list like itemChecked
. You can get
and set
the current item's value.
Example for using getter
:
holder.diverAttended.setChecked(mTasks.get(position).getSelected()); // getSelected is isSelected getter method
And call setSelected
(setter
of isSelected
) in your holder.diverAttended
onClick
Example for your EditText
setter
:
holder.diveTime.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String txt = setDiveTimeDialog();
holder.diveTime.setText(txt);
mTasks.get(position).setcurrentText(txt); //add the setter to the current item's position
}
});
And call getCurrentText()
in the getView
Upvotes: 1
Reputation: 2434
Your Viewholder variable must be inside your getView, preferrably the first variabe you declare right before if(convertView). Caching the ViewHolder outside will cause unpredictable behavior.
ConvertView is the View returned, so you have to set whatever changes you make onto the convertview.
Upvotes: 1