【问题标题】:BlackBerry - Create image viewer黑莓 - 创建图像查看器
【发布时间】:2013-07-14 05:20:23
【问题描述】:

我需要在我的应用程序中创建图像幻灯片(图像应定期更改,并具有淡入/淡出效果)。我尝试了一些代码,但它抛出了非法异常。

是否有任何选项可以以编程方式更改图片滚动字段中的图像? 来自线程或其他什么?

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);
    }
}

【问题讨论】:

  • 上面的代码是用来展示一系列图片的,比如gif动画。
  • 更改定时器的间隔
  • @Signare ya 我从你给出的链接中得到了代码.. 但是onnum nadakkanilla..enthenkilum 想法来实现这个?
  • 您好 Signare 我已经用您的代码创建了动态图像 ..:) 现在需要在图像之间设置淡入淡出动画...非常感谢 :)

标签: blackberry blackberry-eclipse-plugin


【解决方案1】:

发布的代码将抛出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)。所有值都以毫秒为单位。

有用的参考资料

BlackBerry AnimatedGIFField sample code.

BlackBerry forums thread about fade in / fade out

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多