When scrolling, the values ​​that I enter in the AutoCompleteTextView or to EditText fields are repeated when adding items-operations (adding an item from Activity) and scrolling down. That is, it looks like items are repeating, and in some. I tried to find the answer, but the solutions did not help the forums, no matter what I did with the viewHolder, viewInflate, I would change the place of initialization, the problem did not go away. Thank you all for your attention!

Below is my adapter OperationAdapter.java ---------------------------------

class OperationAdapter extends BaseAdapter { public ArrayList<Operation> operations; private Context context; private ArrayList<String> operationns = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); public OperationAdapter(Context context, ArrayList<Operation> 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<String> adapterOperations = new ArrayAdapter<String>(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; } } 

and a block of code from the Activity, where elements are added to the 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(); } }); 

    2 answers 2

    You only bind the data to the item by clicking on the buttons. With this logic, cached values ​​will not be deleted if you do not press a button. You need to explicitly indicate in the getView() method of the adapter exactly which data should be displayed in the item with the current position (without any clicks and conditions). for example (I did not understand from the code what should be displayed in the item if the button was not pressed, but some value should be assigned):

     @Override public View getView(final int position, View convertView, ViewGroup parent) { .... viewHolderFinal.timeBeginOperation.setText("some value"); viewHolderFinal.timeEndOperation.setText("another some value"); ... return convertView; } 

    that is, for each widget in the item it should be clearly indicated what to display in the current position (and not just when you press the button). So you need to do for all widgets on the item whose values ​​change.

    PS: It is also worth noting that the practice of getting values ​​from widgets will not bring you anything good (like this):

     operations.get(position).timeOfStart = holder.timeBeginOperation.getText().toString() 

    get the value from the data source itself, rather than displaying it on the screen.

    • Thank! With logic cleared! Tell me, please, what to do, what to do in a situation - the user enters data but does not save and adds an item in large quantities. Do you need to somehow save the values ​​that are entered but not entered anywhere? - Michael Strelchenko
    • String a = holder.timeBeginOperation.getText (). ToString (); String b = holder.timeEndOperation.getText (). ToString (); String c = holder.etc.getText (). ToString (); String d = holder.operationsAutocomplete.getText (). ToString (); final ViewHolder viewHolderFinal = holder; viewHolderFinal.timeBeginOperation.setText (a); viewHolderFinal.timeEndOperation.setText (b); viewHolderFinal.etc.setText (c); viewHolderFinal.operationsAutocomplete.setText (d); By default, the empty item fields are empty - "" - Michael Strelchenko 4:02 pm
    • about input to EditText - something like this is done - pavlofff pm
    • Your last link to the trick post helped me a lot in the context of using focus-listener in my adapter. Everything worked out. Thank you so much! - Michael Strelchenko

    Cells in the list are reused for optimization. Those. not every time the list is scrolled, the markup is loaded from the xml file. If there is already loaded - it will be displayed. There, of course, there will be information not of the desired cell, but cached. You do not take this into account in the code and assign text to the cell only when loading markup from xml . Just transfer the text assignment code immediately after receiving an instance of the holder:

     if (convertView == null) { LayoutInflater lInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = lInflater.inflate(R.layout.operation_item, null); holder = new ViewHolder(); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } 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); //ТУТ НАДО УСТАНОВИТЬ ТЕКСТ, КАРТИНКИ И ПРОЧЕЕ ДЛЯ ВСЕХ ЭЛеМЕНТОВ РАЗМЕТКИ 
    • Yuri, thanks for the reply! Now with the logic of this action it has become clear, but the item is still repeated when scrolling ... (it did this before, but did not help) Perhaps you still need to somehow reset the view? - Michael Strelchenko
    • get links to widgets the same does not set a value in them - pavlofff
    • one
      @pavlofff, yes, really) Something I hurried up) - Yuriy SPb