0

I have a problem with EditText-fields in a listview. After i scroll some settings seem to be reset (selectAllOnFocus) and the selection cursor goes bananas.

I have a listview with a custom ArrayAdapter and a custom dataobject. In this case the object only holds one String (to simplify it).

My Activity

    // adapter + content
    List<ListviewObject> listViewContent = new ArrayList<ListviewObject>();
    for(int i = 0; i < 50; i++) {
        listViewContent.add(new ListviewObject("num: " + i));
    }       
    adapter = new CustomListAdapter(AddNewPerson.this, R.layout.list_item, listViewContent);

    // list
    ListView mListView = (ListView)findViewById(R.id.sample_list);
    mListView.setItemsCanFocus(true);
    mListView.setAdapter(adapter);

My Adapter

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    HolderObject holder = null;

    if(convertView == null) {
        convertView = mLayoutInflater.inflate(layoutResourceId, parent, false);
        holder = new HolderObject();
        holder.name = (TextView) convertView.findViewById(R.id.txt);
        convertView.setTag(holder);
    } else {
        holder = (HolderObject) convertView.getTag();
    }

    holder.lvObject = items.get(position);

    setNameTextChangeListener(holder);
// Retrieve the correct value 
    holder.name.setText(holder.lvObject.getName());

    return convertView;
}

public static class HolderObject {
    ListviewObject lvObject;
    TextView name;
}

private void setNameTextChangeListener(final HolderObject holder) {
    holder.name.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
// Update the value
            holder.lvObject.setName(s.toString());
        }

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

        @Override
        public void afterTextChanged(Editable s) { }
    });
}

To fix all the focusproblems I found in other threads I've set:
.setItemsCanFocus(true) on the listview
android:descendantFocusability="beforeDescendants" in the activity XML
android:windowSoftInputMode="adjustPan" in the manifest XML

Focussing and editing text works fine. When I scroll the correct values are held and all this seems to work fine.

Before I scroll and I click on some of the EditTexts this happens. (Last focused blurs, clicked one focuses, content is selected)

https://i.stack.imgur.com/Jxfzm.jpg

After I scroll down and up again, and do the same clicks as before, this happens.

https://i.stack.imgur.com/g5oJX.jpg

  • http://stackoverflow.com/questions/20406472/edittext-in-listview-loses-focus-when-pressed-on-android-4-x see this link – duggu Jun 11 '14 at 13:42
  • as per my knowledge it is a bad practice to use edit text in list view – duggu Jun 11 '14 at 13:46
  • I see. So using TextView instead of EditText and replacing them on click/blur seems like the most viable option, or even reusing the convertView, but not the EditText inside it (recreate that on getView). I ran into more quirks in my final setup so I don't really feel like hacking my way through some bad practice. – user3729954 Jun 11 '14 at 14:30

2 Answers2

0

This is due to listView recycling mechanism. To know more about listview recycling mechanism you can refer this link

in your case you avoid the problem by storing a last focused editText and In getView set focus to only last stored integer and skip other position. hope this help you...

Community
  • 1
  • 1
DjP
  • 4,537
  • 2
  • 25
  • 34
0

It's quite easy:

  1. Declare a String[] to keep track each EditText's input inside the afterTextChanged() of "addTextChangedListener().

  2. Becareful of the order:

    viewHolder.editText.removeTextChangedListener(viewHolder.textWatcher);
    
    viewHolder.textWatcher = 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) {
            mInputs[position] = editable.toString();            //record input
    
            viewHolder.editText.setSelection(viewHolder.editText.getText().length());       //set cursor to the end
        }
    };
    
    viewHolder.editText.addTextChangedListener(viewHolder.textWatcher);
    viewHolder.editText.setText(mInputs[position]);
    
  3. Add android:windowSoftInputMode="adjustPan" to your Activity in AndroidManifest file.

Good luck!

Sam Chen
  • 7,597
  • 2
  • 40
  • 73