2010-10-28 9 views
13

J'ai une activité enfant qui contient un ListView. Cette activité est renseignée de manière asynchrone à partir d'un curseur SQLite. Les éléments de la liste contiennent un TextView, un RadioButton et un bouton normal. Le XML est indiqué ci-dessous:Comment savoir quand un ListView Android a été rempli

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout android:id="@+id/rlCategoryListItemLayout" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> 
<TextView android:id="@+id/tvCategoryListItemTitle" style="@style/uwLargeListItemLabelStyle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:singleLine="true" android:text="This is a test note title" /> 
<LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:gravity="center_vertical"> 
    <RadioButton android:id="@+id/rdoCategoryListItemSelect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="10dip" /> 
    <Button android:id="@+id/btnCategoryListItemDelete" android:background="@drawable/delete_red" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" /> 
</LinearLayout> 
</RelativeLayout> 

que je dois faire une certaine logique pour déterminer quel RadioButton est sélectionné par défaut, et je ne peux pas le faire jusqu'à ce que le ListView est déjà chargé. Le problème est qu'avec tous les événements que j'ai essayés jusqu'ici (onCreate, onPostCreate, onResume, onWindowFocusChanged), le nombre d'enfants ListView est zéro. J'ai également essayé d'utiliser la méthode getView dans la classe ArrayAdapter, mais cette méthode est appelée mutliple times et le nombre d'enfants ListView est potentiellement différent à chaque fois, ce qui conduit à des résultats inattendus. Apparemment, ces événements se déclenchent avant que le ListView ait fini de remplir complètement ses éléments enfants.

Y a-t-il un événement que je peux écouter, ou un autre moyen de déterminer quand le ListView a fini de remplir et que tous ses enfants sont accessibles pour être modifiés par programmation?

Merci!

Répondre

1

Une ListView ne crée pas réellement une vue pour chaque élément de la liste des données qu'elle affiche. Au lieu de cela, il recycle les vues afin d'être réactif et pas de mémoire de porc. Vous pourriez repenser ce dont vous avez vraiment besoin lorsque vous dites que le ListView doit être rempli.

Il peut être utile d'entrer dans un peu plus de détails sur votre application et de publier du code.

+1

Merci, Elevine. Je dois juste sélectionner l'un des boutons Radio par défaut. Lorsque j'essaie de faire cela, cependant, le ListView ne semble pas avoir encore d'éléments enfants. Donc, j'ai besoin de savoir quand le ListView est complètement peuplé afin que je puisse entrer et sélectionner un des éléments de la liste. – mahdaeng

+0

Mon point est ce que vous voulez dire par "ListView est entièrement rempli" n'est pas clair. Si vous voulez dire par là que tous les éléments de la liste sont visibles, alors cette condition pourrait ne jamais se produire étant donné la façon dont ListView rend les lignes. – elevine

+0

Oui - c'est exactement ce que je veux dire. :^( – mahdaeng

2

A la fin de votre travail asynchrone sur la base de données, vous pouvez utiliser Handler.post (Runnable) pour réexécuter le code sur le thread principal. C'est presque comme déclencher un rappel et vous pouvez garantir qu'il fonctionnera après que la liste est remplie. Vous pouvez même planifier l'exécution de Runnable à un certain moment si vous avez besoin de tout chronométrer très soigneusement.

Cela vous at-il été utile?

+0

Merci, mtmurdock Je vais essayer quelques trucs là-bas et voir ce que je peux trouver Je ferai un rapport sur mes résultats – mahdaeng

+0

Une autre option dans ce sens est d'utiliser AsyncTask: http: // developer .android.com/reference/android/os/AsyncTask.html – elevine

+0

En fait, j'ai eu un bug subtil ailleurs dans mon code Apparemment, je tirais sur mon Runnable exactement quand j'aurais dû être, mais l'autre bug était Il semblerait que certains contrôles n'étaient pas encore prêts.Merci, mtmurdock et elevine, pour votre volonté de m'aider avec ça – mahdaeng

0

Vous pouvez ajouter une variable de chaîne dans votre activité (par exemple public static String END_LOAD) et définissez la valeur dans votre méthode de getView (dans l'adaptateur), puis dans votre activité, après

ListView listView = (ListView) findViewById(R.id.recordListView); 
     listView.setAdapter(adapter); 

Vous pouvez ajouter un simple fil ce sera vérifier la variable END_LOAD:

Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     while (END_LOAD == null || END_LOAD .equals("")) { // your conditions 
     } 
     createReadRequest(); // your task to execute 
    } 
}; 

new Thread(runnable).start(); 

Ajouter une condition simple qui peut être intéressant pour vous, alors lorsque la condition sera fausse parce que la méthode getView est fait, vous pouvez maintenant faire votre processus spécifique.

+0

Qu'est-ce que END_LOAD? Et comment puis-je l'obtenir? –

6

Vous pouvez utiliser un gestionnaire pour accomplir cette tâche, comme ceci:

Dans votre activité ajouter le gestionnaire comme tout autre bien.

private Handler mListViewDidLoadHanlder = new Handler(new Handler.Callback() { 
    @Override 
    public boolean handleMessage(Message message) { 
     //Do whatever you need here the listview is loaded 
     return false; 
    } 
}); 

Et dans la méthode getView de votre adaptateur listview vous faites la comparaison pour voir si la position actuelle est le dernier, donc, il va finir (mettre juste avant le retour):

public View getView(int position, View convertView, ViewGroup parent) { 
     //Your views logic here 

     if (position == mObjects.size() - 1) { 
       mViewDidLoadHanlder.sendEmptyMessage(0); 
      } 

     return convertView; 
    } 
+4

La taille de vos données (mObjects) ne correspond pas au nombre réel affiché dans getView. – AndroidDev

+0

Il n'y a pas 'getView (' dans mon 'ListView.java'; où est exactement cette méthode? – msysmilu

+0

Vous avez raison, ceci est dans votre adaptateur http://developer.android.com/reference/android/widget/ArrayAdapter .html # getView (int, android.view.View, android.view.ViewGroup) –

Questions connexes