Wednesday, September 10, 2008

Animated Focus Transition For Regular Components

Lists in LWUIT have a great animation by default to show the transition between elements in the list. Components placed in the form don't have that animation by default, but they can thanks to the ability to infinitely customize everything about LWUIT.
The animation is comprised of motion objects tracking the transition from one element to the next and painting an overlay before setting the actual focus element, the code is really very simple...
class FocusAnimation extends Form {
private Component futureFocus;
private Motion focusMotionX;
private Motion focusMotionY;
private Motion focusMotionWidth;
private Motion focusMotionHeight;
public FocusAnimation() {
super("Focus Animation");
for(int iter = 1 ; iter < 5 ; iter++) {
addComponent(new Button("Button " + iter));
}
addComponent(new TextArea("Multi-line text\nwith several\ndifferent lines", 3, 20));
addComponent(new List(new Object[] {"Entry 1", "Entry 2", "Entry 3"}));
addComponent(new ComboBox(new Object[] {"Entry 1", "Entry 2", "Entry 3"}));
}

public void setFocused(Component c) {
Component current = getFocused();
if(current != null && current != c) {
futureFocus = c;
focusMotionX = Motion.createSplineMotion(current.getAbsoluteX(), futureFocus.getAbsoluteX(), 300);
focusMotionY = Motion.createSplineMotion(current.getAbsoluteY(), futureFocus.getAbsoluteY(), 300);
focusMotionWidth = Motion.createSplineMotion(current.getWidth(), futureFocus.getWidth(), 300);
focusMotionHeight = Motion.createSplineMotion(current.getHeight(), futureFocus.getHeight(), 300);
focusMotionX.start();
focusMotionY.start();
focusMotionWidth.start();
focusMotionHeight.start();
super.setFocused(null);
} else {
super.setFocused(c);
}
}

public void paint(Graphics g) {
super.paint(g);
if(futureFocus != null) {
g.setColor(futureFocus.getStyle().getBgSelectionColor());
g.fillRect(focusMotionX.getValue(), focusMotionY.getValue(),
focusMotionWidth.getValue(), focusMotionHeight.getValue(),
(byte)140);
}
}

public boolean animate() {
boolean val = super.animate();
if(futureFocus != null && focusMotionX.isFinished()) {
super.setFocused(futureFocus);
futureFocus = null;
focusMotionX = null;
focusMotionY = null;
focusMotionWidth = null;
focusMotionHeight = null;
}
return val || futureFocus != null;
}
}

6 comments:

  1. hello sir,
    when i copy paste this code for understanding animation,it gives exception as illegal access...
    what is wrong with this?

    ReplyDelete
  2. Can you post the stack trace?
    I have no idea why this should fail

    ReplyDelete
  3. I tried this on the BlackBerry build. I'm not sure what the problem is, but animate() is not called at all so the focus never gets to the next component.

    ReplyDelete
  4. It seems to be fixed by calling form.registerAnimated(form). Is this a good workaround?

    ReplyDelete
  5. That's by design. The bug is in my code that didn't invoke registerAnimated()

    ReplyDelete
  6. Shai Almog.Awesome transition effect, it would be great, if you provide the examples with implemented projects.

    ReplyDelete