编写这个程序之前,你需要对SurfaceView有一定的了解。
View是使用UI主线程开发的,如果UI主线程任务过于繁重,那么UI主线程将阻塞。
SurfaceView是直接从内存和DMA等取得数据,而且SurfaceView可以通过主线程之外的线程更新UI。
被动更新:通过点击事件等更新。(VIEW)
主动更新:一直在更新。(Surface)
这是游戏结束时弹出的对话框,为了避免重复刷新获取视图资源,所以采取静态内部类来供调用。
public class AlertScoreDialog extends Dialog{
private TextView tv_score;
private Button btn_finish;
private Button btn_restart;
private View mRootView;
public AlertScoreDialog(Context context) {
this(context,0);
}
public AlertScoreDialog(Context context, int themeResId) {
super(context, themeResId);
mRootView = LayoutInflater.from(getContext()).inflate(R.layout.dialog_score,null);
tv_score = (TextView) mRootView.findViewById(R.id.tv_score);
btn_finish = (Button) mRootView.findViewById(R.id.dialog_btn_finish);
btn_restart = (Button) mRootView.findViewById(R.id.dialog_btn_restart);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(mRootView);
Window window = getWindow();
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setCanceledOnTouchOutside(false);
}
public void setScore(String score){
if(tv_score!=null){
tv_score.setText(score);
}
}
private void setFinishClickListener(View.OnClickListener onClickListener){
if(btn_finish!=null){
btn_finish.setOnClickListener(onClickListener);
}
}
private void setRestartClickListener(View.OnClickListener onClickListener){
if(btn_restart!=null){
btn_restart.setOnClickListener(onClickListener);
}
}
//静态内部类,供主UI调用。
public static class Builder {
private AlertScoreDialog mAlertScoreDialog;
public Builder(Context context){
mAlertScoreDialog = new AlertScoreDialog(context);
}
public Builder setScore(String score){
mAlertScoreDialog.setScore(score);
return this;
}
public Builder setFinishClickListener(View.OnClickListener onClickListener){
mAlertScoreDialog.setFinishClickListener(onClickListener);
return this;
}
public Builder setRestartClickListener(View.OnClickListener onClickListener){
mAlertScoreDialog.setRestartClickListener(onClickListener);
return this;
}
public AlertScoreDialog builder(){
return mAlertScoreDialog;
}
}
}
本程序黑白快需要一直更新,所以用SurfaceView。
SurfaceHolder可以看成SurfaceView的控制器,控制图形图像的大小像素等。 继承SurfaceHolder接口所以需要实现三个回调方法。
这是开始创建时的回调方法,在此方法中使用 initBlock();进行初始化黑白块。然后开启线程。
public void surfaceCreated(SurfaceHolder holder) {
initBlock();
mBlockPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mScorePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mScorePaint.setTextSize(DensityUtil.sp2px(getContext(),mScore.getTextSize()));
mScorePaint.setColor(mScore.getTextColor());
//设置边框线 mScorePaint.setStrokeWidth(DensityUtil.px2dip(getContext(),mScore.getStrokeWidth()));
// 开启线程
mIsRuning = true;
mDrawThread = new Thread(this);
mDrawThread.start();
}
mDrawThread 线程中有一个draw()方法,用于绘制block和score,draw()负责把黑白快下移。
UI线程分析在博客二。
源码地址:https://github.com/ZeeeeeeNo/PianoTiles