简体   繁体   中英

EditText in ListView loses content in scrolling

I've been digging to find a solution on my problem finding answers but none of them have worked for me. :/ I have a listview with edittext in each list item and when scrolling down and go up again content of the edited edittext has been lost or other edittext has taken his value.

please help me some one

MainActivity:-

public class MainActivity extends AppCompatActivity {

    private ArrayList<Friend> friendArrayList;
    ListViewAdapter adapter;

    String[] countriessArray =  { "USA", "USA", "USA", "USA",
            "China", "Japan", "France", "USA","USA", "USA", "USA", "USA",
            "China", "Japan", "France", "USA"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        friendArrayList = new ArrayList<Friend>();
        for (int i = 0; i < countriessArray.length; i++) {

            Friend item = new Friend(countriessArray[i]);
            friendArrayList.add(item);
        }

        ListView listView = (ListView) findViewById(R.id.list);
        listView.setItemsCanFocus(true);

        adapter = new ListViewAdapter(this, R.layout.item_listview, friendArrayList);

        listView.setAdapter(adapter);
    }

ListViewAdaper:-

public class ListViewAdapter extends ArrayAdapter<Friend> {

    ViewHolder holder;
    private List<Friend> myFriends;
    private Activity activity;

    public static HashMap<Integer,String> myList=new HashMap<Integer,String>();

    public ListViewAdapter(Activity context, int resource, List<Friend> objects) {

        super(context, resource, objects);
        this.activity = context;
        this.myFriends = objects;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        final int viewpos = position;

        // If holder not exist then locate all view from UI file.
        if (convertView == null) {
            // inflate UI from XML file
            convertView = inflater.inflate(R.layout.item_listview, parent, false);
            // get all UI view
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);

        } else {
            // if holder created, get tag from view
            holder = (ViewHolder) convertView.getTag();
        }

        holder.friendName.setText(getItem(position).getName());

        //Edit Text Listeners:-

        holder.editText.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) {
                myList.put(position,s.toString().trim());
            }
        });

        holder.editText.setText(myList.get(position));

        return convertView;
    }

    private static class ViewHolder {

        private TextView friendName;
        private EditText editText;

        public ViewHolder(View v) {
            friendName = (TextView) v.findViewById(R.id.name);
            editText = (EditText) v.findViewById(R.id.edit);
        }
    }
}

Custom Object:-

public class Friend {

    private String name,editText;
    private int selection = 0;

    public Friend(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setSelection(int selection) {
        this.selection = selection;
    }

    public int getSelection() {
        return selection;
    }

    public void setEditText(String editText) {
        this.editText = editText;
    }

    public String getEditText() {
        return editText;
    }
}

You need to store data in afterTextChanged as same object as you set in text

   holder.friendName.setText(myFriends.get(position).getName());

        //Edit Text Listeners:-

        holder.editText.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) {
                myFriends.get(position).setName(s.toString);
            }
        });

Alright, first off all a ListView uses recycled views. That means that when you scroll up and down they will reinflate again, this is why the text goes away. I would recommend not using a ListView, but instead just use a LinearLayout and then programatically add EditText views. Now, if you stubborn and do not feel like changing your current solution. One thing you could do it to basically store all the String values when the user types in the field, and then in the adapter you can set then to the type value.

For example..

String valueForEditTextOne = "";

//in the get view adapter you have to set a tag for each edittext to be able to identify them. 

String tagName = editTextOne.getTag();

   if (tagName == null) {
   //You need to set the tag name (use the passed position constructor)
   editTextOne.setTag(String.valueOf(position));
   } else {
     if(tagName.equals("1")) {
      textViewOne.setText(valueForEditTextOne);
     } else if (tagName.equals("2") {
      //etc...
     }
   } 

}

I have no idea how many TextViews you have, but this would certainly work. You would also have to add a text change listener to update each manual string for that textview.

Solved :

When scroll the listview, all editText items set to SAME VALUE and loses its real value if handler code like that,

 txtQuantityVal.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
            items.get(position).setStock(Double.parseDouble(s.toString()));
        }

Because , textChangeEventListener changes for all elements.

The way to avoid this, add data item object to editText's Tag property ,

  txtQuantityVal.setTag(item);
  txtQuantityVal.setText(String.valueOf(item.getStock()));

and then, we have maintain control in TextChange event , here my unique key for my data is item.productId , the solution logic is, by checking two values, we should check whether the correct element is changing.

 txtQuantityVal.addTextChangedListener(new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {
                    BarcodeItem bitem=items.get(position);
                    BarcodeItem xitem=((BarcodeItem)txtQuantityVal.getTag());
                    if(bitem.getProductId() == xitem.getProductId() ) { // match id, item change ?
                        items.get(position).setStock(Double.parseDouble(s.toString()));
                    }
                    else{
                        // data item ids different, item no changes
                        
                    }
            }
    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM