Tuesday, January 31, 2012

Animated GIF image Field With Text

This is a sample code for an animated GIF image field with a text at the bottom:
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.system.GIFEncodedImage;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.BitmapField;

//A field that displays an animated GIF.

public class ImageTextField extends BitmapField
{
    private GIFEncodedImage gifimage;     //The image to draw.
    private String text;
    private int currentFrame;          //The current frame in the animation sequence.
    private AnimatorThread animatorThread;
    
    private final int vSpace = 6; 
 private final int padding = 5;
 
 private int xImage = 0;
 private int yImage = 0;
 private int xText = 0;
 private int yText = 0;
    
    public ImageTextField(EncodedImage image, String txt)
    {
     super(image.getBitmap(), 0);
     byte[] arr = image.getData();
  gifimage = (GIFEncodedImage) EncodedImage.createEncodedImage(arr, 0, arr.length);
  text = txt;
  
  animatorThread = new AnimatorThread(this);
        animatorThread.start();
    }
    
    public ImageTextField(EncodedImage image, String txt, long style)
    {
     super(image.getBitmap(), style);
     byte[] arr = image.getData();
  gifimage = (GIFEncodedImage) EncodedImage.createEncodedImage(arr, 0, arr.length);
  text = txt;
  
 animatorThread = new AnimatorThread(this);
        animatorThread.start();
    }
    
    public int getPreferredWidth() {
  return (gifimage==null ? 0 : gifimage.getWidth()) + 50;
    }


 public int getPreferredHeight() {
  int imageHeight = gifimage==null ? 0 : gifimage.getHeight();
  int textHeight = getFont().getHeight();
  return imageHeight + vSpace + textHeight + 2 * padding;
 }
 

 protected void layout(int width, int height) {
  width = Math.min(width, getPreferredWidth());
  height = Math.min(getPreferredHeight(), height);
  
  int imageWidth = (gifimage==null ? 0 : gifimage.getWidth());
  int imageHeight = (gifimage==null ? 0 : gifimage.getHeight());

  xImage = (width - imageWidth) / 2;
  yImage = padding;

  xText = (width - getFont().getAdvance(text)) / 2;
  yText = yImage + imageHeight + vSpace;

  setExtent(width, height);
 }

    protected void paint(Graphics graphics)
    {

        graphics.drawImage(xImage, yImage,
        gifimage.getFrameWidth(currentFrame), gifimage.getFrameHeight(currentFrame), gifimage, currentFrame, 0, 0);
        
        int oldColor = graphics.getColor();
        graphics.setColor(Color.WHITE);
        graphics.drawRoundRect(0, 0, getWidth(), getHeight(), 5, 5);
        graphics.drawText(text, xText, yText);
        graphics.setColor(oldColor);
    }

    //Stop the animation thread when the screen the field is on is
    //popped off of the display stack.
    protected void onUndisplay()
    {
        animatorThread.stop();
        super.onUndisplay();
    }


    //A thread to handle the animation.
    private class AnimatorThread extends Thread
    {
        private ImageTextField theImageField;
        private boolean keepGoing = true;
        private int totalFrames;     //The total number of frames in the image.
        private int loopCount;       //The number of times the animation has looped (completed).
        private int totalLoops;      //The number of times the animation should loop (set in the image).

        public AnimatorThread(ImageTextField theField)
        {
            theImageField = theField;
            totalFrames = gifimage.getFrameCount();
            totalLoops = gifimage.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()
                    {
                        theImageField.invalidate();
                    }
                });

                try
                {
                    //Sleep for the current frame delay before
                    //the next frame is drawn.
                    sleep(gifimage.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;
                    }
                }
            }
        }
    }
}
Now this animated image field can be added to a manager:
VerticalFieldManager mainLayout = getCustomManager();
mainLayout.setBackground(BackgroundFactory.createSolidBackground(Color.BLACK));
EncodedImage ec = EncodedImage.getEncodedImageResource("myimage.gif");
ImageTextField ag = new ImageTextField(ec, "My Text", FIELD_HCENTER);
mainLayout.add(ag);

No comments:

Post a Comment