2009-04-29 103 views
13

有没有办法显示“加载”屏幕与动画在黑莓?黑莓 - 加载/等待屏幕与动画

选项:

  • PME动画内容
  • 多线程+图像集+定时器/计数器
  • 标准轮辋API
  • 一些其它方式

任何的这?

谢谢!

+1

你可以在这里使用弹出屏幕视图的例子。 http://supportforums.blackberry.com/t5/Java-Development/Sample-quot-Please-Wait-quot-screen-part-1/ta-p/493808我用这个解决了我的问题。 – BSKANIA 2012-04-27 10:47:33

回答

35

费尔明安东尼+1。你给我的答案的一部分
我的最终解决方案:

1,创建或生成(free Ajax loading gif generator)的动画,并将其添加到项目

2。创建ResponseCallback接口(见Coderholic - Blackberry WebBitmapField)接收线程执行结果:

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

3.创建一个类来处理你的后台线程的工作。在我的情况下,它是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.Create等待屏幕(全屏的混合动力和AnimatedGIFField与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年底,创建启动屏幕调用HttpConnector .HttpGetStream并显示等待屏幕:

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:另一种解决方案naviina.eu: A Web2.0/Ajax-style loading popup in a native BlackBerry application

+0

我希望我可以两次这样做,好吧,很多次。办法。 – Irwin 2011-01-08 15:24:12

+0

感谢分享。我还可以通过添加“graphics.drawText(text,xText,yImage);”在paint()方法中。要计算图像和文本的坐标,请使用“this.getFont()。getAdvance(text)”和“this.getFont()。getHeight();”。 – bob 2011-08-30 22:44:47

2

最简单的方法可能是使用标准GaugeField,设置样式GaugeField.PERCENT。这会给你一个进度条。将其添加到PopupScreen中,它将位于您的内容之上。就像..

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

然后有一个更新方法,它将使用_gaugeField.setValue(newValue);更新进度条。

我通常有这样从哪个线程正在做你的情况的处理(搬入叫,每次操作完成进度条进行更新。

+0

感谢您的回答,但我不需要进度条,而是一个动画“等待”对话框。你能提出一些持续的自更新技术吗? – 2009-04-29 08:16:49

3

如果它只是一个动画你能上的弹出显示的animated gif ?并关闭它加载操作完成时

+0

感谢Fermin,+1。 – 2009-04-29 11:25:21

4

的基本模式为这种事情是:

有一个线程中运行一个循环,更新的变量(如动画图像的帧索引),然后在绘制图像的Field上调用invalidate(然后睡觉一段时间)。无效将排队重新绘制该字段。

在字段的paint方法中,读取变量并绘制图像的相应框。

伪代码(没有完全完成,但给你的想法):

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

还要注意这里我使用的位图的数组,但EncodedImage让你能够将GIF动画作为一个对象,包括获取特定帧的方法。

编辑:为了完整:将此添加到PopupScreen(如在Fermin的答案中)或直接通过覆盖Screen创建自己的对话框。单独的线程是必需的,因为RIM API不是线程安全的:您需要在事件线程上执行与UI相关的所有操作(或者同时持有事件锁,请参阅BlackBerry UI Threading - The Very Basics

2

我建议看看这个简单的实现。我喜欢这个,但从来没有用过它。可能对你有帮助。

link text

4

这是加载画面简单的代码....

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