Blackberry - 带动画的加载/等待屏幕
Posted
技术标签:
【中文标题】Blackberry - 带动画的加载/等待屏幕【英文标题】:Blackberry - Loading/Wait screen with animation 【发布时间】:2010-10-22 12:25:29 【问题描述】:有没有办法在黑莓中显示“加载”屏幕动画?
选项:
PME 动画内容 多线程+图像集+定时器/计数器 标准 rim api 其他方式有这些吗?
谢谢!
【问题讨论】:
您可以在此处使用弹出屏幕查看示例。 supportforums.blackberry.com/t5/Java-Development/…我用这个解决了我的问题。 【参考方案1】:费尔明,安东尼+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 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(
"***.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 Web2.0/Ajax-style loading popup in a native BlackBerry application
【讨论】:
感谢分享。我还可以通过添加“graphics.drawText(text, xText, yImage);”在图像旁边显示文本在paint() 方法中。要计算图像和文本的坐标,请使用“this.getFont().getAdvance(text)”和“this.getFont().getHeight();”。 我可以添加任何帧的图像吗?我正在添加一个 12 帧的图像,但它没有正确绘制。它出现又消失..不确定问题出在哪里.. @Newbie 打印出来或在调试中查看 _totalLoops 值 - 这是要播放的循环数。检查你的动画是否有无限循环caount值,也许它是1所以只播放了一次。 如果你在加载GIF图片时碰巧遇到了NPE(NullPointerEx),请阅读:supportforums.blackberry.com/t5/Java-Development/…【参考方案2】:这种事情的基本模式是:
让一个线程运行一个循环来更新一个变量(例如动画图像的帧索引),然后在绘制图像的字段上调用 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
【讨论】:
【参考方案3】:这是加载屏幕的简单代码......
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();
【讨论】:
【参考方案4】:如果它只是一个动画,您能否在弹出窗口中显示animated gif 并在加载操作完成时将其关闭?
【讨论】:
【参考方案5】:最简单的方法可能是使用标准 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);更新进度条。
我通常会从正在执行工作的任何线程调用它(在您的情况下加载,每次操作完成时,进度条都会更新。
【讨论】:
感谢您的回答,但我不需要进度条,而是动画“等待”对话框。你能推荐一些持续自我更新的技术吗?【参考方案6】:我建议看看这个简单的实现。我喜欢这个,但从未使用过。可能对你有帮助。
link text
【讨论】:
是的,它很棒!但看看我的回答,它已经在那里了,最后)))【参考方案7】:如果您至少使用 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
【讨论】:
以上是关于Blackberry - 带动画的加载/等待屏幕的主要内容,如果未能解决你的问题,请参考以下文章