Blackberry - アニメーション付きの読み込み/待機画面
-
03-07-2019 - |
質問
「読み込み中」画面を表示する方法はありますか アニメーション付き ブラックベリーで?
オプション:
- PME アニメーション コンテンツ
- マルチスレッド + 一連のイメージ + タイマー/カウンター
- 標準リム API
- 他の方法で
これのどれか?
ありがとう!
解決
ファーミン、アンソニー+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.WaitScreenの作成(FullScreenと 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。最後に、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:ネイティブBlackBerryアプリケーションのWeb2.0 / Ajaxスタイルの読み込みポップアップ
他のヒント
この種の基本的なパターンは次のとおりです。
変数(アニメーション画像のフレームインデックスなど)を更新するループを実行してから、画像を描画する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を1つのオブジェクトとして扱うことができ、特定のフレームを取得するメソッドが含まれています。
編集:完全を期すため:これをPopupScreenに追加するか(Ferminの答えのように)、Screenを直接オーバーライドして独自のダイアログを作成します。 RIM APIはスレッドセーフではないため、別のスレッドが必要です。イベントスレッドに関連するUIをすべて実行する必要があります(または、イベントロックを保持しながら、 BlackBerry UIスレッド-非常に基本的な
これは、画面をロードするための単純なコードです...
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();
単なるアニメーションの場合、アニメーションgif がポップアップに表示され、読み込み操作が完了したら閉じますか?
最も簡単な方法は、標準の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);を使用する更新メソッドがあります。進行状況バーを更新します。
通常、作業を実行しているスレッドから呼び出します(あなたの場合は読み込み、操作が完了するたびに進行状況バーが更新されます。
この単純な実装をご覧になることをお勧めします。私はこれが好きでしたが、使ったことはありません。役に立つかもしれません。
少なくとも BB OS 6.0 を使用している場合は、ActivityIndicator が適切なオプションです。
http://www.brighthub.com/mobile/blackberry-platform/articles/94258.aspx
http://docs.blackberry.com/en/developers/deliverables/17966/Screen_APIs_1245069_11.jsp