有点吃不开了,这个时候就要用到SurfaceView类。
因为比较高级,所以就该装B,单纯一个继承自SurfaceView类是不行的,必须实现一个SurfaceHolder.Callback接口来指明SurfaceView创建、改变、删除时的回调方法,并且
在SurfaceView中通过一个SurfaceHolder对象来控制SurfaceView。
如果将该SurfaceView作为某个Activity的全屏View,则直接调用setContentView(new MyView());就好了;但若是作为屏幕View的一部份,就应该修改对应的layout XML文件
了,添加类似的布局代码:
其中com.example.fq.MyView为对应自定义类的全名。
由于默认的XML文件解析方法是调用View的View(Context , AttributeSet )构造函数构造View,因此你的自定义SurfaceView中也应该有一个参数为(Context , AttributeSet )
的构造函数,并且在构造函数中执行父类的对应函数super( Context , AttributeSet )。
在绘图时,必须首先用Canvas c=holder.lockCanvas();锁定并获得画布,随后进行绘制,再调用holder.unlockCanvasAndPost(c);将绘制内容进行呈现
下面是个例子运行图:
主界面:
- public
class MainActivity extends Activity { -
-
private MyView mSV=null; -
private Button mBtnOk; -
private Button mBtnCancle; -
@Override -
public void onCreate(Bundle savedInstanceState) { -
super.onCreate(savedInstanceState); -
setContentView(R.layout.main); -
mSV=(MyView)findViewById(R.id.sv); -
mSV.setTag(true); -
mBtnOk=(Button)findViewById(R.id.btnok); -
mBtnOk.setOnClickListener(new OnClickListener() { -
-
public void onClick(View arg0) { -
// TODO Auto-generated method stub -
mSV.setTag(true); -
} -
}); -
-
mBtnCancle=(Button)findViewById(R.id.btnCancel); -
mBtnCancle.setOnClickListener(new OnClickListener() { -
-
public void onClick(View arg0) { -
// TODO Auto-generated method stub -
mSV.setTag(false); -
} -
}); -
} - }
MyTest界面:
- public
class MyView extends SurfaceView implements SurfaceHolder.Callback{ -
private SurfaceHolder holder=null; //控制对象 -
private Vector<Float> xs=new Vector<Float>(); -
private Vector<Float> ys=new Vector<Float>(); -
public MyView(Context context, AttributeSet attrs) { -
super(context, attrs); -
holder=getHolder(); -
holder.addCallback(this); -
} -
-
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { -
// TODO Auto-generated method stub -
-
} -
-
public void surfaceCreated(SurfaceHolder arg0) { -
// TODO Auto-generated method stub -
new Thread(new MyLoop()).start();//在 View 中系统不允许主线程外的线程控制 UI .但是 SurfaceView 却可以 -
} -
-
public void surfaceDestroyed(SurfaceHolder arg0) { -
// TODO Auto-generated method stub -
-
} -
public void doDraw(Canvas canvas) { -
// TODO Auto-generated method stub -
super.onDraw(canvas); -
canvas.drawColor(Color.WHITE);//这里是绘制背景 -
Paint p=new Paint(); //笔触 -
p.setAntiAlias(true); //反锯齿 -
p.setColor(Color.BLACK); -
p.setStyle(Style.STROKE); -
int a=xs.size(); -
for(int i=0;i<xs.size();i++) -
canvas.drawCircle(xs.elementAt(i),ys.elementAt(i),10, p); -
} -
-
@Override -
public boolean onTouchEvent(MotionEvent event) { -
// TODO Auto-generated method stub -
if(event.getAction()==MotionEvent.ACTION_DOWN){ -
String a=this.getTag().toString(); -
if(a.equals("true")){ -
xs.add(event.getX()); -
ys.add(event.getY()); -
} -
} -
return true; -
} -
-
class MyLoop implements Runnable{ -
//熟悉游戏编程的应该很面熟吧,主循环 -
public void run() { -
// TODO Auto-generated method stub -
while(true){ -
try{ -
Canvas c=holder.lockCanvas(); -
doDraw(c); -
holder.unlockCanvasAndPost(c); -
Thread.sleep(20); -
}catch(Exception e){ -
-
} -
} -
} -
-
} - }
main.xml文件:
- < ?xml
version="1.0" encoding="utf-8"?> - <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" -
android:layout_width="fill_parent" -
android:layout_height="fill_parent" -
> -
<com.android.sv.MyView -
android:id="@+id/sv" -
android:layout_width="fill_parent" -
android:layout_height="fill_parent" -
/> -
<Button android:id="@+id/btnok" -
android:layout_width="wrap_content" -
android:layout_height="wrap_content" -
android:text="开启绘图"/> -
<Button android:id="@+id/btnCancel" -
android:layout_width="wrap_content" -
android:layout_height="wrap_content" -
android:layout_toRightOf="@id/btnok" -
android:text="取消绘图"/> - </RelativeLayout>