2010-12-14 5 views
1

La vue de liste ne met pas à jour les données lorsque la méthode notifyDataChanged() est appelée.notifyDataSetChanged ne fonctionne pas dans android

Dans la méthode onCreate(), j'ai initialisé la listview sans données. Après cela, j'ai commencé à extraire la liste des vidéos en utilisant les nouvelles VideosCategoryFetchTask(). Execute();

dans le post méthode d'exécution, j'ai appelé

  @Override 
    protected void onPostExecute(Boolean success) { 
     if(success) { 
      listAdapter.notifyDataSetChanged(); 
     } else { 
      //show dialog 
     } 
    } 

mais rien ne s'affiche sur la liste. Si quelqu'un connaissait la solution s'il vous plaît aider ...

private class VideosDetailsFetchTask extends AsyncTask<String, Void, Boolean> { 
    @Override 
    public void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected Boolean doInBackground(String... params) { 
     Boolean success = false; 
     try { 
      if (params.length >= 0) { 
       videos = (Videos)videoAPI.videosForCategoryId(params[0],new VideosParser()); 
       success = true; 
      } 
     } catch (Exception e) { 
      // TODO: handle exception 
     } 
     return success; 
    } 

    @Override 
    protected void onPostExecute(Boolean success) { 

     if(success) { 
       progressBar.setVisibility(View.INVISIBLE); 
       onFinishVideoFetch(); 
     } else { 
      //show dialog 
     }  
    } 
} 

ici en utilisant deux classes Async sec, on est appelé à la onPostExecute() du premier ..

private void onFinishVideoFetch() { 
    if(videos != null) { 

     listAdapter.notifyDataSetChanged(); 
    } 
} 

Je ne suis pas une vidéo allant chercher par un .. ici une liste de vidéos est retourné ....

Après avoir obtenu la liste des vidéos je voulais actualiser la liste.

@Override 
protected void onProgressUpdate(Videos... values) { 

    videos = values[0]; 
//add published object to list which holds 
    listAdapter.notifyDataSetChanged(); 


} 

J'ai essayé, mais pas de chance s'il vous plaît aider ..

c'est la classe d'adaptateur utilisé

PHVideosListAdapter public class BaseAdapter {

private Videos videoTitles; 
private LayoutInflater inflater; 

public PHVideosListAdapter(Context context, Videos videoTitles) { 

    inflater = LayoutInflater.from(context); 
    this.videoTitles = videoTitles; 
} 

@Override 
public int getCount() { 
    // TODO Auto-generated method stub 
    if(videoTitles != null) { 
     return videoTitles.size(); 
    } 
    else { 
     return 0; 
    } 
} 

@Override 
public Object getItem(int position) { 
    // TODO Auto-generated method stub 
    return videoTitles.get(position); 
} 

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

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 
    VideoListViewHolder holder = null; 

    if (convertView == null) { 

      holder = new VideoListViewHolder(); 
      convertView = inflater.inflate(R.layout.videos_list, null); 
      holder.videoTitle = (TextView) convertView.findViewById(R.id.video_title); 
      holder.videoImage = (ImageView) convertView.findViewById(R.id.video_image); 
      holder.videoDuration = (TextView) convertView.findViewById(R.id.video_duration); 

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

    holder.videoImage.setImageResource(R.drawable.icon); 
    holder.videoDuration.setText("00:10"); 
    holder.videoTitle.setText(videoTitles.get(position).getVideoTitle()); 
    return convertView; 
} 


    private class VideoListViewHolder { 

    ImageView videoImage; 
    TextView videoTitle; 
    TextView videoDuration; 
} 

}

+0

Pourriez-vous coller toute votre classe 'VideosCategoryFetchTask'? – Cristian

+0

Juste pour vérifier: si vous parcourez votre code en mode débogage, êtes-vous sûr que 'notifyDataSetChanged()' est réellement appelé? Juste pour exclure qu'il y ait un bug ailleurs. – Nailuj

+0

Le code pour PHVideosListAdapter serait utile. –

Répondre

0

Vous besoin de remplacer onProgressUpdate() de la classe AsynTask

Heres un exemple de AsyncTask en supposant que votre liste est videos qui contient des objets de type Video et votre adaptateur étendu est VideosAdapter

