0

I know this question is repeated many times in the stackoverflow , still could not find the proper solution for this. I am building an android application in which i am using Edit text within the Listview . When I enter some data in edit text and scroll to the below part and come back, the entered data either be lost , or it will be in the different row view of list view .

I followed the below stack overflow post and written the code. Still its not working.

Edit Text in custom List View Loses Value on Scroll

Below is my Adapter code .

package com.example.listview;

import java.util.List;

import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnFocusChangeListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.TextView;



class MynewAdapter extends ArrayAdapter<Model> {
private final List<Model> list;
private final Activity context;
int temp;
public String[] text;
//private int editingPosition = 0;

MynewAdapter(Activity context, List<Model> list) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
        text= new String[list.size()];
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        System.out.println("getview:"+position+" "+convertView);
        ViewHolder holder = null;
        temp=position;
        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {

            holder = new ViewHolder();
            convertView = mInflater
                    .inflate(R.layout.row, parent, false);

            holder.text = (TextView) convertView
                    .findViewById(R.id.label);

            holder.address = (EditText) convertView
                    .findViewById(R.id.txtAddress);
            holder.address.setTag(position);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        //holder.address.removeTextChangedListener(watcher);

        holder.address.setText(text[temp]);
       /*
        holder.address.setOnFocusChangeListener(new OnFocusChangeListener(){       
            public void onFocusChange(View v, boolean hasFocus) {
              if(hasFocus) editingPosition = temp;
            }
        });
        */   
      holder.address.addTextChangedListener(new TextWatcher() {

          public void onTextChanged(CharSequence s, int start, int before, int count) {
              System.out.println("onTextChanged size= "+list.size()+" editingposition = "+temp+" string = "+s.toString());
              text[temp] = s.toString();
          }
          public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
          public void afterTextChanged(Editable s) { }
      });
      holder.text.setText(list.get(position).getName());

        return convertView;
    }

    class ViewHolder {
        protected TextView text;
        protected EditText address;
    }
}

I have put trace in the get view method and text watcher. When the app is opened get view is called for all the visible list items and convertview will be null as nothing to recycle. And when I enter the text in the edit field of Listview item 1 , Still the position parameter will be 6. So thats the bug I found in the code. So Is there anyway to find the position of the item where the text is getting edited ? That will really solve the problem.

07-16 10:58:48.449: I/System.out(825): getview:0 null
07-16 10:58:48.469: I/System.out(825): getview:1 null
07-16 10:58:48.469: I/System.out(825): getview:2 null
07-16 10:58:48.479: I/System.out(825): getview:3 null
07-16 10:58:48.479: I/System.out(825): getview:4 null
07-16 10:58:48.489: I/System.out(825): getview:5 null
07-16 10:58:48.489: I/System.out(825): getview:6 null
07-16 10:59:33.309: I/System.out(825): onTextChanged size= 18 editingposition = 6 string = p
07-16 10:59:54.659: I/System.out(825): onTextChanged size= 18 editingposition = 6 string = pr
07-16 11:00:24.599: I/System.out(825): onTextChanged size= 18 editingposition = 6 string = s
07-16 11:00:24.949: I/System.out(825): onTextChanged size= 18 editingposition = 6 string = su
Community
  • 1
  • 1
Prabhuraj
  • 141
  • 3
  • 17

1 Answers1

0
  1. You need to save the new edited text inside the data source you've used to set the text. public String[] text in your case and call notifyDataSetChanged(). If you don't save the updated data, the adapter will just pick up the previous value and display it in the listview.

  2. Use a new textWatcher for every textview.

I'd suggest you to use this :

  holder.address.addTextChangedListener(new TextWatcher() {

          public void onTextChanged(CharSequence s, int start, int before, int count) {
              System.out.println("onTextChanged size= "+list.size()+" editingposition = "+editingPosition+" string = "+s.toString());
              text[position] = s.toString();
          }
          public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
          public void afterTextChanged(Editable s) { }
      });
Shivam Verma
  • 7,973
  • 3
  • 26
  • 34
  • Thanks Shivam for the response. I dint understand your comment completely. It would be very useful if you elaborate a bit . – Prabhuraj Jul 16 '14 at 06:45
  • As of I read about the notifydatasetchanged() function , it will rebuild the Listview again with new set of values. But My problem is when we scroll the view , its messing up with the entered text in edit view of the List view. So I doubt whether notifydatasetchanged would help . Please correct if I am wrong. – Prabhuraj Jul 16 '14 at 07:39
  • Hi Shivam. I have tried this already. The problem with me is ,when the Listview is populated initially assume it can hold 6 rows based on my screen resolution , it will call get views 6 times and create the list view. So when I just open the application the position parameter is set to 6. Though I entered the text into edit text of any row view , I have no way to get the position of the edit text in list view.As of code , If I entered the data in edit text of the first row (position should be 0) , the below code stores it in position 6. text[position] = s.toString(); – Prabhuraj Jul 16 '14 at 07:53
  • why will it store in position 6 if the value of position inside the text watcher = the position of the item in the list view. – Shivam Verma Jul 16 '14 at 07:55
  • Thats how edit view works. Check the log I have posted. 07-16 10:59:33.309: I/System.out(825): onTextChanged size= 18 editingposition = 6 string = p This is the log which I got when I entered a character in the edit text of first row of the List view.It has already built 6 row views and position is set to 6. – Prabhuraj Jul 16 '14 at 08:00
  • So by using the position parameter in the get view , I am not getting the position of the edit text where i m entering the data. So I am trying to find the way to get the position of that particular edit view where the data is entered. – Prabhuraj Jul 16 '14 at 08:03
  • The position value that you have as a parameter in the getView() method is the position of the view that is being generated. So, it has the correct value of the position of the edit text. The way you're implementing it is wrong. You need to attach individual watchers to each textview and not use the same watcher. You can get rid of the focus changed method completely. – Shivam Verma Jul 16 '14 at 08:05
  • I changed the code to your suggestion and tried ,still the same issue. And I updated the code in the main question. As you rightly said "position value that you have as a parameter in the getView() method is the position of the view that is being generated". As in the Listview it will generate multiple views ,one for each row. As currently screen can fit 7 rows , it has created 7 views position from 0..6 . And position is set to 6 of the last generated view. Thats my understanding , please correct if I am wrong.Please check the updated code. – Prabhuraj Jul 16 '14 at 08:21
  • do you have any other methods overidden methods for the adapter? – Shivam Verma Jul 16 '14 at 10:18
  • Hmmm. I am not sure . Currently I have only overridden get view method. Even I am looking for any other methods which might rescue this issue . – Prabhuraj Jul 16 '14 at 10:22