黑莓 - 带动画的加载/等待屏幕

发布于 2024-07-19 08:00:25 字数 179 浏览 5 评论 0原文

有没有办法在黑莓手机中显示“加载”屏幕带有动画

选项:

  • PME 动画内容
  • 多线程 + 图像集 + 定时器/计数器
  • 标准 rim api
  • 其他方式

这是其中之一吗?

谢谢!

Is there a way to show "Loading" screen with animation in blackberry?

Options:

  • PME animation content
  • multithreading + set of images + timer/counter
  • standard rim api
  • some other way

Any of this?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

放我走吧 2024-07-26 08:00:25

费明,安东尼+1。 谢谢大家,你们给了我部分答案。
我的最终解决方案:

1.创建或生成(免费 Ajax 加载 gif 生成器)动画并将其添加到项目中。

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 WaitScreen (全屏和 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.最后,创建 Start 屏幕来调用 HttpConnector.HttpGetStream 并显示 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);
    }
}

更新:另一个解决方案naviina.eu:A本机 BlackBerry 应用程序中的 Web2.0/Ajax 样式加载弹出窗口

Fermin, Anthony +1. Thanks to all, you gave me the part of answer.
My final solution:

1.Create or generate (free Ajax loading gif generator) animation and add it to project.

2.Create ResponseCallback interface (see Coderholic - Blackberry WebBitmapField) to receive thread execution result:

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

3.Create a class to handle your background thread job. In my case it was http request:

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 WaitScreen (a hybrid of FullScreen and AnimatedGIFField with ResponseCallback interface):

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 the end, create Start screen to call HttpConnector.HttpGetStream and to show 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: another solution naviina.eu: A Web2.0/Ajax-style loading popup in a native BlackBerry application

那片花海 2024-07-26 08:00:25

这种事情的基本模式是:

让一​​个线程运行一个循环来更新变量(例如动画图像的帧索引),然后在绘制图像的 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 线程 - 基础知识

The basic pattern for this kind of thing is:

Have a thread running a loop that updates a variable (such as the frame index of the animated image) and then calls invalidate on a Field which draws the image (and then sleeps for a period of time). The invalidate will queue a repaint of the field.

In the field's paint method, read the variable and draw the appropriate frame of the image.

Pseudo code (not totally complete, but to give you the 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);
    }
  }

Note also here I used an array of Bitmaps, but EncodedImage lets you treat an animated gif as one object, and includes methods to get specific frames.

EDIT: For completeness: Add this to a PopupScreen (as in Fermin's answer) or create your own dialog by overriding Screen directly. The separate thread is necessary because the RIM API is not thread-safe: you need to do everything UI related on the event thread (or while holding the event lock, see BlackBerry UI Threading - The Very Basics

云醉月微眠 2024-07-26 08:00:25

这是加载屏幕的简单代码......

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

This is simple code for loading screen ....

                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();
茶底世界 2024-07-26 08:00:25

如果这只是一个动画,您可以显示 动画 gif 在弹出窗口上并在加载操作完成时关闭它?

If it's just an animation could you show an animated gif on a popup and close it when loading operation is complete?

芯好空 2024-07-26 08:00:25

最简单的方法可能是使用标准 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); 更新进度条。

我通常会从正在执行工作的线程调用此函数(在您的情况下加载,每次操作完成时进度条都会更新。

Easiest way is probably to use the standard GaugeField, setting style GaugeField.PERCENT. This will give you a progress bar. Add this to a PopupScreen and it will sit on top of your content. Something like..

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

Then have an update method which will use _gaugeField.setValue(newValue); to update the progress bar.

I normally have this called from whichever thread is doing the work (loading in your case, everytime an operation is complete the progress bar is updated.

天荒地未老 2024-07-26 08:00:25

我建议看一下这个简单的实现。 我喜欢这个,但从未使用过。 可能对你有帮助。

链接文本

I would suggest to take a look at this simple implementation. I liked this but never used it. May be helpful to you.

link text

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文