Android – EditTexts all'interno di ListView legati a Custom ArrayAdapter – tenere traccia delle modifiche

Ho un'attività Android in cui ho un ListView legato a un ArrayAdapter personalizzato. Ogni row del ListView ha due campi EditText (numbersci).

L'ArrayAdapter viene inizialmente popolato da un DB SQLite. Tuttavia l'utente può aggiungere una row alla fine del ListView o (premendo a lungo una row) eliminare qualsiasi row nel ListView. Quando premono il button 'Salva', le modifiche persistono.

  • Come raggruppare le notifiche di android come whatsapp?
  • Schede che vengono visualizzate sopra la barra d'azione quando si gonfia il layout personalizzato
  • Aggiunta di intestazioni di authentication a NetworkImageView in Volley
  • Rendering di Android Studio quando viene aggiunto ScrollView
  • Android Studio Imansible eseguire AVD
  • Android - Come intercettare l'intenzione di 'Installa applicazione'
  • Sto tenendo traccia delle modifiche apportte da un CustomTextWatcher per l'evento AfterTextChanged () a ciascun EditText nel metodo getView () di ArrayAdapter (passando in EditText e nell'object corrispondente nell'elenco degli elementi di ArrayAdapter) e quindi impostando la corrispondenza properties; di tale object al contenuto di EditText. Ciò è in modo che nel risparmio posso semplicemente eseguire l'iterazione attraverso l'elenco degli oggetti sottostante e apportre le modifiche DB appropriate, sapendo che l'elenco degli oggetti è aggiornato.

    Codice per la class dell'adattatore e il CustomTextWatcher:

    private class CustomAdapter extends ArrayAdapter<DataItem> { private ArrayList<DataItem> items; public CustomAdapter(Context context, int textViewResourceId, ArrayList<DataItem> items) { super(context, textViewResourceId, items); this.items = items; } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; DataItem wed = items.get(position); if (v == null) { LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.log_exercise_row, null); } if(wed != null) { EditText text1 = (EditText) v.findViewById(R.id.text1); EditText text2 = (EditText) v.findViewById(R.id.text2); text1.addTextChangedListener(new CustomTextWatcher(text1,wed)); text2.addTextChangedListener(new CustomTextWatcher(text2,wed)); int weight = wed.getWeight(); if(weight != -1) { text1.setText(weight+""); } int reps = wed.getReps(); if(reps != -1) { text2.setText(reps+""); } } return v; } private class CustomTextWatcher implements TextWatcher { private EditText EditText; private DataItem item; public CustomTextWatcher(EditText e, DataItem item) { this.EditText = e; this.item = item; } @Override public void afterTextChanged(Editable arg0) { String text = arg0.toString(); if(text != null && text.length() > 0) { int val; try { val =Integer.parseInt(text); } catch(NumberFormatException e) { val=-1; } if(EditText.getId()==R.id.weightEditText) { item.setWeight(val); } else if(EditText.getId()==R.id.repsEditText) { item.setRepetitions(val); } } } 

    Tutto ciò funziona bene, tranne quando gli elementi vengono aggiunti o eliminati quando succede duplicazione indesiderata di contenuti EditText.

    Per illustrare con un esempio:

    Inizia con 3 righe, il text di EditText è vuoto
    Nella row 2, immettere '5', '6'
    Fai clic su 'Altro' -> Aggiunge una row (vuota) alla fine. Ora 4 righe.
    Elimina l'ultima row-> 3 righe visualizzate, ma le 2 e 3 righe ora mostrano '5', '6' -> ???????

    Sembra che la posizione relativa degli oggetti EditText all'interno di ListView non sia stabile dopo la ribaltazione che sta causando il problema. Ad esempio, l'object EditText 'X' inizia nella posizione 3 e poi dopo un riblogo si trova nella posizione 1 – ma ha ancora un allegato CustomTextWatcher che fa riferimento all'object di dati nella posizione 3. L'altro problema è il fatto che addTextChangedListener () non influenzano i TextWatchers già collegati a EditText.

    Sono piuttosto nuovo per Android, quindi non so se esista un approccio migliore per risolvere il mio problema. Qualsiasi aiuto è apprezzato.

  • tenta di riaprire un object già chiuso: SQLiteDatabase
  • Problema di codifica con loadData di WebView
  • Come fare il dimensionamento e la scalatura del viewport per il supporto del browser cross?
  • Android Proguard - come mantenere i gestori onClick che fanno riferimento solo ai layout XML
  • Come funziona il telecommand Android con Google TV
  • Aggiornamenti periodici di posizione GPS di Android con AlarmManager all'interno di un servizio
  • One Solution collect form web for “Android – EditTexts all'interno di ListView legati a Custom ArrayAdapter – tenere traccia delle modifiche”

    Sembra che una class personalizzata ('ViewHolder') fosse quella di cui avevo bisogno per mantenere i riferimenti tra un object EditText e un object dati associato correttamente sincronizzati su ciascun "legame" dei dati. Inoltre, immettere le chiamate dell'ascoltatore di events quando l'object convertView era null nel metodo getView () significava che un solo listener è stato aggiunto per object EditText.

    Grazie a http://www.vogella.de/articles/AndroidListView/article.html#listsactivity per indicarmi nella giusta direzione.

     public class CustomAdapter extends ArrayAdapter<DataItem> { private ArrayList<DataItem> items; private Activity Context; public CustomAdapter(Activity context, int textViewResourceId, ArrayList<DataItem> items) { super(context, textViewResourceId, items); this.items = items; this.Context = context; } static class ViewHolder { protected EditText weight; protected EditText reps; } public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; DataItem wed = items.get(position); if (v == null) { LayoutInflater inflator = Context.getLayoutInflater(); v = inflator.inflate(R.layout.log_exercise_row, null); final ViewHolder viewHolder = new ViewHolder(); viewHolder.text1 = (EditText) v.findViewById(R.id.text1); viewHolder.text2 = (EditText) v.findViewById(R.id.text2); viewHolder.text1.addTextChangedListener(new CustomTextWatcher(viewHolder, viewHolder.text1)); viewHolder.text2.addTextChangedListener(new CustomTextWatcher(viewHolder, viewHolder.text2)); v.setTag(viewHolder); viewHolder.text1.setTag(wed); viewHolder.text2.setTag(wed); } else { ViewHolder holder = (ViewHolder) v.getTag(); holder.text1.setTag(wed); holder.text2.setTag(wed); } ViewHolder holder = (ViewHolder) v.getTag(); // set values if(wed.getWeight() != -1) { holder.text1.setText(wed.getWeight()+""); } else { holder.weight.setText(""); } if(wed.getRepetitions() != -1) { holder.text2.setText(wed.getRepetitions()+""); } else { holder.reps.setText(""); } return v; } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.