У меня есть действие Android, в котором у меня есть ListView, привязанный к настраиваемому ArrayAdapter. Каждая строка ListView имеет два поля EditText (числовых).
ArrayAdapter изначально заполняется из базы данных SQLite. Однако пользователь может добавить строку в конец ListView или (путем длительного нажатия на строку) удалить любую строку в ListView. Когда они нажимают кнопку «Сохранить», их изменения сохраняются.
Я отслеживаю внесенные изменения, прикрепляя CustomTextWatcher для события AfterTextChanged () к каждому EditText в методе getView () ArrayAdapter (передавая EditText и соответствующий объект в списке элементов ArrayAdapter), а затем установка соответствующего свойства этого объекта на содержимое EditText. Это сделано для того, чтобы при сохранении я мог просто пройтись по базовому списку объектов и внести соответствующие изменения в БД, зная, что список объектов актуален.
Код для класса адаптера и CustomTextWatcher:
private class CustomAdapter extends ArrayAdapter<DataItem> {
private ArrayList<DataItem> items;
public CustomAdapter(Context context, int textViewResourceId, ArrayList<DataItem> items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
DataItem wed = items.get(position);
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.log_exercise_row, null);
}
if(wed != null)
{
EditText text1 = (EditText) v.findViewById(R.id.text1);
EditText text2 = (EditText) v.findViewById(R.id.text2);
text1.addTextChangedListener(new CustomTextWatcher(text1,wed));
text2.addTextChangedListener(new CustomTextWatcher(text2,wed));
int weight = wed.getWeight();
if(weight != -1)
{
text1.setText(weight+"");
}
int reps = wed.getReps();
if(reps != -1)
{
text2.setText(reps+"");
}
}
return v;
}
private class CustomTextWatcher implements TextWatcher {
private EditText EditText;
private DataItem item;
public CustomTextWatcher(EditText e, DataItem item)
{
this.EditText = e;
this.item = item;
}
@Override
public void afterTextChanged(Editable arg0) {
String text = arg0.toString();
if(text != null && text.length() > 0)
{
int val;
try
{
val =Integer.parseInt(text);
}
catch(NumberFormatException e)
{
val=-1;
}
if(EditText.getId()==R.id.weightEditText)
{
item.setWeight(val);
}
else if(EditText.getId()==R.id.repsEditText)
{
item.setRepetitions(val);
}
}
}
Все это работает нормально, за исключением случаев, когда элементы добавляются или удаляются, когда происходит нежелательное дублирование содержимого EditText.
Для иллюстрации на примере:
Начните с 3 строк, EditText все пуст
В строке 2 введите '5', '6'
Нажмите ' Еще '-> Добавляет (пустую) строку в конец. Теперь 4 ряда.
Удалить последнюю строку -> отображаются 3 строки, НО 2-я И 3-я строки теперь отображают '5', '6' -> ???????
Похоже, что относительное положение Объекты EditText в ListView нестабильны после повторной привязки, что вызывает проблему. Например. Объект EditText 'X' начинается в позиции 3, затем после повторной привязки он оказывается в позиции 1, но к нему по-прежнему прикреплен CustomTextWatcher, ссылающийся на объект данных в позиции 3. Другая проблема заключается в том, что addTextChangedListener () не влияет на TextWatchers уже прикреплены к EditText.
Я новичок в Android, поэтому не уверен, что есть лучший подход для решения моей проблемы. Любая помощь приветствуется.