2009-04-29 21 views
13

Existe-t-il un moyen d'afficher l'écran "Chargement" avec animation dans blackberry?Blackberry - Écran de chargement/attente avec animation

Options:

  • PME contenu d'animation
  • multithreading + ensemble d'images + temporisateur/compteur
  • jante standard api
  • d'une autre manière

tout cela?

Merci!

+1

Vous pouvez voir l'exemple en utilisant l'écran pop-up ici. http://supportforums.blackberry.com/t5/Java-Development/Sample-quot-Please-Wait-quot-screen-part-1/ta-p/493808 J'ai résolu mon problème en utilisant ceci. – BSKANIA

Répondre

35

Fermin, Anthony +1 Merci à tous, vous me avez donné la part de réponse
Ma solution finale.

1.Créez ou générer (free Ajax loading gif generator) animation et de l'ajouter au projet

2..Créer une interface ResponseCallback (voir Coderholic - Blackberry WebBitmapField) recevoir résultat d'exécution de fil:

public interface ResponseCallback { 
    public void callback(String data); 
} 

3.Créez une classe pour gérer votre travail de fil d'arrière-plan. Dans mon cas, il a été demande http:

public class HttpConnector 
{ 
    static public void HttpGetStream(final String fileToGet, 
    final ResponseCallback msgs) { 
    Thread t = new Thread(new Runnable() { 
     public void run() { 
     HttpConnection hc = null; 
    DataInputStream din = null; 
    try { 
     hc = (HttpConnection) Connector.open("http://" + fileToGet); 
     hc.setRequestMethod(HttpsConnection.GET); 
     din = hc.openDataInputStream(); 
     ByteVector bv = new ByteVector(); 
     int i = din.read(); 
     while (-1 != i) { 
     bv.addElement((byte) i); 
     i = din.read(); 
     } 
     final String response = new String(bv.toArray(), "UTF-8"); 
     UiApplication.getUiApplication().invokeLater(
     new Runnable() { 
      public void run() { 
     msgs.callback(response); 
       } 
      }); 
    } 
     catch (final Exception e) { 
      UiApplication.getUiApplication().invokeLater(
      new Runnable() { 
       public void run() { 
       msgs.callback("Exception (" + e.getClass() + "): " 
        + e.getMessage()); 
       } 
      }); 
     } 
     finally { 
      try { 
      din.close(); 
      din = null; 
      hc.close(); 
      hc = null; 
      } 
      catch (Exception e) { 
      } 
     } 
     } 
    }); 
    t.start(); 
    } 
} 

4.Créez WaitScreen (un hybride de FullScreen et AnimatedGIFField avec interface ResponseCallback):

public class WaitScreen extends FullScreen implements ResponseCallback 
{ 
    StartScreen startScreen; 
    private GIFEncodedImage _image; 
    private int _currentFrame; 
    private int _width, _height, _xPos, _yPos; 
    private AnimatorThread _animatorThread; 
    public WaitScreen(StartScreen startScreen) { 
     super(new VerticalFieldManager(), Field.NON_FOCUSABLE); 
     setBackground(
      BackgroundFactory.createSolidTransparentBackground(
       Color.WHITE, 100)); 
     this.startScreen = startScreen; 
     EncodedImage encImg = 
      GIFEncodedImage.getEncodedImageResource("ajax-loader.gif"); 
     GIFEncodedImage img = (GIFEncodedImage) encImg; 

     // Store the image and it's dimensions. 
     _image = img; 
     _width = img.getWidth(); 
     _height = img.getHeight(); 
     _xPos = (Display.getWidth() - _width) >> 1; 
     _yPos = (Display.getHeight() - _height) >> 1; 
     // Start the animation thread. 
     _animatorThread = new AnimatorThread(this); 
     _animatorThread.start(); 
     UiApplication.getUiApplication().pushScreen(this); 
    } 

    protected void paint(Graphics graphics) { 
     super.paint(graphics); 
      // Draw the animation frame. 
      graphics 
       .drawImage(_xPos, _yPos, _image 
       .getFrameWidth(_currentFrame), _image 
        .getFrameHeight(_currentFrame), _image, 
       _currentFrame, 0, 0); 
    } 

    protected void onUndisplay() { 
     _animatorThread.stop(); 
    } 

    private class AnimatorThread extends Thread { 
     private WaitScreen _theField; 
     private boolean _keepGoing = true; 
     private int _totalFrames, _loopCount, _totalLoops; 
     public AnimatorThread(WaitScreen _theScreen) { 
      _theField = _theScreen; 
      _totalFrames = _image.getFrameCount(); 
      _totalLoops = _image.getIterations(); 

     } 

     public synchronized void stop() { 
      _keepGoing = false; 
     } 

     public void run() { 
      while (_keepGoing) { 
       // Invalidate the field so that it is redrawn. 
       UiApplication.getUiApplication().invokeAndWait(
        new Runnable() { 
        public void run() { 
         _theField.invalidate(); 
        } 
       }); 
       try { 
        // Sleep for the current frame delay before 
        // the next frame is drawn. 
        sleep(_image.getFrameDelay(_currentFrame) * 10); 
       } catch (InterruptedException iex) { 
       } // Couldn't sleep. 
       // Increment the frame. 
       ++_currentFrame; 
       if (_currentFrame == _totalFrames) { 
        // Reset back to frame 0 
        // if we have reached the end. 
        _currentFrame = 0; 
        ++_loopCount; 
        // Check if the animation should continue. 
        if (_loopCount == _totalLoops) { 
        _keepGoing = false; 
        } 
       } 
      } 
     } 

    } 

    public void callback(String data) { 
     startScreen.updateScreen(data); 
     UiApplication.getUiApplication().popScreen(this); 
    } 
} 

