Domanda

Esiste un modo per mostrare " Caricamento " schermo con animazione in blackberry?

Opzioni:

  • Contenuti di animazione PME
  • multithreading + set di immagini + timer / contatore
  • API rim standard
  • in qualche altro modo

Qualcosa di tutto ciò?

Grazie!

È stato utile?

Soluzione

Fermin, Anthony +1. Grazie a tutti, mi avete dato la parte della risposta.
La mia soluzione finale:

1.Crea o genera ( generatore gratuito di gif di caricamento Ajax ) e aggiungilo al progetto.

2.Crea l'interfaccia ResponseCallback (vedi Coderholic - Blackberry WebBitmapField ) per ricevere il risultato dell'esecuzione del thread :

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

3.Creare una classe per gestire il processo di thread in background. Nel mio caso era una richiesta 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.Creare WaitScreen (un ibrido di FullScreen e AnimatedGIFField con interfaccia 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. Alla fine, crea la schermata Start per chiamare HttpConnector.HttpGetStream e per mostrare 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);
    }
}

AGGIORNAMENTO: un'altra soluzione naviina. eu: un popup di caricamento in stile Web 2.0 / Ajax in un'applicazione BlackBerry nativa

Altri suggerimenti

Lo schema di base per questo tipo di cose è:

Avere un thread che esegue un loop che aggiorna una variabile (come l'indice di frame dell'immagine animata) e quindi chiama invalidato su un campo che disegna l'immagine (e quindi rimane inattivo per un periodo di tempo). L'invalidato metterà in coda una riverniciatura del campo.

Nel metodo di pittura del campo, leggi la variabile e disegna la cornice appropriata dell'immagine.

Codice pseudo (non completamente completo, ma per darti l'idea):

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

Nota anche qui che ho usato un array di Bitmap, ma EncodedImage ti consente di trattare una GIF animata come un oggetto e include metodi per ottenere frame specifici.

MODIFICA: Per completezza: aggiungilo a una PopupScreen (come nella risposta di Fermin) o crea la tua finestra di dialogo sovrascrivendo direttamente Screen. Il thread separato è necessario perché l'API RIM non è thread-safe: è necessario eseguire tutte le operazioni relative all'interfaccia utente nel thread degli eventi (o mentre si tiene il blocco eventi, consultare BlackBerry UI Threading - The Very Basics

Questo è un codice semplice per il caricamento della schermata ....

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

Se è solo un'animazione potresti mostrare un GIF animate su un popup e chiuderlo al termine dell'operazione di caricamento?

Probabilmente il modo più semplice è usare lo standard GaugeField, impostando lo stile GaugeField.PERCENT. Questo ti darà una barra di avanzamento. Aggiungi questo a un PopupScreen e siederà in cima ai tuoi contenuti. Qualcosa come ..

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

Quindi utilizza un metodo di aggiornamento che utilizzerà _gaugeField.setValue (newValue); per aggiornare la barra di avanzamento.

Normalmente ricevo questa chiamata da qualunque thread stia facendo il lavoro (caricando nel tuo caso, ogni volta che un'operazione è completa la barra di avanzamento viene aggiornata.

Suggerirei di dare un'occhiata a questa semplice implementazione. Mi è piaciuto ma non l'ho mai usato. Potrebbe esserti utile.

testo del link

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top