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


    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简单见解

     

     

     

  • 相关阅读:
    MySql相关
    RabbmitMQ 的配置及开启MQTT服务
    cmake 编译.so or .a文件很大问题
    模型上移动端遇到简单的问题:No variants found for 'app'
    第一次用go mod模式创建beego1.12的步骤
    python中RabbitMQ的使用hello world简单模式
    Ubuntu18.04 20.04安装rabbitMQ
    Django的mysqlclient报错
    《软件需求》读书笔记六
    《软件需求》读书笔记五
  • 原文地址:https://www.cnblogs.com/stars-one/p/7273580.html
Copyright © 2020-2023  润新知