2012-02-17 870 views
10

Tengo el elemento de la lista con EditText en él, no sé cuántos artículos habrá. Tengo un problema cuando ingreso texto en EditText, y luego despliego un ListView, después de volver a desplazarme, no hay texto en mi primer EditText, o hay texto de otro EditText de ListView.Android: ¿EditText pierde contenido en desplazamiento en ListView?

He intentado TextWatcher y guardo datos en una matriz, pero hay problemas en que la posición de vista devuelta en ListView no siempre es correcta, así que perdí algunos datos de la matriz.

Por favor ayuda.

Aquí está mi código:

public class EfficientAdapter extends BaseAdapter { 

    private LayoutInflater mInflater; 
    public String[] Current; 
    ArrayList<String> MeterName, PreviousReading, Current_Reading; 
    JSONArray getArray_Meter_Reading; 

    public EfficientAdapter(Context context, JSONArray getArray_Meter_Reading) { 
     mInflater = LayoutInflater.from(context); 
     this.getArray_Meter_Reading = getArray_Meter_Reading; 
     MeterName = new ArrayList<String>(); 
     PreviousReading = new ArrayList<String>(); 
     for (int i = 0; i < getArray_Meter_Reading.length(); i++) { 
      try { 
       String Meter_Name = getArray_Meter_Reading.getJSONObject(i) 
         .getString("MeterName").toString(); 
       String previous_Meter_Reading = getArray_Meter_Reading 
         .getJSONObject(i).getString("PrevMeterReading") 
         .toString(); 
       MeterName.add(Meter_Name); 
       PreviousReading.add(previous_Meter_Reading); 

       // Meter[i]=MeterName.get(i); 
       // Previous[i]=PreviousReading.get(i); 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    public int getCount() { 

     return getArray_Meter_Reading.length(); 
    } 

    public Object getItem(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

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

     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.meter_reading_list, null); 
      holder = new ViewHolder(); 
      holder.adp_MeterName = (TextView) convertView 
        .findViewById(R.id.txt_Meter_Name); 
      holder.adp_Previous = (TextView) convertView 
        .findViewById(R.id.txt_Previous); 
      holder.adp_Current = (EditText) convertView 
        .findViewById(R.id.ed_Current); 

      holder.adp_Current.addTextChangedListener(new TextWatcher() { 

       public void onTextChanged(CharSequence s, int start, 
         int before, int count) { 

       } 

       public void beforeTextChanged(CharSequence s, int start, 
         int count, int after) { 
        // TODO Auto-generated method stub 

       } 

       public void afterTextChanged(Editable s) { 

        Current[holder.ref] = s.toString(); 

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

     holder.ref = position; 
     holder.adp_MeterName.setText(MeterName.get(position)); 
     holder.adp_Previous.setText(PreviousReading.get(position)); 
     // holder.adp_Current.setHint(MeterName.get(position)); 

     // holder.adp_Current.setText(PreviousReading.get(position)); 

     return convertView; 
    } 

    class ViewHolder { 
     TextView adp_MeterName, adp_Previous; 
     EditText adp_Current; 
     int ref; 

    } 

} 

Respuesta

8

intente esto:

public class EfficientAdapter extends BaseAdapter { 

private LayoutInflater mInflater; 
public String[] Current; 
ArrayList<String> MeterName, PreviousReading, Current_Reading; 
JSONArray getArray_Meter_Reading; 
public static HashMap<Integer,String> myList=new HashMap<Integer,String>(); 

public EfficientAdapter(Context context, JSONArray getArray_Meter_Reading) { 
    mInflater = LayoutInflater.from(context); 
    this.getArray_Meter_Reading = getArray_Meter_Reading; 
    MeterName = new ArrayList<String>(); 
    PreviousReading = new ArrayList<String>(); 

    for (int i = 0; i < getArray_Meter_Reading.length(); i++) { 
     try { 
      String Meter_Name = getArray_Meter_Reading.getJSONObject(i) 
        .getString("MeterName").toString(); 
      String previous_Meter_Reading = getArray_Meter_Reading 
        .getJSONObject(i).getString("PrevMeterReading") 
        .toString(); 
      MeterName.add(Meter_Name); 
      PreviousReading.add(previous_Meter_Reading); 

      // Meter[i]=MeterName.get(i); 
      // Previous[i]=PreviousReading.get(i); 
     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    // initialize myList 
    for(int i=0;i<JSON_ARRAY_LENGTH;i++) 
    { 
     myList.put(i,""); 
    } 
} 

public int getCount() { 

    return getArray_Meter_Reading.length(); 
} 

public Object getItem(int position) { 
    // TODO Auto-generated method stub 
    return position; 
} 

public long getItemId(int position) { 
    // TODO Auto-generated method stub 
    return position; 
} 

public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    final int pos=position; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.meter_reading_list, null); 
     holder = new ViewHolder(); 
     holder.adp_MeterName = (TextView) convertView 
       .findViewById(R.id.txt_Meter_Name); 
     holder.adp_Previous = (TextView) convertView 
       .findViewById(R.id.txt_Previous); 
     holder.adp_Current = (EditText) convertView 
       .findViewById(R.id.ed_Current); 


     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.adp_Current.addTextChangedListener(new TextWatcher() { 

      public void onTextChanged(CharSequence s, int start, 
        int before, int count) { 

      } 

      public void beforeTextChanged(CharSequence s, int start, 
        int count, int after) { 
       // TODO Auto-generated method stub 

      } 

      public void afterTextChanged(Editable s) { 

       Current[holder.ref] = s.toString(); 
       myList.put(pos,s.toString.trim()); 
      } 
     }); 
    holder.ref = position; 
    holder.adp_MeterName.setText(MeterName.get(position)); 
    holder.adp_Previous.setText(PreviousReading.get(position)); 
    // holder.adp_Current.setHint(MeterName.get(position)); 

    // holder.adp_Current.setText(PreviousReading.get(position)); 

    holder.adp_Current.setText(myList.get(position)); 

    return convertView; 
} 

class ViewHolder { 
    TextView adp_MeterName, adp_Previous; 
    EditText adp_Current; 
    int ref; 

} 

} 

Aquí he incluido un objeto HashMap que mantener un ojo en si contiene EditarTexto valor o not.and cuando se desplaza la vista de lista, se volverá a representar llamando a su método getView junto con el texto asociado a cada texto de edición.

En este código, cuando cargue listview por primera vez, todo el texto de edición estará sin texto. Cuando ingrese texto, se anotará en myList.So cuando vuelva a mostrar la lista, se evitará el texto.

Una cosa más, debe implementar textwatcher fuera if (convertView == null) .. else .. block.That es una mejor práctica!

+0

lo que es diferente en ella? –

+0

¿has mirado el código que sugerí? ¡contiene un objeto HashMap there.go a través del código primero! – Hiral

+1

qué problema tengo cuando escribo algún valor en 1st edittext y me desplazo hacia abajo a la lista, el valor en 1st edittext se muestra en algún otro cuadro de texto de edición. puede dar una solución para ese im que enfrenta este problema de los últimos tres días. –

9

Estaba teniendo exactamente el mismo problema con un proyecto en el que estaba trabajando. Todas las soluciones que encontré también mencionaron usar el textChangeListener, sin embargo, debido a la naturaleza de la lista, y con un EditText en cada vista de fila, esto fue muy ineficiente. Tomé un enfoque separado usando el EditText.setOnFocusChangeListener().

Adjunté esto a cada EditText dentro del método getView. La razón por la que esto funciona tan bien es que se llama cuando el usuario cambia a un texto de edición diferente o se desplaza para que la fila actual esté fuera de la pantalla, lo que hace que el EditText pierda el foco.

En el onFocusChange (Ver v, hasFocus booleano) dentro del oyente simplemente poner:

if (!hasFocus) { 
       EditText et = (EditText) v.findViewById(R.id.groupAmount);     
       data.get(position).put("dueAmount", et.getText().toString().trim()); 
      } 

En mi ejemplo estoy almacenando el valor entrado en mis datos se utiliza para rellenar las vistas en cada llamada getView, pero esto aún debería mostrar cómo acceder a los datos ingresados ​​por el usuario. Solo asegúrate de intentar tomar esta información almacenada e intenta llenar el editText en la posición correspondiente.

Espero que esto ayude.

Publicar mi adaptador completo aquí como referencia

public class memberlistadapter extends BaseAdapter { 
private LayoutInflater mInflater; 
public ArrayList<Hashtable<String, String>> data; 
ViewHolder viewHolder; 
public static HashMap<Integer,String> myList=new HashMap<Integer,String>(); 

public memberlistadapter(Context context) { 
    mInflater = LayoutInflater.from(context); 
} 

public memberlistadapter(Activity activity, ArrayList<Hashtable<String, String>> objects) { 
    super(); 
    mInflater = activity.getLayoutInflater(); 
    //this.activity = activity; 
    this.data = objects; 
    Log.d("data", data.toString()); 
} 

public void clear() { 
    this.data.clear(); 
    viewHolder = null; 
} 

public void setData(ArrayList<Hashtable<String, String>> data) { 
    this.data = data; 
} 

public int getCount() { 
    return data.size(); 
} 

public Object getItem(int item) { 
    return data.get(item); 
} 

public long getItemId(int position) { 
    return position; 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.member_amount_child, null); 
     viewHolder = new ViewHolder(); 

     viewHolder.nameText = (TextView) convertView.findViewById(R.id.grp_amt_child); 
     viewHolder.amountText = (EditText) convertView.findViewById(R.id.groupAmount); 
     viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.memberCheckNotif); 

     convertView.setTag(viewHolder); 

    } else { 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 
    //Log.d("data at "+position, data.get(position).toString()); 
    String amt = data.get(position).get("dueAmount"); 
    String name = data.get(position).get("name"); 
    String check = data.get(position).get("reminder"); 

    viewHolder.nameText.setText(name); 
    try { 
    if (amt.length() > 0 && !amt.equalsIgnoreCase("0")) { 
     viewHolder.amountText.setText(amt); 
    } else { 
     viewHolder.amountText.setText(""); 
    } 
    } catch (Exception e) { 
     viewHolder.amountText.setText(""); 
    } 

    viewHolder.amountText.setOnFocusChangeListener(new View.OnFocusChangeListener() { 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (!hasFocus) { 
       EditText et = (EditText) v.findViewById(R.id.groupAmount); 
       data.get(position).put("dueAmount", et.getText().toString().trim()); 
      } 
     } 
    }); 

    try { 
    if (check.equalsIgnoreCase("true")) { 
     viewHolder.checkBox.setChecked(true); 
    } else { 
     viewHolder.checkBox.setChecked(false); 
    } 
    } catch (Exception e) { 
     viewHolder.checkBox.setChecked(false); 
    } 
    viewHolder.checkBox.setOnClickListener(new View.OnClickListener() { 

     public void onClick(View v) { 
      if (((CheckBox) v).isChecked()) { 
       data.get(position).put("reminder", "True"); 
      } else { 
       data.get(position).put("reminder", "False"); 
      } 
     } 
    }); 
    if (position == 0) { 
     viewHolder.checkBox.setVisibility(View.GONE); 
     viewHolder.amountText.setVisibility(View.GONE); 
     viewHolder.nameText.setVisibility(View.GONE); 
    } else { 
     viewHolder.checkBox.setVisibility(View.VISIBLE); 
     viewHolder.amountText.setVisibility(View.VISIBLE); 
     viewHolder.nameText.setVisibility(View.VISIBLE); 
    } 

    return convertView; 
} 

static class ViewHolder { 
    TextView nameText; 
    EditText amountText; 
    CheckBox checkBox; 
} 
} 
+3

esto no resuelve el problema en absoluto. Si coloca texto en Editar texto y luego se desplaza, el primer texto de edición no pierde el foco y la entrada se pierde. – kiduxa

+0

@kiduxa Use 'addTextChangedListener' en lugar de' setOnClickListener' para EditText y ponga 'vendorList.get (position) .put (" preference ", et_preference.getText(). ToString(). Trim());' en ** afterTextChanged ** –

Cuestiones relacionadas