Custom view to draw bitmap along path, calculate in background thread

Last post show a example of “Custom view to draw bitmap along path“, with calculation run inside onDraw(). It’s modified version to pre-calculate in back thread.


(remark: in last post, canvas.drawPath() is called inside onDraw(). It seem run very slow, removed in this example.)

Modify AnimationView.java

package com.blogspot.android_er.androidmovingbitmapalongpath;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class AnimationView extends View {

List<AnimationThing> animationThingsList;
public AnimationView(Context context) {
super(context);
initAnimationView();
}

public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
initAnimationView();
}

public AnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAnimationView();
}

private void initAnimationView(){
animationThingsList = new ArrayList<>();
}

public void insertThing(AnimationThing thing){
animationThingsList.add(thing);
}

//prepare calculation in background thread
public void preDraw(){
for (AnimationThing thing : animationThingsList){
if(thing.distance < thing.pathLength){
thing.pathMeasure.getPosTan(thing.distance, thing.pos, thing.tan);

thing.matrix.reset();
float degrees = (float)(Math.atan2(thing.tan[1],
thing.tan[0])*180.0/Math.PI);
thing.matrix.postRotate(degrees, thing.bm_offsetX, thing.bm_offsetY);
thing.matrix.postTranslate(thing.pos[0]-thing.bm_offsetX,
thing.pos[1]-thing.bm_offsetY);

thing.distance += thing.step;
}else{
thing.distance = 0;
}
}
}

@Override
protected void onDraw(Canvas canvas) {
for (AnimationThing thing : animationThingsList){
canvas.drawBitmap(thing.bm, thing.matrix, null);
}

invalidate();
}


/*
@Override
protected void onDraw(Canvas canvas) {
for (AnimationThing thing : animationThingsList){

//This code run slow!!!
//canvas.drawPath(thing.animPath, thing.paint);

if(thing.distance < thing.pathLength){
thing.pathMeasure.getPosTan(thing.distance, thing.pos, thing.tan);

thing.matrix.reset();
float degrees = (float)(Math.atan2(thing.tan[1],
thing.tan[0])*180.0/Math.PI);
thing.matrix.postRotate(degrees, thing.bm_offsetX, thing.bm_offsetY);
thing.matrix.postTranslate(thing.pos[0]-thing.bm_offsetX,
thing.pos[1]-thing.bm_offsetY);

canvas.drawBitmap(thing.bm, thing.matrix, null);

thing.distance += thing.step;
}else{
thing.distance = 0;
}
}

invalidate();
}
*/



}

MainActivity.java

package com.blogspot.android_er.androidmovingbitmapalongpath;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Path;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

AnimationView myAnimationView;
AniThread myAniThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myAnimationView = (AnimationView)findViewById(R.id.MyAnimationView);

prepareThings();
myAniThread = new AniThread(myAnimationView);
myAniThread.start();

}

private void prepareThings() {
Path animPath;
float step;
Bitmap bm;

bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

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();

step = 1;

AnimationThing thing = new AnimationThing(animPath, bm, step);
myAnimationView.insertThing(thing);

//The second thing
bm = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_add);

animPath.reset();
animPath.addCircle(400, 400, 300, Path.Direction.CW);
step = 3;
thing = new AnimationThing(animPath, bm, step);
myAnimationView.insertThing(thing);
}

class AniThread extends Thread{

AnimationView targetView;

public AniThread(AnimationView target) {
super();
targetView = target;
}

@Override
public void run() {
while (true){
targetView.preDraw();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}


}

The other files, AnimationThing.java and activity_main.xml, refer last post.

download filesDownload the files .

Android-er