Question

Existe-t-il un moyen d'afficher le " Chargement " l'écran avec animation dans BlackBerry?

Options:

  • contenu de l'animation PME
  • multithreading + jeu d'images + minuterie / compteur
  • api de jante standard
  • d'une autre manière

Tout ça?

Merci!

Était-ce utile?

La solution

Fermin, Anthony +1. Merci à tous, vous m'avez donné la partie de réponse.
Ma solution finale:

1.Créez ou générez ( un générateur de gif de chargement Ajax gratuit ) et ajoutez-le au projet.

2.Créez l'interface ResponseCallback (voir Coderholic - Blackberry WebBitmapField ) pour recevoir le résultat de l'exécution du thread :

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

3.Créez une classe pour gérer votre travail de thread en arrière-plan. Dans mon cas, c’était la requête 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 l'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.À la fin, créez un écran de démarrage pour appeler HttpConnector.HttpGetStream et afficher 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: Une fenêtre contextuelle de chargement de type Web 2.0 / Ajax dans une application BlackBerry native

Autres conseils

Le modèle de base pour ce genre de chose est:

Demandez à un thread exécutant une boucle qui met à jour une variable (telle que l’index d’image de l’image animée), puis invalide les appels sur un champ qui dessine l’image (puis met le lecteur en veille pendant un certain temps). L'invalidation mettra en attente une nouvelle peinture du champ.

Dans la méthode de dessin du champ, lisez la variable et tracez le cadre approprié de l'image.

Pseudo-code (pas tout à fait complet, mais pour vous donner une 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 aussi ici que j'ai utilisé un tableau de bitmaps, mais EncodedImage vous permet de traiter un gif animé comme un seul objet et inclut des méthodes pour obtenir des images spécifiques.

EDIT: Pour être complet: ajoutez ceci à un PopupScreen (comme dans la réponse de Fermin) ou créez votre propre boîte de dialogue en remplaçant directement Screen. Le thread séparé est nécessaire car l'API RIM n'est pas thread-safe: vous devez effectuer tout ce qui est lié à l'interface utilisateur sur le thread d'événement (ou tout en maintenant le verrou de l'événement, voir Threading de l'interface utilisateur BlackBerry - Notions de base

C’est un code simple pour charger l’écran ....

                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();

S'il ne s'agit que d'une animation, pouvez-vous afficher un gif animé dans une fenêtre et le fermer lorsque le chargement est terminé?

La méthode la plus simple consiste probablement à utiliser le champ standard GaugeField, en définissant le style GaugeField.PERCENT. Cela vous donnera une barre de progression. Ajoutez ceci à un écran Popup et il sera placé 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);
}

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

Je l'appelle normalement depuis le thread qui effectue le travail (dans votre cas, lorsque vous chargez une opération, la barre de progression est mise à jour chaque fois qu'une opération est terminée.

Je suggérerais de regarder cette implémentation simple. J'ai aimé ça mais je ne l'ai jamais utilisé. Peut vous être utile.

texte du lien

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top