2009-04-29 9 views
13

¿Hay una manera de mostrar "Carga" de pantalla con la animación en mora?Blackberry - Carga/Espera pantalla con animación

Opciones:

  • PME contenidos de animación
  • multihilo + conjunto de imágenes + temporizador/contador
  • llanta estándar API
  • alguna otra manera

algo de esto?

Gracias!

+1

Usted puede ver el ejemplo utilizando la pantalla emergente aquí. http://supportforums.blackberry.com/t5/Java-Development/Sample-quot-Please-Wait-quot-screen-part-1/ta-p/493808 Resolví mi problema al usar esto. – BSKANIA

Respuesta

35

Fermin, Anthony +1. Gracias a todos, que me dio la parte de la respuesta
Mi solución final:. (free Ajax loading gif generator) animación

1.Create o generar y añadirlo a proyectar

2..Crear interfaz ResponseCallback (ver Coderholic - Blackberry WebBitmapField) para recibir resultado de la ejecución del hilo:

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

3.Create una clase para manejar su trabajo subproceso en segundo plano. En mi caso fue petición 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.Cree WaitScreen (un híbrido de pantalla completa y AnimatedGIFField con interfaz 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 Al final, crear la pantalla de inicio para llamar HttpConnector .HttpGetStream y para mostrar 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); 
    } 
} 

UPDATE: otra solución naviina.eu: A Web2.0/Ajax-style loading popup in a native BlackBerry application

+0

Ojalá pudiera votar esto dos veces, bueno, muchas veces. CAMINO. – Irwin

+0

Gracias por compartir esto. También podría mostrar texto junto a la imagen agregando "graphics.drawText (text, xText, yImage);" en el método paint(). Para calcular las coordenadas de la imagen y el texto, utiliza "this.getFont(). GetAdvance (texto)" y "this.getFont(). GetHeight();". – bob

+0

¿Puedo agregar imágenes de cualquier marco? Estoy agregando una imagen con 12 fotogramas, pero no está pintada correctamente. Aparece y desaparece. No estoy seguro de dónde está el problema. – ayachama

2

La manera más fácil es probablemente usar el estándar GaugeField, el establecimiento de GaugeField.PERCENT estilo. Esto le dará una barra de progreso. Agregue esto a una ventana emergente y se ubicará en la parte superior de su contenido. Algo así como ..

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

entonces un método de actualización que utilizará _gaugeField.setValue (nuevoValor); para actualizar la barra de progreso.

que normalmente tienen esta llamada desde cualquier hilo está haciendo el trabajo (carga en su caso, cada vez que una operación se ha completado la barra de progreso se actualiza.

+0

Gracias por su respuesta, pero no necesito una barra de progreso, sino un cuadro de diálogo de "espera" de animación. ¿Puedes sugerir alguna técnica de auto actualización continua? –

3

Si es sólo una animación podría mostrar una animated gif en una ventana emergente ? y cerrarla cuando la operación de carga se completa

+0

Gracias Fermin, +1. –

4

el patrón básico para este tipo de cosas es:

Tener un hilo conductor a un circuito que actualiza una variable (como el índice de la trama de la imagen animada) y luego llamadas invalidadas en un campo que dibuja la imagen (y luego duerme para un período de tiempo). El invalidato pondrá en cola un repintado del campo.

En el método de pintura del campo, leer la variable y dibujar el marco apropiado de la imagen.

Pseudo código (no totalmente completa, pero para darle la 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); 
    } 
    } 

Tenga en cuenta también que aquí he utilizado una serie de mapas de bits, pero EncodedImage le permite tratar un gif animado como un objeto, y incluye métodos para obtener marcos específicos.

EDIT: Para completar: Añadir a un PopupScreen (como en la respuesta de Fermín) o crear su propio diálogo anulando la pantalla directamente. El hilo separado es necesario porque la API de RIM no es segura para subprocesos: necesita hacer todo lo relacionado con la interfaz de usuario en la cadena de eventos (o al mantener el bloqueo de eventos, consulte BlackBerry UI Threading - The Very Basics

2

Sugiero que eche un vistazo a esta sencilla implementación. Me gustó esto pero nunca lo usé. Puede ser útil para usted

link text

+0

¡Sí, es genial! pero mira mi respuesta, ya está allí, al final))) –

+0

ohh sí mi mal. Me alegra que hayas resuelto tu problema. – Sameer

4

Este es un código simple para pantalla de carga ....

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