安卓绘图需要用到三个类:Bitmap、canvas、paint。
绘图需要重写系统的View方法,通过自定义MyView来重写View,然后在自己的MyView中关联Bitmap类,Bitmap用来控制界面上的像素点。
再创建一个Canvas类,Canvas类关联Bitmap上的像素点,再创建一个Paint类,Paint类相当于画笔,用来调整颜色。
创建MyView重写系统的View时,要继承父类的上下文和属性,接着直接在构造函数里面去把Bitmap、Canvas、Paint三个绘图类给创建好。
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
map = Bitmap.createBitmap(720, 900, Config.ARGB_8888);
canvas = new Canvas(map);
this.setImageBitmap(map);
paint = new Paint();
paint.setStrokeWidth(2);
}
要在界面上操作就要在View里面添加监听,监听方法是:onTouchEvent(MotionEvent event)。
我自己重写的onTouchEvent(MotionEvent event)是这样的:
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
break;
case MotionEvent.ACTION_MOVE:
x2 = event.getX();
y2 = event.getY();
break;
case MotionEvent.ACTION_UP:
switch(Paint_demo.type){
case 11:MyRect mr = new MyRect();mr.myDraw(x1,y1,x2,y2);break;
case 22:MyOval mo = new MyOval();mo.myDraw(x1,y1,x2,y2);break;
case 33:MyLine ml = new MyLine();ml.myDraw(x1,y1,x2,y2);break;
}
this.invalidate();
break;
}
return true;
}
在按下和移动的时候获取到x,y坐标,然后在释放的时候检测要绘制的图形,画图板比较简单,只有三种图形:直线、矩形、圆形。
在layout文件夹中的XML文件就不可以写View了,必须包名加上自己重写的View类。
这里曾经遇到过一个问题:在画图板上画出来的位置与鼠标位置不匹配,后来在XML文件里面把layout_width与layout_height改成wrap_content就可以了。
public void myDraw(float x1,float y1,float x2,float y2) {
MyView.canvas.drawLine(x1, y1, x2, y2, MyView.paint);
}
public void myDraw(float x1,float y1,float x2,float y2) {
Rect rect = new Rect((int)x1, (int)y1, (int)x2, (int)y2);
MyView.canvas.drawRect(rect, MyView.paint);
}
public void myDraw(float x1,float y1,float x2,float y2) {
RectF recrf = new RectF((int)x1, (int)y1, (int)x2, (int)y2);
MyView.canvas.drawOval(recrf, MyView.paint);
}
这几段代码就是画直线,画矩形与画圆形。
设置颜色与更换图像类型的代码:
为每一个颜色按钮与图形类型按钮添加一个标签,然后创建一个监听,监听按钮事件,这样就可以实现颜色与图形的改变。
findViewById(R.id.red).setTag(1);
findViewById(R.id.yellow).setTag(2);
findViewById(R.id.green).setTag(3);
findViewById(R.id.ding).setTag(4);
findViewById(R.id.zi).setTag(5);
findViewById(R.id.blue).setTag(6);
findViewById(R.id.juxing).setTag(11);
findViewById(R.id.yuanxing).setTag(22);
findViewById(R.id.zhixian).setTag(33);
OnClickListener colorListener = new OnClickListener() {
public void onClick(View v) {
Button bt = (Button)v;
int color = (Integer) bt.getTag();
switch(color){
case 1:paint.setColor(Color.RED);break;
case 2:paint.setColor(Color.YELLOW);break;
case 3:paint.setColor(Color.GREEN);break;
case 4:paint.setColor(Color.CYAN);break;
case 5:paint.setColor(Color.MAGENTA);break;
case 6:paint.setColor(Color.BLUE);break;
}
}
};
OnClickListener typeListener = new OnClickListener(){
public void onClick(View v) {
Button bt = (Button)v;
int shapetype = (Integer) bt.getTag();
switch(shapetype){
case 11:type = 11;break;
case 22:type = 22;break;
case 33:type = 33;break;
}
}
};
最后别忘了添加监听:
findViewById(R.id.blue).setOnClickListener(colorListener);
findViewById(R.id.yellow).setOnClickListener(colorListener);
findViewById(R.id.red).setOnClickListener(colorListener);
findViewById(R.id.green).setOnClickListener(colorListener);
findViewById(R.id.ding).setOnClickListener(colorListener);
findViewById(R.id.zi).setOnClickListener(colorListener);
findViewById(R.id.zhixian).setOnClickListener(typeListener);
findViewById(R.id.yuanxing).setOnClickListener(typeListener);
findViewById(R.id.juxing).setOnClickListener(typeListener);
五子棋的绘图与画图板一样,先把棋盘的线条画出来,然后给棋盘上色:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
map = Bitmap.createBitmap(720, 720, Config.ARGB_8888);
type = "black";
canvas = new Canvas(map);
this.setImageBitmap(map);
paint = new Paint();
paint.setStrokeWidth(2);
for(int i=0;i<=18;i++){
canvas.drawLine(0, i*40, 720, i*40, paint);
canvas.drawLine(i*40, 0, i*40, 720, paint);
}
content = new int[18][18];
invalidate();
}
方法里面触发事件绘图、判断输赢
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
for(int i=1;i<18;i++){
for(int j=1;j<18;j++){
if( Math.abs(x1-j*40) < 20 && Math.abs(y1-i*40) < 20 && content[i][j] == 0 ){
if( type.equals("black") ){
RectF oval = new RectF(j*40-20,i*40-20,j*40+20,i*40+20);
paint.setColor(Color.BLACK);
canvas.drawOval(oval, paint);
type = "while";
content[i][j] = 1;
Boolean result = check(i,j);
if( result ){
Toast.makeText(getContext(), "黑子获胜", Toast.LENGTH_SHORT).show();
}
}else if( type.equals("while") ){
RectF oval = new RectF(j*40-20,i*40-20,j*40+20,i*40+20);
paint.setColor(Color.WHITE);
canvas.drawOval(oval, paint);
type = "black";
content[i][j] = 2;
check(i,j);
Boolean result = check(i,j);
if( result ){
Toast.makeText(getContext(), "白子获胜", Toast.LENGTH_SHORT).show();
}
}
}
}
}
}
invalidate();
return true;
}
最后就是判断输赢了
public boolean check(int i,int j){
if( WinInRow(i,j)|| WinInColumn(i,j)||leftColumn(i,j)||rightColumn(i,j)){
return true;
}
return false;
}