5.In la fin, créez écran de démarrage pour appeler HttpConnector .HttpGetStream et montrer WaitScreen:

public class StartScreen extends MainScreen 
{ 
    public RichTextField text; 
    WaitScreen msgs; 
    public StartScreen() {  
     text = new RichTextField(); 
     this.add(text); 
    } 

    protected void makeMenu(Menu menu, int instance) { 
     menu.add(runWait); 
     super.makeMenu(menu, instance); 
    } 

    MenuItem runWait = new MenuItem("wait", 1, 1) { 
     public void run() { 
      UiApplication.getUiApplication().invokeLater(
       new Runnable() { 
        public void run() { 
         getFile(); 
        } 
      });    
     } 
    }; 

    public void getFile() { 
     msgs = new WaitScreen(this); 
     HttpConnector.HttpGetStream(
      "stackoverflow.com/faq", msgs);     
    } 

    //you should implement this method to use callback data on the screen. 
    public void updateScreen(String data) 
    { 
     text.setText(data); 
    } 
} 

MISE à JOUR: une autre solution naviina.eu: A Web2.0/Ajax-style loading popup in a native BlackBerry application

+0

J'aurais aimé pouvoir faire deux fois la même chose, bon, beaucoup de fois. FAÇON. – Irwin

+0

Merci pour le partage. Je pourrais également montrer le texte à côté de l'image en ajoutant "graphics.drawText (text, xText, yImage);" dans la méthode paint(). Pour calculer les coordonnées de l'image et du texte, utilisez "this.getFont(). GetAdvance (texte)" et "this.getFont(). GetHeight();". – bob

+0

puis-je ajouter des images de cadres? J'ajoute une image avec 12 images, mais elle n'est pas peinte correctement. il apparaît et disparaît .. pas sûr où le problème est .. – ayachama

2

Le moyen le plus simple est probablement d'utiliser le GaugeField standard, en définissant le style GaugeField.PERCENT. Cela vous donnera une barre de progression. Ajouter ceci à un PopupScreen et il s'assoira au-dessus de votre contenu. Quelque chose comme ..

private GaugeField _gaugeField; 
private PopupScreen _popup; 

public ProgressBar() {  
    DialogFieldManager manager = new DialogFieldManager(); 
    _popup = new PopupScreen(manager); 
    _gaugeField = new GaugeField(null, 0, 100, 0, GaugeField.PERCENT);  
    manager.addCustomField(_gaugeField); 
} 

ont ensuite une méthode de mise à jour qui utilisera _gaugeField.setValue (newValue); pour mettre à jour la barre de progression.

Je normalement cette appelé de quel fil fait le travail (chargement dans votre cas, à chaque fois qu'une opération est terminée, la barre de progression est mis à jour.

+0

Merci pour votre réponse, mais je n'ai pas besoin d'une barre de progression, mais une boîte de dialogue "wait" d'animation. Pouvez-vous suggérer une technique d'auto-mise à jour continue? –

3

Si c'est juste une animation pourrait vous montrer un animated gif sur un popup ? et fermez-le lorsque l'opération de chargement est terminée

+0

Merci Fermin, +1. –

4

le modèle de base pour ce genre de chose est la suivante:

Avoir un fil conducteur une boucle qui met à jour une variable (comme l'indice d'image de l'image animée), puis appelle invalidate sur un champ qui dessine l'image (puis dort pour une période de temps). L'invalide mettra en attente une repeinte du champ.

Dans la méthode de peinture du champ, lisez la variable et dessinez l'image appropriée de l'image.

Code Pseudo (pas tout à fait complet, mais pour vous donner l'idée):

public class AnimatedImageField extends Field implements Runnable { 

    private int currentFrame; 
    private Bitmap[] animationFrames; 

    public void run() { 
    while(true) { 
     currentFrame = (currentFrame + 1) % animationFrames.length; 
     invalidate(); 
     Thread.sleep(100); 
     } 
    } 

    protected void paint(Graphics g) { 
     g.drawBitmap(0, 0, imageWidth, imageHeight, animationFrames[currentFrame], 0, 0); 
    } 
    } 

Notez également ici je un tableau de bitmaps, mais EncodedImage vous permet de traiter un fichier GIF animé comme un seul objet, et Includes méthodes pour obtenir des images spécifiques.

EDIT: Par souci d'exhaustivité: Ajoutez ceci à un PopupScreen (comme dans la réponse de Fermin) ou créez votre propre dialogue en remplaçant Screen directement. Le thread séparé est nécessaire car l'API RIM n'est pas thread-safe: vous devez faire tout ce qui est lié à l'événement (ou tout en maintenant le verrou d'événement, voir BlackBerry UI Threading - The Very Basics

2

Je suggère de jeter un oeil à cette implémentation simple. J'ai aimé ça mais je ne l'ai jamais utilisé. Peut être utile pour vous.

link text

+0

ouais c'est génial! mais voir ma réponse, c'est déjà là, à la fin))) –

+0

ohh ouais ma mauvaise. Content que tu aies résolu ton problème. – Sameer

4

Ceci est un code simple pour l'écran de chargement ....

   HorizontalFieldManager popHF = new HorizontalFieldManager(); 
       popHF.add(new CustomLabelField("Pls wait...")); 
       final PopupScreen waitScreen = new PopupScreen(popHF); 
       new Thread() 
       { 
        public void run() 
        { 

         synchronized (UiApplication.getEventLock()) 
         { 
          UiApplication.getUiApplication().pushScreen(waitScreen); 
         } 
         //Here Some Network Call 

         synchronized (UiApplication.getEventLock()) 
         { 
          UiApplication.getUiApplication().popScreen(waitScreen); 
         } 
        } 
       }.start();