安卓项目五子棋代码详解(二)

hello,大家好,这里是第二期的代码详解。

上一期的说明个人重新看了一下发现还有逻辑没有理清,这里便补充说明一下,实现自定义view要重写三种方法,分别是onMeasure(),onLayout(),onDraw(),

  1.View本身大小多少,这由onMeasure()决定;

  2.View在ViewGroup中的位置如何,这由onLayout()决定;

  3.绘制View,onDraw()定义了如何绘制这个View。

在这个五子棋项目中,onLayout是采取默认的,并没有重写。

 

话不多说,进入正题——

 

onMeasure()方法上一期没有说明,这一期来说明一下,代码如下:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int WidthSize = MeasureSpec.getSize(widthMeasureSpec);
        int WidthMode = MeasureSpec.getMode(widthMeasureSpec);
        
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        
        int width = Math.min(WidthSize, heightSize); //因为棋盘是正方形,所以取最小值,
        
        if(WidthMode == MeasureSpec.UNSPECIFIED){//MeasureSpec.UNSPECIFIED表示未知大小
            width = heightSize;
        }else if(heightMode == MeasureSpec.UNSPECIFIED){
            width = WidthSize;
        }
        setMeasuredDimension(width, width);//设置实际大小,两个width分别为长和宽,相同即是正方形
    }

 

 

protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

onMeasure传入的两个参数是由上一层控件传入的大小,有多种情况,重写该方法时需要对计算控件的实际大小,然后调用setMeasuredDimension(int, int)设置实际大小。

onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。

我们需要通过int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸

这个方法代码其实就是用来设置棋盘的大小的。

 

除此之外,还要重写一个onSizeChange()方法,代码如下:

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {//当View大小发生改变(比如分辨率变化)的时候会被系统自动回调。
        super.onSizeChanged(w, h, oldw, oldh);
        
        PanelWidth =w;
        mLineHeight = PanelWidth * 1.0f/Max_LINE;
        
        int pieceWidth = (int)(mLineHeight*ratioPieceOfLineheight);//棋子大小占行宽的3/4
        Whitepiece = Bitmap.createScaledBitmap(Whitepiece, pieceWidth, pieceWidth, false); //以src为原图,创建新的图像,指定新图像的高宽以及是否可变
        Blackpiece = Bitmap.createScaledBitmap(Blackpiece, pieceWidth, pieceWidth, false);
    }
    

解释标记出来了,这里也就不啰嗦什么了。

接下来解释的是onDraw()方法里面的drawBoard()方法。代码如下:

private void drawBoard(Canvas canvas) {
        int w = PanelWidth;
        float LineHeight = mLineHeight;
        for(int i=0;i<Max_LINE;i++){    //画十条线
            int startX = (int)(LineHeight/2);//设置起点横坐标为半个棋盘空格的宽度
            int endX = (int)(w-LineHeight/2);//设置终点X横坐标为宽度减去半个lineHeight(棋盘空格宽度)
            int y =(int)((0.5+i)*LineHeight);
            canvas.drawLine(startX, y, endX, y, paint);//画横线
            canvas.drawLine(y, startX, y, endX, paint);//画纵线,坐标反过来
        }
    }

正如其名,drawBoard()就是用来画棋盘的,通过for循环画出横线,这里的注释需要仔细地思索一下,想清楚画笔起始坐标是如何计算得出的

 

这一期就到这里了,下面附上参考资料:

 

 

深入自定义View的知识

onMeasure简单见解

 

 

 

 

 

 

 

posted @ 2017-08-02 14:06  Stars-one  阅读(630)  评论(0编辑  收藏