private class VideosDetailsFetchTask extends AsyncTask<String, Video, Boolean> {  
    @Override  
    public void onPreExecute() {  
     super.onPreExecute();  
    }  

    @Override  
    protected Boolean doInBackground(String... params) {  
    //utilize string you are passing otherwise use Void as first generic param.   
    Boolean success = false;  
     try {  
      if (params.length >= 0) {  
       Videos videoFetched = (Videos)PrimeraHoraAPI.videosForCategoryId(params[0],new VideosParser());  
       success = true; 
       publishProgress(videoFetched); 
      }  
     } catch (Exception e) {  
      // TODO: handle exception  
     }  
     return success;  
    }  

    @Override  
    protected void onPostExecute(Boolean success) {  

     if(success) {  
       progressBar.setVisibility(View.INVISIBLE);  
       onFinishVideoFetch();  
     } else {  
      //show dialog  
     }   
    } 

    @Override 
    protected void onProgressUpdate(Video... values) { 
     videos.add(values[0]);//add published object to list which holds 
     ((VideosAdapter)getListAdapter()).notifyDataSetChanged(); 

    }  
}  
4

Lorsque vous créez votre PHVideosListAdapter, il tient une référence à la liste Videos que Je suppose est un membre de votre activité. Dans votre méthode doInBackground, l'appel à videoAPI.videosForCategoryId met à jour la référence Videos dans votre activité, mais l'adaptateur conserve toujours la référence d'origine qui a été transmise au constructeur pour PHVideosListAdapter. Vous devez recréer le PHVideosListAdapter dans onPostExecute ou ajouter une méthode set dans PHVideosListAdapter pour modifier la variable privée videoTitles.

J'ai rencontré le même problème en utilisant le ArrayAdapter fourni par Google. Vous pouvez uniquement définir le sous-jacente List dans le constructeur, vous devez donc recréer ArrayAdapter ou créer votre propre classe qui permet de modifier les données sous-jacentes pour que notifyDataSetChanged fonctionne.

+0

crée une méthode set qui met à jour la variable privée. C'est la meilleur façon –

0

Ce n'est pas très bon descript partout, mais ce que vous faites quand u appelez

listAdapter.notifyDataSetChanged();

u dire votre machine "Oke, votre code n'est pas réglo" et maintenant u arrêtez! Donc, fondamentalement, votre machine n'a aucune idée de ce que 2 font ensuite! Ma solution est:

créer un SetupData private void()

private void setupData() { 
     ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>(); 
     final List<Table_Follow> data = db.getAllData(); // from database 
     HashMap<String,String> item; 
     for(Table_Data td : data){ 
      item = new HashMap<String,String>(); 
      item.put("name1", td.getName_One()); 
      item.put("name2", td.getName_Two()); 
      item.put("date", td.getDate()); 
      list.add(item); 
     }; 

     my_data = new SimpleAdapter(this, list, R.layout.my_listview_row, new String[] { "name1","name2", "date" }, new int[] {R.id.lv_line_a, R.id.lv_line_b, R.id.lv_line_c}); 
     listview.setAdapter(my_data); 
    } 

J'ai une mise en page personnalisée avec 3 textviews (ligne a> titre, ligne b> sous-titre, ligne c> temps voir en bas de page pour xml). Donc basiquement je vais utiliser ce vide privé pour dire ce que ma machine 2 faire ensuite à l'aide SetupData() après avoir appelé> notifydatasetchanged() dans mon thread principal

my_data.notifyDataSetChanged(); 
setupData(); 

Une dernière chose! J'utilise l'ID andview listview pour ma listview dans mon fichier xml principal! Oh, et si vous avez du mal à utiliser votre 'onItemClickListener' (ne pas vous donner le bon id, juste le texte moi! J'ai fait face à ce problème et l'a résolu: p)

Mon fichier XML pour ma liste:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" > 

    <TextView 
     android:id="@+id/lv_line_c" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textColor="#FFFFFF" 
     android:textSize="15sp" /> 

    <LinearLayout 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" > 

     <TextView 
      android:id="@+id/lv_line_a" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:textColor="#FFFFFF" 
      android:textSize="24sp" 
      android:textStyle="bold" /> 

     <TextView 
      android:id="@+id/lv_line_b" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:textColor="#FFFFFF" 
      android:textSize="15sp" /> 
    </LinearLayout> 

</RelativeLayout>