2009-04-29 2 views
13

Есть ли способ показать экран «Загрузка» с анимацией в blackberry?Blackberry - Загрузка/Ожидание экрана с анимацией

Варианты:

  • РМЕ контента анимации
  • многопоточной + набор изображений + таймер/счетчик
  • стандартный обод апи
  • какой-то другой способ

Любой из этого?

Спасибо!

+1

Вы можете просмотреть пример, используя экран всплывающее здесь. http://supportforums.blackberry.com/t5/Java-Development/Sample-quot-Please-Wait-quot-screen-part-1/ta-p/493808 Я решил свою проблему, используя это. – BSKANIA

ответ

35

Fermin, Anthony +1. ты дал мне часть ответа
Мой окончательное решение:.

1.Create или генерировать (free Ajax loading gif generator) анимацию и добавить его к проекту

2..Создание интерфейса ResponseCallback (см Coderholic - Blackberry WebBitmapField), чтобы получить результат выполнения резьбы:

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

3.Create класс для обработки вашей фона нити работы. В моем случае это был запрос 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.In конца, создать экран 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); 
    } 
} 

UPDATE: другое решение naviina.eu: A Web2.0/Ajax-style loading popup in a native BlackBerry application

+0

Жаль, что я не смог бы это сделать дважды, ну, много раз. ПУТЬ. – Irwin

+0

Спасибо, что поделились этим. Я также мог бы показать текст рядом с изображением, добавив «graphics.drawText (текст, xText, yImage)»; в методе paint(). Чтобы вычислить координаты для изображения и текста, используйте «this.getFont(). GetAdvance (text)» и «this.getFont(). GetHeight();». – bob

+0

Можно ли добавлять изображения любых фреймов? Я добавляю изображение с 12 кадрами, но оно не окрашено должным образом. он появляется и исчезает .. не уверен, где проблема .. – ayachama

2

Самый простой способ - это, вероятно, использовать стандартный калибровочный элемент, установив стиль 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 (новое_значение); для обновления индикатора выполнения.

Я обычно у этого вызывается из какой нить делает работу (загрузки в вашем случае, каждый раз, когда операция будет завершена прогресс бар обновляется.

+0

Спасибо за ваш ответ, но мне не нужен индикатор выполнения, а анимационный диалог «wait». Можете ли вы предложить некоторую непрерывную технику самообновления? –

3

Если это просто анимация могли бы вы показать animated gif на всплывающее окно ? и закрыть его при загрузке операции завершена

+0

Спасибо Fermin, +1. –

4

Основной образец для такого рода вещи:

У нить работает цикл, который обновляет переменную (например, индекс кадра анимированного изображения), а затем вызывает недействительность на поле, которое рисует изображение (а затем спит для Период времени). Недействительный будет стоять в очереди на перерисовку поля.

В методе рисования поля прочитайте переменную и нарисуйте соответствующий кадр изображения.

Псевдо код (не полностью завершена, но, чтобы дать вам идею):

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

Отметим также, здесь я использовал массив Bitmaps, но EncodedImage позволяет рассматривать анимированный GIF как один объект, и включает в себя методы для получения определенных кадров.

EDIT: Для полноты: добавьте это в PopupScreen (как в ответе Фермина) или создайте свой собственный диалог, переопределив экран напрямую. Отдельный поток необходим, потому что RIM API не является потокобезопасным: вам нужно сделать все, что связано с пользовательским интерфейсом на потоке событий (или, удерживая блокировку событий, см. BlackBerry UI Threading - The Very Basics

2

Я предлагаю взглянуть на эту простую реализацию. Мне это нравилось, но я никогда не использовал его. Может быть полезно для вас.

link text

+0

да, это здорово! но см. мой ответ, это уже есть, в конце концов))) –

+0

ohh yeah my bad. Рад, что вы решили свою проблему. – Sameer

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(); 
Смежные вопросы