EditText in ListView without it recycling input

后端 未结 2 1287
温柔的废话
温柔的废话 2020-12-15 01:25

Still new to android and even more to custom cursor adapter so I\'m having trouble understanding how to prevent my listview from recycling views to prevent input from one e

2条回答
  •  失恋的感觉
    2020-12-15 02:18

    First of all, you really don't want to prevent a list view from recycling its views. View recycling is a huge optimization. For a lot of really good info on lists, see the google IO talk: http://www.youtube.com/watch?v=wDBM6wVEO70

    That being said, you've correctly identified your problem: You have far fewer EditTexts than you do items in your list. As the you scroll through the list those EditTexts are recycled so you see the same input over and over again.

    Basically what you need to do is save the input for your EditTexts in some datastructure (a HashMap if they will only edit a few values, maybe a List if they will be changing most of the values, either would work) that maps the position to the input. You can do this by adding a textChangedListener to your edit texts in getView:

    @Override
    public View getView(final int position, View convertView, ViewGroup parent){
        ...
        cursor.moveToPosition(position);
        int label_index = cursor.getColumnIndex("userword");
        String label = cursor.getString(label_index);
    
        holder.text.setText(label);
    
        //clear whatever text was there from some other position
        //and set it to whatever text the user edited for the current 
        //position if available
        String oldText = yourMapOfPositionsToValues.get(position);
        holder.setText(oldText == null ? "" : oldText); 
    
        //every time the user adds/removes a character from the edit text, save 
        //the current value of the edit text to retrieve later
        holder.edittext.addTextChangedListener(new TextWatcher(){
            @Override
            public void afterTextChanged(Editable editable) {
                yourMapOfPositionsToValues.put(position, editable.toString());
            }
            ....
        };
    
        return convertView;
    }
    

    Whenever your user is done editing, you can run through your datastructure and do whatever with those values.

    Edit:

    I changed onTextChanged to afterTextChanged because I've used that before and I know it works. Keep in mind that afterTextChanged is called every time a LETTER changes, not just after the user finishes typing a word. If the user types "dog" afterTextChanged will be called three times, first with 'd', then with 'do', then with 'dog'.

    A HashMap is simple: Map yourMapOfPositionsToValues = new HashMap();

    to add or update an item: yourMap.put(position, someText); to fetch an item: yourMap.get(position);

    if hashmaps don't make sense, spend some time researching them. They are an incredibly important data structure.

    Your TextWatcher implementation is incorrect. Your data structure should not belong to a single view, but rather the activity or your adapter. It appears to you that positions aren't stable because your List is owned by each view. The positions themselves are stable in that unless the underlying data changes the cursor will return the same data every time for the same position. However, the edit text is used for multiple different positions.

    Create a hashmap as an instance variable I demonstrated above in the constructor of your adapter. Then add exactly the TextWatcher I wrote originally, no need for a named class, anonymous is simpler. Your code should work.

提交回复
热议问题