EditText en ListView sin reciclar entrada

Todavía nuevo a androide e incluso más al adaptador del cursor de encargo así que estoy teniendo dificultad el entender cómo evitar que mi listview recicle las vistas para evitar la entrada de un edittext para demostrar para arriba en otra cuando está enrollado. He visto en otro post diciendo que cambiar el nombre de convertirview, pero cómo hacer que estoy dibujando un espacio en blanco. Esperaba que alguien aquí pudiera dar más detalles o un ejemplo de cómo hacer basado en qué código he escrito hasta ahora.

public class editview extends ListActivity { private dbadapter mydbhelper; private PopupWindow pw; public static int editCount; public static ListView listView; /** Called when the activity is first created. */ @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}; ItemAdapter 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; 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(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); return convertView; } } 

Se ha cambiado a

 class ItemAdapter extends SimpleCursorAdapter { private LayoutInflater mInflater; private Cursor cursor; Map<Integer, String> inputValues = new HashMap<Integer, String>(); 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); String 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()); } 

Pero es reciclaje después de todo edittext tener datos. Intentado usar holder.edittext.setText (oldText) pero el mismo efecto.

Empieza a rellenar los campos

Completar campos de relleno

Desplazarse hacia arriba.

En primer lugar, realmente no desea evitar que una vista de lista recicle sus vistas. Ver el reciclaje es una optimización enorme. Para un montón de información muy buena en las listas, consulte la charla de google IO: http://www.youtube.com/watch?v=wDBM6wVEO70

Dicho esto, ha identificado correctamente su problema: tiene mucho menos EditTexts que los elementos de su lista. A medida que se desplaza por la lista, EditTexts se recicla para que vea la misma entrada una y otra vez.

Básicamente, lo que debes hacer es guardar la entrada para tus EditTexts en alguna estructura de datos (un HashMap si solo editarán algunos valores, tal vez una Lista si van a cambiar la mayoría de los valores, o funcionaría) que asigna la posición a La entrada. Puede hacerlo añadiendo un textChangedListener a sus textos de edición en getView:

 @Override public View getView(final int position, View convertView, ViewGroup parent){ ... cursor.moveToPosition(position); int label_index = cursor.getColumnIndex("userword"); String label = cursor.getString(label_index); holder.text.setText(label); //clear whatever text was there from some other position //and set it to whatever text the user edited for the current //position if available String oldText = yourMapOfPositionsToValues.get(position); holder.setText(oldText == null ? "" : oldText); //every time the user adds/removes a character from the edit text, save //the current value of the edit text to retrieve later holder.edittext.addTextChangedListener(new TextWatcher(){ @Override public void afterTextChanged(Editable editable) { yourMapOfPositionsToValues.put(position, editable.toString()); } .... }; return convertView; } 

Cada vez que su usuario está hecho de edición, puede ejecutar a través de su datastructure y hacer lo que con esos valores.

Editar:

He cambiado onTextChanged a afterTextChanged porque he usado eso antes y sé que funciona. Tenga en cuenta que afterTextChanged se llama cada vez que cambia una LETTER, no sólo después de que el usuario termine de escribir una palabra. Si el usuario escribe "dog" después deTextChanged se llamará tres veces, primero con 'd', luego con 'do', luego con 'dog'.

Un HashMap es simple: Map yourMapOfPositionsToValues ​​= new HashMap ();

Para agregar o actualizar un elemento: yourMap.put (position, someText); Para obtener un elemento: yourMap.get (position);

Si hashmaps no tiene sentido, pasar algún tiempo investigándolos. Son una estructura de datos increíblemente importante.

Su implementación TextWatcher es incorrecta. Su estructura de datos no debe pertenecer a una sola vista, sino la actividad o su adaptador. Parece que las posiciones no son estables porque su Lista es propiedad de cada vista. Las posiciones mismas son estables en que a menos que los datos subyacentes cambien el cursor volverá los mismos datos cada vez para la misma posición. Sin embargo, el texto de edición se utiliza para múltiples posiciones diferentes.

Cree un hashmap como una variable de instancia que he demostrado anteriormente en el constructor de su adaptador. A continuación, agregue exactamente el TextWatcher que escribí originalmente, sin necesidad de una clase con nombre, anónimo es más simple. Su código debería funcionar.

La solución a esto es quitar el textwatcher agregado antes de fijar el texto. De lo contrario, el textwatcher anterior en esa vista seguirá siendo llamado junto con el nuevo textwatcher. Almacene el textwatcher como una etiqueta en el EditText para no perder de vista él.

 Object oldWatcher = viewHolder.quantitySold.getTag(); if(oldWatcher != null){ viewHolder.quantitySold.removeTextChangedListener((CustomTextWatcher)oldWatcher); } String oldText = inputValues.get("key"+position); Log.d(TAG, "oldText: "+oldText+" position: "+position); viewHolder.quantitySold.setText(oldText == null ? "" : oldText); CustomTextWatcher watcher = new CustomTextWatcher( cursor.getString(SKUFragment.COL_NAME), cursor.getInt(SKUFragment.COL_ID), cursor.getDouble(SKUFragment.COL_UNIT_PRICE), position ) { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (s != null) { int quantity = 0; if (!TextUtils.isEmpty(s.toString())) { quantity = Integer.parseInt(s.toString()); inputValues.put("key"+mPosition, "" + quantity); }else{ inputValues.put("key"+mPosition, ""); } double value = quantity * skuPrice; mListener.onQuantityChanged(skuName+", position: "+mPosition, skuId, quantity, value); } } }; viewHolder.quantitySold.setTag(watcher); viewHolder.quantitySold.addTextChangedListener(watcher); 
  • NotifyItemChanged () hace que el RecyclerView desplace y salte a UP
  • Diffutil en recycleview, lo que hace autoscroll si se agrega un nuevo elemento
  • Drawable vs Single reutilizable Bitmap mejor con la memoria?
  • Arrastrar y soltar entre dos RecyclerView
  • Implementación de la vista de reciclador anidada como aplicación de Google Play Store
  • Android: error de "intentar utilizar un mapa de bits reciclado" con Bitmaps temporales
  • No hay animación en el elemento RecyclerView seleccione Android
  • Anima intercambio de elementos en RecyclerView
  • GapWorker con vistas desechadas o adjuntas no se puede reciclar. IsScrap: false isAttached: true
  • Checkbox listener en RecyclerView con DataBinding
  • Subclasificación de SimpleCursorAdapter para incluir convertView para la conservación de la memoria
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.