Improve dragging animation

This commit is contained in:
Victor Shcherb 2011-05-25 00:33:14 +02:00
parent e9317a4b89
commit 9fa007928a
3 changed files with 65 additions and 32 deletions

View file

@ -7,4 +7,4 @@
<item name="android:windowContentOverlay">@null</item> <item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">false</item> <item name="android:backgroundDimEnabled">false</item>
</style> </style>
</resources> </resources>

View file

@ -5,7 +5,11 @@ import net.osmand.osm.MapUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import android.os.SystemClock;
import android.util.FloatMath; import android.util.FloatMath;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
/** /**
* Thread for animated dragging. * Thread for animated dragging.
@ -70,7 +74,9 @@ public class AnimateDraggingMapThread implements Runnable {
@Override @Override
public void run() { public void run() {
currentThread = Thread.currentThread(); currentThread = Thread.currentThread();
AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
try { try {
boolean conditionToCountinue = true; boolean conditionToCountinue = true;
while (!stopped && conditionToCountinue) { while (!stopped && conditionToCountinue) {
// calculate sleep // calculate sleep
@ -159,11 +165,11 @@ public class AnimateDraggingMapThread implements Runnable {
conditionToCountinue = true; conditionToCountinue = true;
while (conditionToCountinue && callback != null) { while (conditionToCountinue && callback != null) {
conditionToCountinue = false; conditionToCountinue = false;
float rotationDiff = targetRotate-callback.getRotate(); float rotationDiff = targetRotate - callback.getRotate();
if (Math.abs((rotationDiff+360)%360) < Math.abs((rotationDiff-360)%360)) { if (Math.abs((rotationDiff + 360) % 360) < Math.abs((rotationDiff - 360) % 360)) {
rotationDiff = (rotationDiff+360)%360; rotationDiff = (rotationDiff + 360) % 360;
} else { } else {
rotationDiff = (rotationDiff-360)%360; rotationDiff = (rotationDiff - 360) % 360;
} }
float absDiff = Math.abs(rotationDiff); float absDiff = Math.abs(rotationDiff);
if (absDiff > 0) { if (absDiff > 0) {
@ -172,7 +178,7 @@ public class AnimateDraggingMapThread implements Runnable {
callback.rotateTo(targetRotate); callback.rotateTo(targetRotate);
} else { } else {
conditionToCountinue = true; conditionToCountinue = true;
callback.rotateTo(((absDiff/10)*Math.signum(rotationDiff) + callback.getRotate())%360); callback.rotateTo(((absDiff / 10) * Math.signum(rotationDiff) + callback.getRotate()) % 360);
} }
} }
} }
@ -285,32 +291,63 @@ public class AnimateDraggingMapThread implements Runnable {
thread.start(); thread.start();
} }
public void startDragging(float velocityX, float velocityY, float startX, float startY, float endX, float endY){ public void startDragging(final float velocityX, final float velocityY, float startX, float startY,
final float endX, final float endY){
stopAnimatingSync(); stopAnimatingSync();
targetZoom = 0;
this.notifyListener = true; this.notifyListener = true;
vx = velocityX;
vy = velocityY;
dirX = (byte) (endX > startX ? 1 : -1);
dirY = (byte) (endY > startY ? 1 : -1);
animateDrag = true;
ax = vx * a;
ay = vy * a;
time = System.currentTimeMillis();
stopped = false; stopped = false;
Thread thread = new Thread(this,"Animatable dragging"); //$NON-NLS-1$ final float animationTime = 1900f;
System.out.println("Velocity x " + velocityX + " velocity Y " + velocityY);
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
float curX = endX;
float curY = endY;
DecelerateInterpolator interpolator = new DecelerateInterpolator(1);
long timeMillis = SystemClock.uptimeMillis();
float normalizedTime = 0f;
float prevNormalizedTime = 0f;
while(!stopped){
normalizedTime = (SystemClock.uptimeMillis() - timeMillis) / animationTime;
if(normalizedTime >= 1f){
break;
}
float interpolation = interpolator.getInterpolation(normalizedTime);
float newX = velocityX * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curX;
float newY = velocityY * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curY;
callback.dragTo(curX, curY, newX, newY, notifyListener);
curX = newX;
curY = newY;
prevNormalizedTime = normalizedTime;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
stopped = true;
}
}
if(!stopped){
}
}
},"Animatable dragging"); //$NON-NLS-1$
thread.start(); thread.start();
} }
public void startRotate(float rotate) public void startRotate(float rotate) {
{
this.targetRotate = rotate; this.targetRotate = rotate;
if (!isAnimating()) { if (!isAnimating()) {
//stopped = false; // stopped = false;
//do we need to kill and recreate the thread? wait would be enough as now it // do we need to kill and recreate the thread? wait would be enough as now it
//also handles the rotation? // also handles the rotation?
Thread thread = new Thread(this,"Animatable dragging"); //$NON-NLS-1$ Thread thread = new Thread(this, "Animatable dragging"); //$NON-NLS-1$
thread.start(); thread.start();
} }
} }

View file

@ -421,7 +421,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
private void refreshMapInternal() { private void refreshMapInternal() {
handler.removeMessages(1); handler.removeMessages(1);
long time = System.currentTimeMillis(); // long time = System.currentTimeMillis();
boolean useInternet = getSettings().USE_INTERNET_TO_DOWNLOAD_TILES.get(); boolean useInternet = getSettings().USE_INTERNET_TO_DOWNLOAD_TILES.get();
if (useInternet) { if (useInternet) {
@ -439,7 +439,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
Canvas canvas = holder.lockCanvas(); Canvas canvas = holder.lockCanvas();
if (canvas != null) { if (canvas != null) {
boolean nightMode = false; boolean nightMode = false;
log.info("Canvas " + (System.currentTimeMillis() - time));
if (application != null) { if (application != null) {
Boolean dayNightRenderer = application.getDaynightHelper().getDayNightRenderer(); Boolean dayNightRenderer = application.getDaynightHelper().getDayNightRenderer();
if (dayNightRenderer != null) { if (dayNightRenderer != null) {
@ -455,7 +454,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left); latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left);
latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom); latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom);
latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right); latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right);
log.info("Calc" + (System.currentTimeMillis() - time));
if(nightMode){ if(nightMode){
canvas.drawARGB(255, 220, 220, 220); canvas.drawARGB(255, 220, 220, 220);
} else { } else {
@ -472,11 +470,9 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
// drawEmptyTile(canvas, x1, y1, ftileSize, nightMode); // drawEmptyTile(canvas, x1, y1, ftileSize, nightMode);
// } // }
// } // }
log.info("Draw before layers" + (System.currentTimeMillis() - time));
drawOverMap(canvas, latlonRect, tilesRect, nightMode); drawOverMap(canvas, latlonRect, tilesRect, nightMode);
log.info("Draw with layers " + (System.currentTimeMillis() - time)); // log.info("Draw with layers " + (System.currentTimeMillis() - time));
} finally { } finally {
holder.unlockCanvasAndPost(canvas); holder.unlockCanvasAndPost(canvas);
} }
@ -752,8 +748,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
@Override @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) { if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) {
animatedDraggingThread.startDragging(Math.abs(velocityX / 1000), Math.abs(velocityY / 1000), e1.getX(), e1.getY(), e2 animatedDraggingThread.startDragging(velocityX, velocityY,
.getX(), e2.getY()); e1.getX(), e1.getY(), e2.getX(), e2.getY());
} else { } else {
onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY()); onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY());
} }