Saturday, April 17, 2010

Using pointerDragged method

Some cell phones do not have a keyboard. They only have a touch screen.
In this case, if you have a Canvas
screen on your application you will have to rely only on pointer methods.

This fact came to me because a user of my Books
application have such a phone and sent me an email informing that he could not go back to a previous page.
I checked the application source code and found out the reason. The code used pointer methods only to go forward, never backwards.
I have developed (but not released) a solution using pointerDragged and here are the details.

For functional backward compatibility I had to differ from two user actions:


  • touch and release - methods call order is: first pointerPressed and then pointerReleased.
  • touch, dragg and release - methods call order is: first pointerPressed, then a lot of pointerDragged calls and then pointerReleased.

A new boolean attribute was added: pointerDragging. This attribute receives true at pointerDragged and is checked on pointerReleased.
If it is false I go forward to next book page. Below is how I use this attribute:

protected void pointerDragged(int x, int y) {
pointerDragging = true;
// ... more code. I will show this in a while
}
protected void pointerReleased(int x, int y) {
if (pointerDragging == false) {
// move the text down. Torwards the end of the file
this.keyPressed(Canvas.KEY_NUM8);
}
pointerDragging = false;
}


Now I had to add the new user action: text dragging. To help know where the dragging is moving a new class was created: Point.

class Point {

int x, y;

void set (int x, int y) {
this.x = x;
this.y = y;
}

boolean rightOf (int x) { return x < this.x; }

boolean leftOf (int x) { return x > this.x; }

boolean above (int y) { return y > this.y; }

boolean below (int y) { return y < this.y; }
}

A new Point attribute was added: lastPoint. It is initiated on constructor and used on pointerPressed to store the first point the user touched the screen.

protected void pointerPressed(int x, int y) {
this.lastPoint.set(x, y);
}

As pointerDragged method is called a lot of times I could not move to previous/next page at each call to this method.
I had to check if current x,y point was far enough from the lastPoint stored on pointerPressed.
And "far enough" came to me as font.getHeight(), where font is the Font instance used to draw the text on paint method.

Below is my final source code for pointerDragged method:


protected void pointerDragged(int x, int y) {
pointerDragging = true;

if (this.lastPoint.rightOf(x + font.getHeight())
|| this.lastPoint.above(y - font.getHeight())) {
// move the text up. Torwards the beginning of the file
this.keyPressed(Canvas.KEY_NUM2);
this.lastPoint.set(x, y);
}
else if (this.lastPoint.leftOf(x - font.getHeight())
|| this.lastPoint.below(y + font.getHeight())){
// move the text down. Torwards the end of the file
this.keyPressed(Canvas.KEY_NUM8);
this.lastPoint.set(x, y);
}
}

I check both x and y values because the user will be able to move between pages using up/down or left/right touch movements.
Next release of Books is planned for this week. Stay tuned!

Related topics:

2 comments:

Einar said...

Buenisimo Gracias!!!! :D mucho tiempo buscaba una solucion tan buena

y una cosa no sabes como hacer un desplazamiento mas suave jejeje y que reconozca la velocidad con que quieres q se desplase??? GRAX

Telmo Pimentel Mota said...

I chose this way for my Books app because the user will need to tap fewer times on the screen while reading.