2013-05-02 3 views
6

Ho molti problemi ad aggiornare una visualizzazione elenco con un adattatore personalizzato. Ho cercato online nell'ultima ora e non riesco a trovare alcuna soluzione che renda la mia lista aggiornata.L'adattatore Android ListView non si aggiorna

Ho provato notifyDataSetChanged e anche listView.invalidate, ma nulla sembra funzionare. Qualsiasi aiuto sarebbe molto apprezzato. Posso vedere i dati in fase di aggiornamento utilizzando logcat, ma non viene aggiornato sullo schermo e non ho idea del perché.

Di seguito è riportato il codice.

ArrayList<Student> students = new ArrayList<Student>(); 

listview = (ListView) findViewById(R.id.listView); 
adapter = new StudentAdapter(this, R.layout.listitemlayout, students); 
listview.setAdapter(adapter); 

adattatore personalizzato

public class StudentAdapter extends ArrayAdapter<Student>{ 

    Context context; 
    int layoutResourceId;  
    ArrayList<Student> data = null; 

    public StudentAdapter(Context context, int layoutResourceId, ArrayList<Student> data) { 
     super(context, layoutResourceId, data); 
     this.layoutResourceId = layoutResourceId; 
     this.context = context; 
     this.data = data; 
    } 

    public void updateStudentsList(ArrayList<Student> newlist){ 
     data.clear(); 
     data = newlist; 
     this.notifyDataSetChanged(); 
    } 

    public void updateStudentTime(){ 
     for (Student s : data) { 
      s.updateElapsedTime();   
     } 
     this.notifyDataSetChanged(); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View row = convertView; 
     if(row == null){ 
      LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      Student student = data.get(position); 

      TextView title = (TextView)row.findViewById(R.id.txtTitle); 
      title.setText(student.getFirstname() + " " + student.getLastname()); 

      TextView subTitle = (TextView)row.findViewById(R.id.txtSubTitle); 
      subTitle.setText(student.getStudentID());  

      TextView duration = (TextView)row.findViewById(R.id.textDuration); 
      duration.setText(student.getElapsedTime()); 
     } 
     return row; 
    } 
} 

ho aggiornare i dati utilizzando un filo ogni tanto.

Runnable runnable = new Runnable() { 
      public void run() { 
       runOnUiThread(new Runnable() { 
        public void run() { 
         // Updates how long the student is in the centre. 
         adapter.updateStudentTime(); 
         adapter.notifyDataSetChanged(); 
         listview.invalidate(); 
         Log.i("Debug", "Running on UI Thread"); 
        } 
       }); 
       handler.postDelayed(this, 1000); 
      } 
     }; 
     handler.postDelayed(runnable, 1000); 
+0

aggiornamento ui ui sul filo. call adapter.updateStudentTime(); usa il runonuithread – Raghunandan

risposta

5

ListView ricicla la vista, quindi è necessario impostare i dati in getView. e i f(row == null){ significa che i dati non verranno aggiornati, utilizzare solo i vecchi dati.

si dovrebbe fare in questo modo:

Class ViewHolder { 
    TextView title; 
    TextView subTitle; 
    TextView duration; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    ViewHolder holder = null; 
    if(row == null){ 
     LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
     row = inflater.inflate(layoutResourceId, parent, false); 

     Student student = data.get(position); 
     holder = new ViewHolder(); 
     holder.title = (TextView)row.findViewById(R.id.txtTitle); 
     holder.subTitle = (TextView)row.findViewById(R.id.txtSubTitle); 
     holder.duration = (TextView)row.findViewById(R.id.textDuration); 
     row.setTag(holder); 
    } else { 
     holder = row.getTag(); 
    } 
    holder.title.setText(student.getFirstname() + " " + student.getLastname()); 
    holder.subTitle.setText(student.getStudentID()); 
    holder.duration.setText(student.getElapsedTime());  
    return row; 
} 
+0

Funziona, grazie! – SikhWarrior

0

Pensate il codice qui sotto a prevenire si aggiorna l'elenco.

if(row == null){  
... 
} 

Il codice ha detto che quando l'elenco si aggiorna. Verificherà che la riga è nullo (significa che la riga visualizzata in Screen è stata creata o meno). Quando aggiorni l'elenco, la riga già creata. Quindi NON è NULL, i nuovi dati non verranno impostati!

si dovrebbe cambiare qualcosa di simile:

public View getView(int position, View convertView, ViewGroup parent) { 

    View row = convertView; 

    if(row == null){ 
     LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
     row = inflater.inflate(layoutResourceId, parent, false); 

    } 

    Student student = data.get(position); 
    ... 

}