В CustomDialog создан CustomAdapter
Кастом адаптер создаёт поля с элементами EditText и Button.
Поля EditText заполняются из arrayAdapter.
Когда по нажатию на кнопку создаёшь несколько едиттекстов в листвью и прокручиваешь список вниз, те элементы, которые ушли за экран, очищаются от данных.
Исходный экран
Создали парочку едитТекстов по нажатию на "+"
Прокрутили вниз списка и вернулись наверх
Код с адаптера:
public class CustomDialogAdapter extends ArrayAdapter<ItemNotify> {
private Context context;
ArrayList<ItemNotify> arrayList;
long id_pray;
InputFilter timeFilter;
private boolean doneOnce = false;
public CustomDialogAdapter(Context context, ArrayList<ItemNotify> arrayList, long id_pray) {
super(context, R.layout.activity_custom_dialog, arrayList);
this.context = context;
this.arrayList = arrayList;
this.id_pray = id_pray;
}
static class ViewHolder {
public EditText editText;
public Button delete;
public Button add;
public LinearLayout lay;
public TextView txposition;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.item_for_customdialog_adapter, null, true);
holder = new ViewHolder();
holder.txposition = (TextView) rowView.findViewById(R.id.textViewItem2);
holder.editText = (EditText) rowView.findViewById(R.id.editTextItem2);
holder.delete = (Button) rowView.findViewById(R.id.button);
holder.add = (Button) rowView.findViewById(R.id.button2);
holder.lay = (LinearLayout) rowView.findViewById(R.id.lay);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
holder.txposition.setText((position + 1)+"");
holder.editText.setText(getItem(position).time);
holder.editText.addTextChangedListener(new MyTextWatcher(position));
return rowView;
}
private class MyTextWatcher implements TextWatcher {
private int position;
public MyTextWatcher(int position) {
this.position = position;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
Log.e("edit", "edit " + s);
arrayList.get(position).time = s.toString();
if (arrayList.get(position).en != StatusNotifi.NEW) {
arrayList.get(position).en = StatusNotifi.EDIT;
}
}
}
}
Спасибо за совет, pavlofff
UPD: сделал. Это уже рабочий код класса
public class CustomDialogAdapter extends ArrayAdapter<ItemNotify> {
private Context context;
ArrayList<ItemNotify> arrayList;
long id_pray;
InputFilter timeFilter;
private boolean doneOnce = false;
public CustomDialogAdapter(Context context, ArrayList<ItemNotify> arrayList, long id_pray) {
super(context, R.layout.activity_custom_dialog, arrayList);
this.context = context;
this.arrayList = arrayList;
this.id_pray = id_pray;
}
static class ViewHolder { // класс для кеширования вьюшек, чтоб они каждый раз не пересоздавались
public EditText editText;// поле ввода
public Button delete; // удаление поля ввода
public Button add; // добавление поля ввода
public LinearLayout lay; // слой, нужен чтоб при удалении поля удалялся весь слой
public TextView txposition; //нумерация полей
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.item_for_customdialog_adapter, null, true);
holder = new ViewHolder();
holder.txposition = (TextView) rowView.findViewById(R.id.textViewItem2);
holder.editText = (EditText) rowView.findViewById(R.id.editTextItem2);
holder.delete = (Button) rowView.findViewById(R.id.button);
holder.add = (Button) rowView.findViewById(R.id.button2);
holder.lay = (LinearLayout) rowView.findViewById(R.id.lay);
rowView.setTag(holder); // установили тэг на элемент
} else {
holder = (ViewHolder) rowView.getTag(); // получили нужный элемент по тэгу
}
holder.txposition.setText((position < 9 ? "0" : "") + (position + 1)+".");// для выравнивания размера добавляем 0, позиция идёт с 0
if (position == 0) { // на 0-й позиции кнопку удаления скрываем, чтоб нельзя было удалить все поля
holder.delete.setVisibility(View.INVISIBLE);
}else{
holder.delete.setVisibility(View.VISIBLE);
}
timeFilter = new InputFilter() { // фильтр ввода. позволяет вводить от 00:00 до 23:59
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
int dstart, int dend) {
if (source.length() > 1 && !doneOnce) {
source = source.subSequence(source.length() - 1, source.length());
if (source.charAt(0) >= '0' && source.charAt(0) <= '2') { // первый символ может быть 0,1,2
doneOnce = true; //флаг первого символа в editText
return source;
} else {
return ""; //остальные символы будут зануляться
}
}
if (source.length() == 0) {
return null;// deleting, keep original editing
}
String result = "";
result += dest.toString().substring(0, dstart);
result += source.toString().substring(start, end);
result += dest.toString().substring(dend, dest.length());
if (result.length() > 5) { // если в поле 5 символов( 1 2 : 4 5 )
return "";// не разрешать добавлять символы
}
boolean allowEdit = true;
char c;
if (result.length() > 0) {
c = result.charAt(0);
allowEdit &= (c >= '0' && c <= '2');
}
if (result.length() > 1) {
c = result.charAt(1);
if (result.charAt(0) == '0' || result.charAt(0) == '1')
allowEdit &= (c >= '0' && c <= '9');
else
allowEdit &= (c >= '0' && c <= '3');
}
if (result.length() > 2) {
c = result.charAt(2);
allowEdit &= (c == ':');
}
if (result.length() > 3) {
c = result.charAt(3);
allowEdit &= (c >= '0' && c <= '5');
}
if (result.length() > 4) {
c = result.charAt(4);
allowEdit &= (c >= '0' && c <= '9');
}
return allowEdit ? null : "";
}
};
holder.editText.clearFocus(); // снимаем фокусировку(выполнится, когда мы начнём прокручивать список и отрисуется новый элемент)
holder.editText.setText(getItem(position).time); //установка времени с массива arrayList
if (arrayList.get(position).editDisabled == 1) { //если поле = 1 ("не удаляемое")
holder.editText.setFocusable(false); //не фокусить
holder.editText.setClickable(false); //не кликать
holder.editText.setFocusableInTouchMode(false);
holder.delete.setVisibility(View.INVISIBLE); //кнопку Х убрать
} else { //если поле удаляемое
holder.editText.setFilters(new InputFilter[]{timeFilter}); // установили наш фильтр полю
holder.editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { // слушатель смены фокуса на полях
@Override
public void onFocusChange(View v, boolean hasFocus) {
Log.e("edit", "edit: " + hasFocus);
if(hasFocus) return; // пока есть фокус на поле, которое заполняем, делаем прерывание
EditText ed = (EditText) v; // находим адрес поля(берём с принимаемых аргументов)
arrayList.get(position).time = ed.getText().toString(); // вносим данные с текущего поля
if (arrayList.get(position).en != StatusNotifi.NEW) { // метка статуса поля массива
arrayList.get(position).en = StatusNotifi.EDIT; //(новое или изменённое)
}
}
});
}
holder.delete.setOnClickListener(new View.OnClickListener() { //реализация удаления поля
@Override
public void onClick(View v) {
holder.lay.setVisibility(View.GONE); //спрятали наш слой
arrayList.get(position).en = StatusNotifi.DELETED; //дали статус поля "удалённое"
}
});
holder.add.setOnClickListener(new View.OnClickListener() { //реализация добавления поля
@Override
public void onClick(View v) {
arrayList.add(new ItemNotify(StatusNotifi.NEW, id_pray)); //добавили объект в массив
CustomDialogAdapter.this.notifyDataSetChanged(); // и уведомили адаптер об этом
}
});
return rowView;
}
}



arrayList, считывая их с полей ввода(типа "кэш"). По поводу дубликата вопроса, там ведь нет точного ответа и там адаптер курсорный используется – zayn1991 May 16 '16 at 06:33TextWotcher, а по потере фокусаOnFocusChangeListener, как в ответе-копии – pavlofff May 16 '16 at 07:55