In order to get the position and angle of the animated bitmap in a distance along a path, we use the code:
pathMeasure = new PathMeasure(animPath, false);
pathLength = pathMeasure.getLength();
...
pathMeasure.getPosTan(distance, pos, tan);
where pos, and tan are float[2] passed to retrieve the resulting position and tangent.
MainActivity.java.
package com.example.androidanimationalongpath;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
/res/layout/activity_main.xml, simple include our custom view in layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidanimationalongpath.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<com.example.androidanimationalongpath.AnimationView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
AnimationView.java, custom view.
package com.example.androidanimationalongpath;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Toast;
public class AnimationView extends View {
Paint paint;
Bitmap bm;
int bm_offsetX, bm_offsetY;
Path animPath;
PathMeasure pathMeasure;
float pathLength;
float step; //distance each step
float distance; //distance moved
float[] pos;
float[] tan;
Matrix matrix;
public AnimationView(Context context) {
super(context);
initMyView();
}
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
initMyView();
}
public AnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initMyView();
}
public void initMyView(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
bm_offsetX = bm.getWidth()/2;
bm_offsetY = bm.getHeight()/2;
animPath = new Path();
animPath.moveTo(100, 100);
animPath.lineTo(200, 100);
animPath.lineTo(300, 50);
animPath.lineTo(400, 150);
animPath.lineTo(100, 300);
animPath.lineTo(600, 300);
animPath.lineTo(100, 100);
animPath.close();
pathMeasure = new PathMeasure(animPath, false);
pathLength = pathMeasure.getLength();
Toast.makeText(getContext(), "pathLength: " + pathLength, Toast.LENGTH_LONG).show();
step = 1;
distance = 0;
pos = new float[2];
tan = new float[2];
matrix = new Matrix();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(animPath, paint);
if(distance < pathLength){
pathMeasure.getPosTan(distance, pos, tan);
matrix.reset();
float degrees = (float)(Math.atan2(tan[1], tan[0])*180.0/Math.PI);
matrix.postRotate(degrees, bm_offsetX, bm_offsetY);
matrix.postTranslate(pos[0]-bm_offsetX, pos[1]-bm_offsetY);
canvas.drawBitmap(bm, matrix, null);
distance += step;
}else{
distance = 0;
}
invalidate();
}
}
Download the files.