Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

ListView повторяет item (при скроллировании)

При скроллировании значения, которые я ввожу в поля AutoCompleteTextView or to EditText повторяется при добавлении items-operations (добавляю item из Activity) и прокручиваю книзу. Т. е. с виду похоже на то, что items повторяются, причем в некотором. Пытался найти ответ, но по форумам решения не помогли, что бы я ни делал с viewHolder, viewInflate, менял бы место инициализации, проблема не уходила. Всем спасибо за внимание!
Внизу мой адаптер OperationAdapter.java---------------------------------
class OperationAdapter extends BaseAdapter { public ArrayList operations; private Context context; private ArrayList operationns = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
public OperationAdapter(Context context, ArrayList operations) { this.operations = operations; this.context = context; operationns.add("Maltcev"); operationns.add("Loskut"); }
@Override public int getCount() { return operations.size(); }
@Override public Object getItem(int position) { return operations.get(position); }
@Override public long getItemId(int i) { return i; }
@Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder;
if (convertView == null) { LayoutInflater lInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = lInflater.inflate(R.layout.operation_item, null);
holder = new ViewHolder();
holder.timeEndOperation = (EditText) convertView.findViewById(R.id.timeEndOperation); holder.etc = (EditText) convertView.findViewById(R.id.etc); holder.deleteOperationBut = (Button) convertView.findViewById(R.id.deleteOperation); holder.saveOperationBut = (Button) convertView.findViewById(R.id.saveOperation); holder.startTimeBut = (Button) convertView.findViewById(R.id.startTimeBut); holder.finishTimeBut = (Button) convertView.findViewById(R.id.finishTimeBut); holder.timeBeginOperation = (EditText) convertView.findViewById(R.id.timeBeginningOperation); holder.operationsAutocomplete = (AutoCompleteTextView) convertView.findViewById(R.id.operationAutocomplete);
convertView.setTag(holder);

} else { holder = (ViewHolder)convertView.getTag(); }

ArrayAdapter adapterOperations = new ArrayAdapter(context, R.layout.support_simple_spinner_dropdown_item, operationns); holder.operationsAutocomplete.setAdapter(adapterOperations);
operations.get(position).timeOfStart = holder.timeBeginOperation.getText().toString(); operations.get(position).timeOfFinish = holder.timeEndOperation.getText().toString(); operations.get(position).etc = String.valueOf(position); operations.get(position).nameOfOperation = holder.operationsAutocomplete.getText().toString();
final ViewHolder viewHolderFinal = holder;
holder.deleteOperationBut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { viewHolderFinal.timeBeginOperation.clearComposingText(); viewHolderFinal.timeEndOperation.clearComposingText(); viewHolderFinal.etc.clearComposingText(); viewHolderFinal.operationsAutocomplete.clearComposingText();
operations.remove(position); notifyDataSetChanged(); } });
holder.startTimeBut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String currentStartTime = sdf.format(new Date()); viewHolderFinal.timeBeginOperation.setText(currentStartTime); } });
holder.finishTimeBut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String currentEndTime = sdf.format(new Date()); viewHolderFinal.timeEndOperation.setText(currentEndTime); } }); return convertView; }
public void addNewOperationCard() { Operation operation = new Operation("", "", "", ""); operations.add(operation); }
static class ViewHolder { public EditText timeBeginOperation; public EditText timeEndOperation; public EditText etc; public AutoCompleteTextView operationsAutocomplete; public Button deleteOperationBut; public Button saveOperationBut; public Button startTimeBut; public Button finishTimeBut; } }
и блок кода из Activity, где добавляются элементы в ListView:
final ListView operationListView = (ListView) findViewById(R.id.operationListView);
final OperationAdapter operationAdapter = new OperationAdapter(this, operations); operationListView.setAdapter(operationAdapter);
Button addOperationButton = (Button) findViewById(R.id.addOperationButton); addOperationButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { operationAdapter.addNewOperationCard(); operationAdapter.notifyDataSetChanged(); Toast.makeText(OperationAndWorkerActivity.this, operations.size() + " " + operationAdapter.operations.size(), Toast.LENGTH_LONG).show(); } });


Ответ

Вы биндите данные на айтем только при нажатии на кнопки. При такой логике, кэшированные значения не будут удалятся, если не нажимать на кнопку. Вам нужно в методе getView() адаптера явно указывать, какие именно данные должны быть отображены в айтеме с текущей позицией (без всяких нажатий и условий). например (я не понял из кода, что в айтеме должно отображаться, если кнопку не нажали, но какое то значение должно быть присвоено):
@Override public View getView(final int position, View convertView, ViewGroup parent) {
....
viewHolderFinal.timeBeginOperation.setText("some value"); viewHolderFinal.timeEndOperation.setText("another some value");
...
return convertView; }
то есть, для каждого виджета в айтеме должно быть однозначно указано, что в нем отображать в текущей позиции (а не только при нажатии на кнопку).Так нужно делать для всех виджетов на айтеме, значения которых меняются.
PS: Так же стоит заметить, что практика получения значений из виджетов ни до чего хорошего вас не доведет (как тут):
operations.get(position).timeOfStart = holder.timeBeginOperation.getText().toString()
получайте значение из самого источника данных, а не его отображения на экране.

Комментариев нет:

Отправить комментарий