I have a Listview with custom cursor adapter. I’m trying to prevent input in edittext field from being recycled. I’ve been working with a Hashmap. It works when you first scroll down (to not use data from 0 etc in the newly shown view). But when you scroll back up it recycles inputs again. I’m hoping someone here can spot my issue bc I’ve looked at other post with issue on recycled inputs with edittext and I can’t see what I’m doing wrong compared to what worked for other.
public class editview extends ListActivity {
private dbadapter mydbhelper;
public static int editCount;
public static ListView listView;
public ItemAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mydbhelper = new dbadapter(this);
mydbhelper.open();
View footer = getLayoutInflater().inflate(R.layout.footer_layout, null);
ListView listView = getListView();
listView.addFooterView(footer);
showResults();
}
//Populate view
private void showResults (){
Cursor cursor = mydbhelper.getUserWord();
startManagingCursor(cursor);
String[] from = new String[] {dbadapter.KEY_USERWORD};
int[] to = new int[] {R.id.textType};
adapter = new ItemAdapter(this, R.layout.edit_row, cursor,
from, to);
adapter.notifyDataSetChanged();
this.setListAdapter(adapter);
editCount = adapter.getCount();
}
//footer button
public void onClick(View footer){
final MediaPlayer editClickSound = MediaPlayer.create(this, R.raw.button50);
editClickSound.start();
startActivity(new Intent("wanted.pro.madlibs.OUTPUT"));
}
...
//custom cursor adapter
class ItemAdapter extends SimpleCursorAdapter {
private LayoutInflater mInflater;
private Cursor cursor;
static Map<Integer, String> inputValues = new LinkedHashMap<Integer, String>();
static String oldText;
public ItemAdapter(Context context, int layout, Cursor cursor, String[] from,
int[] to) {
super(context, layout, cursor, from, to);
this.cursor = cursor;
mInflater = LayoutInflater.from(context);
}
static class ViewHolder {
protected TextView text;
protected EditText edittext;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.edit_row, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.textType);
holder.edittext = (EditText) convertView.findViewById(R.id.editText);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
cursor.moveToPosition(position);
int label_index = cursor.getColumnIndex("userword");
String label = cursor.getString(label_index);
holder.text.setText(label);
oldText = inputValues.get(position);
holder.edittext.setText(oldText == null ? "" : oldText);
holder.edittext.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable editable) {
inputValues.put(position, editable.toString());
//Log.e(String.valueOf(position), "position in Hashmap");
//Log.e(inputValues.get(position), "data in Hashmap");
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
// TODO Auto-generated method stub
}
});
return convertView;
}
}
I tried this below code but it ended up having my recycled view called position 0.
static class ViewHolder implements TextWatcher {
protected TextView text;
protected EditText edittext;
protected int position;
public void afterTextChanged(Editable editable) {
Log.e(String.valueOf(position), "Position in array");
Log.e(editable.toString(), "data in array");
inputValues.put(position, editable.toString());
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.edit_row, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.textType);
holder.edittext = (EditText) convertView.findViewById(R.id.editText);
holder.position = position;
holder.edittext.addTextChangedListener(holder);
convertView.setTag(holder);
} else {....
You probably want to remove old TextWatcher instances before adding new ones. Looks like you have scope for multiple TextWatchers watching the same EditText for multiple positions in the list, which could end up looking like view recycling gone wrong.