У меня есть активность 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, поэтому я не уверен, что есть лучший подход для решения моей проблемы.Любая помощь приветствуется.