I have the list of travelers with custom adapter what consist two EditText - edtFirstName and edtLastName. I want when user enters text save changes to List, and when next button click send this List to another activity.
My code:
public class TravellersAdapter extends BaseAdapter {
private List<Traveler> itemsList;
private LayoutInflater inflater;
private Activity context;
public TravellersAdapter(Activity context, List<Traveler> itemsList) {
super();
this.itemsList = itemsList;
this.context = context;
inflater = LayoutInflater.from(context);
}
public int getCount() { return itemsList.size(); }
public Object getItem(int i) { return itemsList.get(i); }
public View getView(final int position, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.traveller_item, null);
}
Traveler currentItem = (Traveler) getItem(position);
EditText firstNameView = (EditText) view.findViewById(R.id.edtFirstName);
firstNameView.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable editable) {
currentItem.setFirstName(editable.toString());
}
});
return view;
}
}
For exemple List itemsList consist 5 items. When I edit 2-4 element all ok, but when I edit first or last element edited value assigned to all element in List. In dubugger i saw that method afterTextChanged
calls 5 times with different values of position
.
How to fix it?
The issue happens because views are reusable (that is by design in Android API). So eventually you may assign more than 1 text watcher to the same text view. And all of the assigned watchers are fired when text inside of the text view is changed.
A quick fix (and non-optimal if the list is really long, say, of 1000+ items) would be to have a map of
Traweller -> TextWatcher
.Then inside of getView() you can do this (pseudo-code):
TextWatcher
for thisTraweller
TextWatcher
, put in the map and assign toEditText
TextWatcher
from theEditText
and remove from the mapTextWatcher
, put in the map and assign toEditText
in getView method, the parameter position gives the position of the newly created childView, not the clicked childView's position.
use this to get the correct position:
in
onClick(View v);
of theonClickListener
of any View. In you case, you must implement onTextChangedListener for that EditText.here:
myList is the ListView
v is the View you clicked, in this case the childView of the parent(myList).
Create one more
EditText
in the screen that is invisible with nameinvivisbleEt
. And do the following thing in theaddTextChangedListener
Also add this code in the
onCreate
method forListView
object.