简体   繁体   中英

ListView Item Position Change on Scroll

When I scroll down/up so quickly, the position changes so fast that it messes up the item for the position, causing the texts to change instead of what it should be. I've been searched around fixes but can't seem to figure where it went wrong. Below is my Custom ArrayAdapter Code

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.TextView;

import java.util.ArrayList;

import aungkyawpaing.ngapyinkeyboard.Models.CustomKey;
import aungkyawpaing.ngapyinkeyboard.R;
import butterknife.ButterKnife;
import butterknife.InjectView;

/**
 * Created by Vincent on 16-Apr-15.
 */
public class CustomKeyAdapter extends ArrayAdapter<CustomKey> {

    private int size;
    ArrayList<CustomKey> datas = new ArrayList<>();

    public CustomKeyAdapter(Context context, ArrayList<CustomKey> list) {
        super(context, R.layout.listitem_customkey, list);
        size = list.size();
    }

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

        if (convertView != null) {
            viewHolder = (ViewHolder) convertView.getTag();
        } else {
            LayoutInflater layoutInflater =
                    (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.listitem_customkey, parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }
        CustomKey key = getItem(position);
        datas.add(position, key);

        viewHolder.txt_number.setText("Key #" + (position + 1) + " : ");
        viewHolder.value_field.setText(key.getOutput());
        viewHolder.value_field.addTextChangedListener(new MyTextWatcher(position));

        return convertView;
    }

    private class MyTextWatcher implements TextWatcher {

        private int position;

        public MyTextWatcher(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            CustomKey key = getItem(position);
            key.setOutput(editable.toString());
            datas.add(position, key);
        }
    }

    static class ViewHolder {
        @InjectView(R.id.custom_key_number) TextView txt_number;
        @InjectView(R.id.custom_key_value) EditText value_field;

        public ViewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }

    public ArrayList<CustomKey> getValues() {
        return datas;
    }
}

EDIT: TextView is fine, it's just the texts in EditText that keep changing

Before adding the TextWatcher to the EditText remove the existing TextWatcher of the EditText .
In the TextWatcher

 static class ViewHolder {
        @InjectView(R.id.custom_key_number) TextView txt_number;
        @InjectView(R.id.custom_key_value) EditText value_field;
        MyTextWatcher myWatcher;
        public ViewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }

Now remove the existing TextWatcher of the EditText ,initialize the TextWatcher of the view holder in the getView() method and add the TextWatcher to the EditText

 public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;

        if (convertView != null) {
            viewHolder = (ViewHolder) convertView.getTag();
        } else {
            LayoutInflater layoutInflater =
                    (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.listitem_customkey, parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }
        CustomKey key = getItem(position);
        datas.add(position, key);

        viewHolder.txt_number.setText("Key #" + (position + 1) + " : ");
        viewHolder.value_field.setText(key.getOutput());
        //Remove the myWatcher
        viewHolder.value_field.emoveTextChangedListener(myWatcher);
        viewHolder.myWatcher=new MyTextWatcher(position);
        //add the myWatcher
        viewHolder.value_field.addTextChangedListener(myWatcher);

        return convertView;
    }

I have solved the issue. I will Seems like in "onTextChanged", the key is referencing to the item in the view. and therefore setOutput changes that key output. Fixed the issue with following code

public void afterTextChanged(Editable editable) {
    CustomKey key = getItem(position);
    datas.add(position,  new CustomKey(key.getCode(), editable.toString()));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM