2012-02-17 11 views
10

Mam element listy z EditText w nim, nie wiem, ile elementów będzie. Mam problem, gdy wpisuję jakiś tekst w numerze EditText, a następnie przewijam w dół znak ListView, po ponownym przewinięciu w górę nie ma tekstu w moim pierwszym EditText lub jest jakiś tekst z innego EditText z ListView.Android: EditText traci zawartość na przewijanie w ListView?

Próbowałem już TextWatcher i zapisywanie danych do tablicy, ale problem polega na tym, że zwrócona pozycja widoku w ListView nie zawsze jest poprawna, więc straciłem dane z tablicy.

Proszę o pomoc.

Oto mój kod:

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; 

    } 

} 

Odpowiedz

8

spróbuj tego:

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; 

} 

} 

Tutaj mam włączone obiekt HashMap które będą pilnować jeśli EditText zawiera wartość lub not.And podczas przewijania listview, zostanie ono zrenderowane ponownie przez wywołanie metody getView wraz z tekstem powiązanym z każdym edittext.

W tym kodzie, po pierwszym załadowaniu listview, cały twój edittext będzie bez tekstu. Po wprowadzeniu jakiegoś tekstu, zostanie to odnotowane w myList.So, gdy ponownie wyświetlisz listę, twój tekst zostanie zablokowany.

Jeszcze jedno, powinieneś zaimplementować textwatchera na zewnątrz, jeśli (convertView == null) .. else .. block.To jest lepsza praktyka!

+0

co różni się w nim? –

+0

Czy sprawdziłeś kod, który zasugerowałem? zawiera obiekt HashMap tam. Przejdź przez kod pierwszy! – Hiral

+1

jaki problem napotykam, gdy wpisuję jakąś wartość w 1. edycji i przewijam w dół do listy, wyświetlana jest wartość w pierwszym edytorze tekstu to inne pole editekstu. może dać rozwiązanie tego problemu w obliczu tego problemu z ostatnich trzech dni. –

9

Miałem dokładnie ten sam problem z projektem, nad którym pracowałem. Wszystkie rozwiązania, które znalazłem wspomniałem również przy użyciu textChangeListener, jednak ze względu na naturę listy oraz z EditText w każdym widoku rzędu, było to bardzo nieefektywne. Podjąłem osobne podejście przy użyciu EditText.setOnFocusChangeListener().

Dołączyłem to do każdego EditText w metodzie getView. Powód, dla którego działa tak dobrze, jest wywoływany, gdy użytkownik przełącza się na inny edittext lub zwoje, więc bieżący wiersz jest poza ekranem, co powoduje utratę fokusu przez EditText.

W onFocusChange (Widok v, logiczna hasFocus) wewnątrz słuchacza po prostu umieścić:

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

w moim przykładzie mam przechowywania wprowadzoną wartość do moich danych używany do zapełniania poglądy na temat każdego połączenia getView, ale powinno to nadal pokazywać, jak uzyskać dostęp do danych wprowadzonych przez Użytkownika. Po prostu upewnij się, że próbujesz zabrać te przechowywane dane i spróbuj wypełnić tekst editText w odpowiedniej pozycji.

Mam nadzieję, że to pomoże.

zamieszczaniu moje pełne adapter tutaj odniesienie

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

to nie rozwiązuje problemu w ogóle. Jeśli umieścisz tekst na Edytowanym tekście, a następnie przewiniesz, pierwszy tekst edycji nie straci ostrości, a dane wejściowe zostaną utracone. – kiduxa

+0

@kiduxa Użyj 'addTextChangedListener' zamiast' setOnClickListener' dla EditText i wstaw 'vendorList.get (position) .put (" preference ", et_preference.getText(). ToString(). Trim());' in ** afterTextChanged ** –

Powiązane problemy