我需要在我的应用程序中创建一个图像幻灯片(即,应在一定的时间间隔内以淡入/淡出效果更改图像)。我已经尝试了一些代码,但是它引发了非法异常。
是否可以通过编程方式更改图片滚动字段中的图像?即从线程之类的东西?
public class SlideTransition extends MainScreen {
final Bitmap image000 = Bitmap.getBitmapResource("img1.jpg");
final Bitmap image001 = Bitmap.getBitmapResource("img2.jpg");
final Bitmap image002 = Bitmap.getBitmapResource("img3.jpg");
final BitmapField animationField = new BitmapField(image000);
int counter = 0;
Timer animationTimer = new Timer();
TimerTask animationTask;
public SlideTransition() {
animationTask = new TimerTask() {
public void run() {
if (counter == 0) {
animationField.setBitmap(image000);
}
if (counter == 1) {
animationField.setBitmap(image001);
}
if (counter == 2) {
animationField.setBitmap(image002);
counter = -1;
}
counter++;
}
};
animationTimer.scheduleAtFixedRate(animationTask, 0, 100);
add(animationField);
}
}
发布的代码将引发,IllegalStateException
因为它试图直接从后台(计时器)线程修改UI元素:
animationField.setBitmap(image000);
您需要使用UiApplication.getUiApplication().invokeLater()
或类似方法从后台线程修改UI。
另外,您可以让计时器连续调整位图字段的Alpha值(不透明度)以产生淡入淡出效果。
这是一个示例,从您提供的代码开始:
public class SlideTransition extends MainScreen {
private final Bitmap image000 = Bitmap.getBitmapResource("img1.jpg");
private final Bitmap image001 = Bitmap.getBitmapResource("img2.jpg");
private final Bitmap image002 = Bitmap.getBitmapResource("img3.jpg");
private AlphaBitmapField animationField = new AlphaBitmapField(image000);
private Timer animationTimer = new Timer();
private TimerTask animationTask;
private final int animationPeriodMsec = 40; // 25 Hz animation timer
public SlideTransition() {
animationTask = new AnimationTask();
add(animationField);
animationTimer.scheduleAtFixedRate(animationTask, 0, animationPeriodMsec);
}
// I separated your anonymous timer task into its own class for readability
private class AnimationTask extends TimerTask {
private final int fadeDurationMsec = 500;
private final int displayDurationMsec = 1500;
private final int fadeInEndCount = fadeDurationMsec / animationPeriodMsec;
private final int fadeOutStartCount = (fadeDurationMsec + displayDurationMsec) / animationPeriodMsec;
private final int endCount = (2 * fadeDurationMsec + displayDurationMsec) / animationPeriodMsec;
private int imgCounter = 0;
private int cycleCounter = 0;
public void run() {
if (cycleCounter >= endCount) {
cycleCounter = 0;
}
Bitmap newImage = null;
if (cycleCounter == 0) {
// time to switch the images
if (imgCounter == 0) {
newImage = image000;
} else if (imgCounter == 1) {
newImage = image001;
} else if (imgCounter == 2) {
newImage = image002;
imgCounter = -1;
}
imgCounter++;
}
// assign final variables to use inside a UI thread Runnable
final Bitmap currentImage = newImage;
final int i = cycleCounter;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
if (i == 0) {
// switch images, and start with the image invisible (alpha = 0)
animationField.setAlpha(0);
animationField.setBitmap(currentImage);
} else if (i <= fadeInEndCount) {
// fade in by changing alpha
animationField.setAlpha(i * 255 / fadeInEndCount);
} else if (i >= fadeOutStartCount) {
// fade out by changing alpha
animationField.setAlpha(255 + (fadeOutStartCount - i) * 255 / (endCount - fadeOutStartCount));
}
}
});
cycleCounter++;
}
}
// this class extends BitmapField to allow alpha adjustment, and automatic repainting
private class AlphaBitmapField extends BitmapField {
private int _alpha;
public AlphaBitmapField(Bitmap img) {
super(img);
}
public void setAlpha(int alpha) {
if (alpha != _alpha) {
_alpha = alpha;
// force a repaint
invalidate();
}
}
protected void paint(Graphics graphics) {
graphics.setGlobalAlpha(_alpha);
super.paint(graphics);
}
}
}
我从您的代码中更改了时间值,但是您可以将它们修改为任意的值。我使动画计时器以每秒25个周期运行。我发现这对于智能手机动画来说是一个合理的价值。它的速度足以使它看起来相当平滑,但仅是人眼可以处理此类信息的速度的两倍……任何更快的速度都可能是浪费的。
我定义了一些常数,您可以使用这些常数来控制淡入和淡出所花费的时间(fadeDurationMsec
)以及淡入和淡出之间所显示的每个图像的时间(displayDurationMsec
)。所有值均以毫秒为单位。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句