user2033242
user2033242

Reputation: 33

EditText in ListView loses content on scroll in ListView

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

Answers (2)

Blaze Tama
Blaze Tama

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

G_V
G_V

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

Related Questions