2009-04-29 9 views
13

"Loading"画面とアニメーションをブラックベリーで表示する方法はありますか?Blackberry - アニメーションの読み込み中/待機中画面

オプション:画像+タイマ/カウンタ

  • 標準リムAPI
  • の他の方法
  • これのどれを設定

    • PMEアニメーションコンテンツ
    • マルチスレッド+?

      ありがとうございます!

    +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。あなたのバックグラウンドスレッドジョブを処理するための

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

    3.Createクラス:スレッドの実行結果を受信する(Coderholic - Blackberry WebBitmapFieldを参照)ResponseCallbackインターフェイスを作成します。 HTTPConnectorのを呼び出すためのスタート画面を作成し、

    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:

    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待機画面(ResponseCallbackインターフェイスと全画面表示のハイブリッドとAnimatedGIFField):私の場合、それはhttpリクエストでした.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

    私はこれを2回upvoteできればいいと思っています。方法。 – Irwin

    +0

    これを共有していただきありがとうございます。私はまた、 "graphics.drawText(text、xText、yImage);"を追加することで画像の横にテキストを表示することもできました。 paint()メソッドでイメージとテキストの座標を計算するには、 "this.getFont()。getAdvance(text)"と "this.getFont()。getHeight();"を使用します。 – bob

    +0

    任意のフレームの画像を追加できますか?私は12フレームの画像を追加していますが、適切に塗られていません。表示され、消えます..どこに問題があるのか​​わかりません。 – ayachama

    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

    あなたの答えをありがとうが、私はプログレスバーは必要ありませんが、アニメーションの "待機"ダイアログ。いくつかの連続的な自己更新手法を提案できますか? –

    3

    それだけでアニメーションだ場合は、ポップアップでanimated gifを示すことができましたその後、

    は、(アニメーション画像のフレームインデックスなど)の変数を更新ループを実行中のスレッドを持っていると:?とロード操作が完了すると、この種のもののための基本的なパターンがある

    +0

    ありがとうFermin、+1。 –

    4

    それを閉じますイメージを描画するフィールドで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はあなたが1つのオブジェクトとしてアニメーションGIFを扱うことができます、と含み特定のフレームを取得するメソッド。

    編集:これをPopupScreen(Ferminの回答のように)に追加するか、Screenを直接オーバーライドして独自のダイアログを作成します。 RIM APIはスレッドセーフではないため、イベントスレッド(またはイベントロックを保持している間)のすべての操作を行う必要があります。

    2

    この簡単な実装を見てみることをお勧めします。私はこれが好きでしたが、決してそれを使用しませんあなたに役立つかもしれません。あなたは、少なくともBB OS 6.0を使用している場合

    link text

    +0

    これは素晴らしい!しかし、私の答えを参照してください、それはすでにそこに、最後に))) –

    +0

    オハイオ州私の悪い。あなたの問題を解決してうれしいです。 – 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(); 
    
    関連する問題