2010-05-06 7 views
0

J'ai ici un bouton qui appelle un calcul très longue durée. Pour l'indiquer à l'utilisateur, je souhaite afficher un symbole de chargement. Le calcul est appelé dans cette méthode dans un thread supplémentaire (LoadingAnimationThread);Comportement Android Animation/GUI

@Override 
     public void onClick(View v) { 

      BookView bookView = (BookView) lexs.startBook(); 
      LoadingAnimationThread thread = null; 
      if (type == BOOK) { 
      thread = new LoadingAnimationThread(BOOK, book, bookView); 
      } else if (type == CHAPTER) { 
       thread = new LoadingAnimationThread(CHAPTER, chapter, bookView); 
      } else if (type == PARAGRAPH) { 
       thread = new LoadingAnimationThread(PARAGRAPH, paragraph, bookView); 
      } 

      LoadingAnimation.startAnimation(); 
      thread.run(); 
     } 

La méthode d'exécution du fil est le suivant:

@Override 
     public void run() { 

      if (type == BOOK) { 
       ((BookView) bookView).setBookToDisplay(book); 
      } else if (type == CHAPTER) { 
       ((BookView) bookView).setBookToDisplay(chapter.getBook()); 
       ((BookView) bookView).setExpanededChapter(chapter, true); 
      } else if (type == PARAGRAPH) { 
       ((BookView) bookView).setBookToDisplay(paragraph.getParentChapter().getBook()); 
       ((BookView) bookView).setExpanededChapter(paragraph.getParentChapter(), false); 
       ((BookView) bookView).setExpandedParagraph(paragraph); 
      } 
      LoadingAnimation.stopAnimation(); 
     } 

Cela appelle la méthode d'exécution du fil sont les méthodes qui ont besoin de beaucoup de calcul. Avec LoadingAnimation.startAnimation() et LoadingAnimation.stopAnimation() est de commencer à arrêter respectivement l'animation:

public static void startAnimation() { 

     lexs.runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       loadingImage.setImageResource(R.drawable.loading_background); 
       animation.start(); 
       Log.v("Animation", "Loading Animation started"); 
      } 
     }); 

    } 

    public static void stopAnimation() { 

     lexs.runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       loadingImage.setImageResource(R.drawable.loading0); 
       animation.stop(); 
       Log.v("Animation", "Loading Animation stopped"); 
      } 
     }); 

    } 

Je vois les lignes Connexion Logcat, mais l'animation est pas visible sur l'interface graphique. Pourquoi pas??? Je sais que l'animation fonctionne correctement, car dans d'autres endroits, cela fonctionne correctement. Parfois, Android ne met pas à jour l'interface utilisateur immédiatement, c'est pourquoi j'ai utilisé runOnUIThread(). Mais la doc pour cette méthode dit:

Si le thread courant est le fil conducteur interface utilisateur , l'action est exécutée immédiatement.

Donc je pense que le fil actuel n'est pas le fil de l'interface utilisateur, mais comment puis-je trouver le fil de l'interface utilisateur? Ou comment puis-je forcer le Runnable à fonctionner immédiatement?

+0

Vous pouvez essayer d'utiliser un ProgressDialog, au lieu d'exécuter le calcul sur un thread différent, vous exécutez le ProgressDialog sur un thread différent et le calcul reste dans le fil conducteur . Je l'ai fait pour télécharger des fichiers et d'autres choses. –

+0

n'est pas la boîte de dialogue de progression pour afficher un élément d'interface utilisateur? Vous faites le calcul dans la boîte de dialogue de progression? –

+0

ok j'ai essayé votre méthode, maintenant l'animation de chargement est affichée au début comme une image statique. alors le calcul commence et l'animation fronce. –

Répondre

1

Vous ne devez appeler que runOnUiThread à partir d'un thread d'arrière-plan. Je pense que vous avez la logique en arrière. Vous devez le configurer de sorte que startAnimation et stopAnimation ne lancent aucun appel à runOnUiThread, utilisez simplement le code tel quel. Ensuite, startAnimation doit être appelé à partir du thread d'interface utilisateur principal et stopAnimation peut être appelé par le thread d'arrière-plan avec runOnUiThread.

Voici quelques exemples de code:

public void onClick(View v) { 
    // this is the main thread 
    // ...... 
    LoadingAnimation.startAnimation(); // Don't need to call this with runOnUiThread since we're on teh main thread 
    thread.run(); 
} 

@Override 
public void run() { 

    runOnUiThread(new Runnable() { 
     // Need to put this in runOnUiThread since it's changing the UI from the background 
     if (type == BOOK) { 
      ((BookView) bookView).setBookToDisplay(book); 
     } else if (type == CHAPTER) { 
      ((BookView) bookView).setBookToDisplay(chapter.getBook()); 
      ((BookView) bookView).setExpanededChapter(chapter, true); 
     } else if (type == PARAGRAPH) { 
      ((BookView) bookView).setBookToDisplay(paragraph.getParentChapter().getBook()); 
      ((BookView) bookView).setExpanededChapter(paragraph.getParentChapter(), false); 
      ((BookView) bookView).setExpandedParagraph(paragraph); 
     } 
     LoadingAnimation.stopAnimation(); 
    }); 
} 

public static void startAnimation() { 
    loadingImage.setImageResource(R.drawable.loading_background); 
    animation.start(); 
    Log.v("Animation", "Loading Animation started"); 
} 

public static void stopAnimation() { 
    loadingImage.setImageResource(R.drawable.loading0); 
    animation.stop(); 
    Log.v("Animation", "Loading Animation stopped"); 
} 
+0

merci pour votre indice. J'ai mis en place votre approche et maintenant l'animation est affichée, mais l'animation fronce pendant le processus d'arrière-plan jusqu'à ce que stopAnimation soit appelé – RoflcoptrException

+0

Je vois, je pensais du point de vue du ProgressBar qui fonctionne en arrière-plan. Il semblerait que vous deviez démarrer l'animation en arrière-plan où vous appelez thread.run(). –

Questions connexes