Dans Android, si vous souhaitez animer un objet et le faire déplacer un objet de location1 à location2, l'API d'animation détermine les emplacements intermédiaires (interpolation), puis met en file d'attente sur le thread principal les opérations de déplacement appropriées aux moments appropriés à l'aide d'une minuterie . Cela fonctionne bien, sauf que le thread principal est généralement utilisé pour de nombreuses autres choses - peinture, ouverture de fichiers, réponse aux entrées de l'utilisateur, etc. Un temporisateur en file d'attente peut souvent être retardé. Les programmes bien écrits essaieront toujours de faire autant d'opérations que possible dans les threads d'arrière-plan (non principaux), mais vous ne pouvez pas toujours éviter d'utiliser le thread principal. Les opérations qui vous obligent à opérer sur un objet d'interface utilisateur doivent toujours être effectuées sur le thread principal. En outre, de nombreuses API redirigent les opérations vers le thread principal sous forme de sécurité des threads.
Les vues sont toutes dessinées sur le même thread GUI qui est également utilisé pour toutes les interactions utilisateur.
Donc, si vous devez mettre à jour rapidement l'interface graphique ou si le rendu prend trop de temps et affecte l'expérience utilisateur, utilisez SurfaceView.
Exemple d'image de rotation:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
drawThread = new DrawThread(getHolder(), getResources());
drawThread.setRunning(true);
drawThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
drawThread.setRunning(false);
while (retry) {
try {
drawThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
class DrawThread extends Thread{
private boolean runFlag = false;
private SurfaceHolder surfaceHolder;
private Bitmap picture;
private Matrix matrix;
private long prevTime;
public DrawThread(SurfaceHolder surfaceHolder, Resources resources){
this.surfaceHolder = surfaceHolder;
picture = BitmapFactory.decodeResource(resources, R.drawable.icon);
matrix = new Matrix();
matrix.postScale(3.0f, 3.0f);
matrix.postTranslate(100.0f, 100.0f);
prevTime = System.currentTimeMillis();
}
public void setRunning(boolean run) {
runFlag = run;
}
@Override
public void run() {
Canvas canvas;
while (runFlag) {
long now = System.currentTimeMillis();
long elapsedTime = now - prevTime;
if (elapsedTime > 30){
prevTime = now;
matrix.preRotate(2.0f, picture.getWidth() / 2, picture.getHeight() / 2);
}
canvas = null;
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(picture, matrix, null);
}
}
finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
activité:
public class SurfaceViewActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MySurfaceView(this));
}
}