Custom Adapter with EditText проблема с позицией

109
28 октября 2019, 09:20

Уважаемые специалисты, бьюсь вот уже несколько часов. Задача, генерировать динамически список с помощью кастомного адаптера, проверять чтобы пользователь ввел все данные в динамически созданные поля EditText, затем проверять корректность ввода и если все нормально, то обрабатывать данные дальше. Проблема заключается в том, что я провожу валидацию полей через метод в главном классе приложения, получая у адаптера ссылку на статический список объектов ArrayList.

Кастомный адаптер выглядит примерно так:

// получение списка с нужным типом
public static ArrayList<RowData> objects;

Дальше стандартно получение вьюхи списка, на этом этапе все замечательно

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) {
        holder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) ctx
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.row_data_send_for_adapter, parent, false);
        holder.editText = convertView.findViewById(R.id.send_new_counter);
        convertView.setTag(holder);
    }else {
        holder = (ViewHolder)convertView.getTag();
    }
    holder.editText.setText(objects.get(position).getEditTextValue());
    RowData p = getProduct(position);
    ((TextView) convertView.findViewById(R.id.place)).setText(getPlace(p.place));
    ((TextView) convertView.findViewById(R.id.name_counter)).setText(getName(p.name_counter));
    ((TextView) convertView.findViewById(R.id.old_counter)).setText(p.old_counter);
    // Initialize edit text to empty
    objects.get(position).setEditTextValue(holder.editText.getText().toString());
    holder.editText.addTextChangedListener(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) {
            objects.get(position).setEditTextValue(holder.editText.getText().toString());
            Log.d(Settings.getLog(), "position=" + position); // смотрим в какой позиции(в каком объекте из списка) изменяется поле editText
        }
        @Override
        public void afterTextChanged(Editable editable) {
        }
    });
    return convertView;
}
private class ViewHolder {
    protected EditText editText;
}
// собственно сам метод, возвращающий ссылку на список объектов
public ArrayList<RowData> getObjects(){
    return objects;
}

Дальше в main классе мы объявляем метод, который получает и перебирает элементы из списка. Остальные методы опущены.

    private boolean checkField(){
    boolean result = true;
    Log.d(Settings.getLog(), "object.length()=" + rowAdapter.getObjects().size());
    for (RowData object : rowAdapter.getObjects()) {
        if (object.getEditTextValue().length() == 0)
        {
            Log.d(Settings.getLog(), "object.getEditTextValue().length()=" + object.getEditTextValue().length() + object.getClass().getName());
            result = false;
        }
        Log.d(Settings.getLog(), "objects=" + object.getEditTextValue());
    }
    Log.d(settings.getLog(), "result=" + result);
    return result;
}

И почему-то валидация происходит не корректно, если заполнено самое первое поле из списка с позицией 0. Логи я ставил не зря и решил посмотреть. Допустим у нас есть три элемента в списке. Я щелкаю по первому EditText(должна быть позиция 0), но в логах генерируется вот что:

2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=0
2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=1
2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=2
2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=0
2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=1
2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=2
2019-02-26 19:41:50.207 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=0

Итак при каждом изменеии текста в EditText первого элемента

Если же изменять текст в любом другом элементе, то все отрабатывает корректно.

2019-02-26 19:44:39.415 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=1

или

2019-02-26 19:44:54.832 22933-22933/kz.kyzylzhar_su.kyzyljarsu D/myLog: position=2

Помогите понять в чем моя ошибка.

Answer 1

В общем после внимательного изучения и тестов пришел к выводу, что вьюхи нужно было создавать в любом случае без проверки на null, после корректировки кода до вида

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;

    holder = new ViewHolder();
    LayoutInflater inflater = (LayoutInflater) ctx
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.row_data_send_for_adapter, parent, false);
    holder.editText = convertView.findViewById(R.id.send_new_counter);
    convertView.setTag(holder);
    RowData p = getProduct(position);
    ((TextView) convertView.findViewById(R.id.place)).setText(getPlace(p.place));
    ((TextView) convertView.findViewById(R.id.name_counter)).setText(getName(p.name_counter));
    ((TextView) convertView.findViewById(R.id.old_counter)).setText(p.old_counter);
    // Initialize edit text to empty
    objects.get(position).setEditTextValue(holder.editText.getText().toString());
    holder.editText.addTextChangedListener(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) {
            objects.get(position).setEditTextValue(holder.editText.getText().toString());
           // Log.d(Settings.getLog(), "position=" + position);
        }
        @Override
        public void afterTextChanged(Editable editable) {
        }
    });
    return convertView;
}

все заработало прекрасно. Может кому-то будет полезно.

READ ALSO
java.net.ConnectException: Connection refused: connect

java.net.ConnectException: Connection refused: connect

При запуске клиент-серверного приложения ЧАТА вылетает ошибка, указанная в заголовке

118
Закругленные края у кнопки

Закругленные края у кнопки

Подскажите пожалуйста как закруглить края у кнопки или какого-либо другого обьекта

132
убрать в дереве svg не создавая новый класс

убрать в дереве svg не создавая новый класс

Имеется класс, мне надо сделать так, чтобы в 1 дереве была показана svg, а в другом она пряталасьКак можно сделать, не создавая новый класс?

131
Как отменить overflow:hidden, для дочернего элемента

Как отменить overflow:hidden, для дочернего элемента

Есть вот такая вёрстка которую нельзя ломать

156