0

I have a listview consists of TextView, EditText and Checkbox. I am want to make the state of the edittext to be persistent so that, when i change the text inside the edittext and then scroll the listview up or down that text that was added/written into the edittext should not be changed and must remain as it is

I managed to make the checkbox persistent, I do not know how to make the edittext state persistent.

please have a look at the getView() methos it is posted below and please let me know how to solve this issue

getView

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    View view = null;

    if (convertView == null) {
        LayoutInflater layoutinflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        view = layoutinflater.inflate(R.layout.model, null);

        final ViewHolder holder = new ViewHolder();

        holder.tv = (TextView) view.findViewById(R.id.tv);
        holder.cb = (CheckBox) view.findViewById(R.id.cb);
        holder.et = (EditText) view.findViewById(R.id.et);

        holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub

                ItemDesign element = (ItemDesign) holder.cb.getTag();
                element.setChecked(buttonView.isChecked());
            }
        });

        view.setTag(holder);

        holder.cb.setTag(designList.get(position));//checkbox

        //edittext
        ItemDesign element = (ItemDesign) holder.et.getTag();
        if (element != null) {
            element.setEtTxt(holder.et.getText().toString());
        }
        holder.et.setTag(designList.get(position));

        holder.tv.setTag(designList.get(position));//textview

    } else {
        view = convertView;

        ((ViewHolder)view.getTag()).et.setTag(designList.get(position));//edittext
        ((ViewHolder)view.getTag()).tv.setTag(designList.get(position));//textview
        ((ViewHolder)view.getTag()).cb.setTag(designList.get(position));//checkbox
    }
    ViewHolder holder = (ViewHolder) view.getTag();

    holder.tv.setText(designList.get(position).getTxt()); //textview
    holder.cb.setChecked(designList.get(position).isChecked());//checkbox

    //edittext
    String etTxt = holder.et.getText().toString();
    designList.get(position).setEtTxt(etTxt);
    holder.et.setText(designList.get(position).getEtTxt());

    return view;
}
private class ViewHolder {
    TextView tv;
    CheckBox cb;
    EditText et;
}
Amrmsmb
  • 1
  • 27
  • 104
  • 226
  • You have to maintain value in designList array. and in getView method you have to check and settext or setchecked... – Samir Mangroliya Feb 12 '17 at 14:31
  • @SamirMangroliya ok, in my designList there are getters and setters for each view "TextView, Checkbox,Edittext" and I use these getters and setters in the getView as posted above, and i managed to make the checkbox persistent...but my question is, how to make the Edittext value persistent – Amrmsmb Feb 12 '17 at 14:39

2 Answers2

1

You should add a TextWatcher to your edit text and use that to track the text inputted to the textview.

holder.et.setTag(designList.get(position));//edittext    
holder.et.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            ItemDesign element = (ItemDesign) holder.cb.getTag();
            element.setEditTextValue(s.toString())
        }
Saurabh
  • 1,055
  • 14
  • 38
1

if I understood you correctly, you need to register TextWatcher in your EditText and save string value every time, when you change text in it. So you will need to update you part of code from:

String etTxt = holder.et.getText().toString();
designList.get(position).setEtTxt(etTxt);
holder.et.setText(designList.get(position).getEtTxt());

to (sorry, I don't know what time of element do you have in designList, but let it be, for example, type Item, you can past your type instead of it):

final Item designItem = designList.get(position);
holder.et.setText(designItem.getEtTxt());
holder.et.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void afterTextChanged(Editable editable) {
        designItem.setEtTxt(editable.toString);
    }
});

But be careful. This solution is not working yet, since you have register new and new watchers but don't clear old. There is no perfect solution in this situation for me, since EditText doesn't have something like clearTextChangedListeners(). But you can solve it with introducing your own EditText (copied from here):

public class ExtendedEditText extends EditText {
    private ArrayList<TextWatcher> mListeners = null;

    public ExtendedEditText(Context ctx) {
        super(ctx);
    }

    public ExtendedEditText(Context ctx, AttributeSet attrs) {
        super(ctx, attrs);
    }

    public ExtendedEditText(Context ctx, AttributeSet attrs, int defStyle) {
        super(ctx, attrs, defStyle);
    }

    @Override
    public void addTextChangedListener(TextWatcher watcher) {
        if (mListeners == null) {
            mListeners = new ArrayList<TextWatcher>();
        }
        mListeners.add(watcher);

        super.addTextChangedListener(watcher);
    }

    @Override
    public void removeTextChangedListener(TextWatcher watcher) {
        if (mListeners != null) {
            int i = mListeners.indexOf(watcher);
            if (i >= 0) {
                mListeners.remove(i);
            }
        }

        super.removeTextChangedListener(watcher);
    }

    public void clearTextChangedListeners() {
        if (mListeners != null) {
            for (TextWatcher watcher : mListeners) {
                super.removeTextChangedListener(watcher);
            }

            mListeners.clear();
            mListeners = null;
        }
    }
}

After that final solution will look like this:

final Item designItem = designList.get(position);
holder.et.clearTextChangedListeners();
holder.et.setText(designItem.getEtTxt());
holder.et.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void afterTextChanged(Editable editable) {
        designItem.setEtTxt(editable.toString);
    }
});

Where et will be of type ExtendedEditText instead of EditText.

Community
  • 1
  • 1
Michael Spitsin
  • 2,539
  • 2
  • 19
  • 29