surfaceCreated()//通知Surface已被创建,可以在此处启动动画线程 surfaceChanged()//通知Surface已改变 surfaceDestroyed()//通知Surface已被销毁,可以在此处终止动画线程
SurfaceView使用有一个原则,即该界面操作必须在surfaceCreated之后及surfaceDestroyed之前。该回调的监听通过SurfaceHolder设置。代码如下://于SurfaceView类中,该类实现SurfaceHolder.Callback接口,如本例中的ParabolaView SurfaceHolder holder = getHolder(); holder.addCallback(this);
示例代码中,通过启动DrawThread调用handleThread()实现对SurfaceView的刷新。刷新界面首先需要执行holder.lockCanvas()锁定Canvas并获得Canvas实例,然后进行界面更新操作,最后结束锁定Canvas,提交界面更改,至Surface最终显示在屏幕上。
代码如下:
canvas = holder.lockCanvas(); … … … … … … … … canvas.drawBitmap(bitmap, x, y, paint); holder.unlockCanvasAndPost(canvas);
本例中,需要清除屏幕脏区域,出于简便的做法,是将整个SurfaceView背景重复地设置为透明,代码为:
canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);
对于SurfaceView的操作,下面这个链接讲述得更详细,更易理解,推荐去看下:Android开发之SurfaceView
惯例,Java代码如下,XML请自行实现
ActSurfaceView.java package lab.sodino.surfaceview; import lab.sodino.surfaceview.RotateAnimation.InterpolatedTimeListener; import android.app.Activity; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; public class ActSurfaceView extends Activity implements OnClickListener, ParabolaView.ParabolaListener, Callback, InterpolatedTimeListener { public static final int REFRESH_TEXTVIEW = 1; private Button btnStartAnimation; /** 动画界面。 */ private ParabolaView parabolaView; /** 购物车处显示购物数量的TextView。 */ private TextView txtNumber; /** 购物车中的数量。 */ private int number; private Handler handler; /** TextNumber是否允许显示最新的数字。 */ private boolean enableRefresh; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); handler = new Handler(this); number = 0; btnStartAnimation = (Button) findViewById(R.id.btnStartAnim); btnStartAnimation.setOnClickListener(this); parabolaView = (ParabolaView) findViewById(R.id.surfaceView); parabolaView.setParabolaListener(this); txtNumber = (TextView) findViewById(R.id.txtNumber); } public void onClick(View v) { if (v == btnStartAnimation) { LogOut.out(this, "isShowMovie:" + parabolaView.isShowMovie()); if (parabolaView.isShowMovie() == false) { number++; enableRefresh = true; parabolaView.setIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon)); // 设置起始Y轴高度和终止X轴位移 parabolaView.setParams(200, ((ViewGroup) txtNumber.getParent()).getLeft()); parabolaView.showMovie(); } } } public void onParabolaStart(ParabolaView view) { } public void onParabolaEnd(ParabolaView view) { handler.sendEmptyMessage(REFRESH_TEXTVIEW); } public boolean handleMessage(Message msg) { switch (msg.what) { case REFRESH_TEXTVIEW: if (txtNumber.getVisibility() != View.VISIBLE) { txtNumber.setVisibility(View.VISIBLE); } RotateAnimation anim = new RotateAnimation(txtNumber.getWidth() >> 1, txtNumber.getHeight() >> 1, RotateAnimation.ROTATE_INCREASE); anim.setInterpolatedTimeListener(this); txtNumber.startAnimation(anim); break; } return false; } @Override public void interpolatedTime(float interpolatedTime) { // 监听到翻转进度过半时,更新txtNumber显示内容。 if (enableRefresh && interpolatedTime > 0.5f) { txtNumber.setText(Integer.toString(number)); // Log.d("ANDROID_LAB", "setNumber:" + number); enableRefresh = false; } } }