回答
費爾明安東尼+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
最簡單的方法可能是使用標準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);更新進度條。
我通常有這樣從哪個線程正在做你的情況的處理(搬入叫,每次操作完成進度條進行更新。
感謝您的回答,但我不需要進度條,而是一個動畫「等待」對話框。你能提出一些持續的自更新技術嗎? – 2009-04-29 08:16:49
的基本模式爲這種事情是:
有一個線程中運行一個循環,更新的變量(如動畫圖像的幀索引),然後在繪製圖像的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
我建議看看這個簡單的實現。我喜歡這個,但從來沒有用過它。可能對你有幫助。
ActivityIndicator是一個不錯的選擇,如果你是至少BB OS 6.0的工作。
http://www.brighthub.com/mobile/blackberry-platform/articles/94258.aspx
http://docs.blackberry.com/en/developers/deliverables/17966/Screen_APIs_1245069_11.jsp
這是加載畫面簡單的代碼....
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();
- 1. 動畫錯誤等待屏幕 - 黑莓
- 2. 黑莓 - 等待屏幕
- 3. 加載屏幕黑莓
- 4. 黑莓加載屏幕:按回到去加載屏幕
- 5. 黑莓中的加載屏幕
- 6. 黑莓 - 應用程序加載屏幕
- 7. 黑莓 - 屏幕底部的加載欄
- 8. 黑莓:InCall屏幕
- 9. 等待效果結束加載屏幕
- 10. 爲WPF窗口加載等待屏幕
- 11. 螺紋加載(等待)屏幕
- 12. 動畫加載屏幕
- 13. 黑莓主屏幕轉換
- 14. 黑莓屏幕導航
- 15. 黑莓屏幕導航
- 16. 黑莓部分屏幕MapView
- 17. 黑莓連接屏幕
- 18. 黑莓手機:屏幕不滾動
- 19. 黑莓問題凍結屏幕和緩慢加載
- 20. 顯示加載動畫在等待
- 21. 等待屏幕,等待響應
- 22. 黑莓verticalfieldmanager部分屏幕滾動與標籤字段
- 23. sh屏幕 - 等待屏幕終止
- 24. 添加垂直滾動條在黑莓應用程序屏幕
- 25. 加載屏幕動畫口吃
- 26. 加載紋理時的動畫屏幕
- 27. Xcode中動畫加載屏幕
- 28. 使用線程加載屏幕動畫
- 29. 黑莓,黑莓的初始屏幕圖像webworks
- 30. 與HTML5畫布等待動畫
你可以在這裏使用彈出屏幕視圖的例子。 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