imooc学习笔记--五子棋

来源:互联网 发布:足彩过滤软件app 编辑:程序博客网 时间:2024/05/17 19:21

imooc视频地址

本次要练习的是自定义控件,并不是数学逻辑 ,所以主要的目的就是绘制棋盘。

养的猫咪跑丢了 郁闷ing….

首先看看效果图,然后分析一下。

这里写图片描述
首先,背景图 这个交给父容器
然后棋盘,可以分为两部分,第一是线、 第二是棋子。

首先画线的时候,肯定要求画的是矩形,所以必须要以长和宽当中最小的那一方来作为棋盘的边。
可以注意到有个细节是 在棋盘的左右离手机屏幕都有一定距离的。
棋盘是10*10的。
棋子落在线的交点上。

分析:
想要知道长和宽当中最小的那一方,前提是知道长和宽,获取长和宽的方法
那么获取宽高可以这样:

onMeasure方法中:    int width_size = MeasureSpec.getSize(widthMeasureSpec);    int height_size = MeasureSpec.getSize(heightMeasureSpec);    Log.e("ASD", getMeasuredWidth() + "****" + getMeasuredHeight());    Log.e("ASD", getWidth() + "++++" + getHeight());    Log.e("ASD", width_size + "----" + height_size);

可是,这三个哪个是设备宽高、哪个是获取控件宽高呢?于是我测了一下:

    <sunshine.myview2.MyView        android:layout_width="100dp"        android:layout_height="100px" />06-28 20:57:55.872 13720-13720/sunshine.myview2 E/ASD: 0,006-28 20:57:55.872 13720-13720/sunshine.myview2 E/ASD: 0,006-28 20:57:55.912 13720-13720/sunshine.myview2 E/ASD: 0****006-28 20:57:55.912 13720-13720/sunshine.myview2 E/ASD: 0++++006-28 20:57:55.912 13720-13720/sunshine.myview2 E/ASD: 200----111806-28 20:57:55.912 13720-13720/sunshine.myview2 E/ASD: 200****111806-28 20:57:55.912 13720-13720/sunshine.myview2 E/ASD: 0++++006-28 20:57:55.912 13720-13720/sunshine.myview2 E/ASD: 200----10006-28 20:57:56.116 13720-13720/sunshine.myview2 E/ASD: 200****10006-28 20:57:56.116 13720-13720/sunshine.myview2 E/ASD: 200++++10006-28 20:57:56.116 13720-13720/sunshine.myview2 E/ASD: 200----111806-28 20:57:56.116 13720-13720/sunshine.myview2 E/ASD: 200****111806-28 20:57:56.116 13720-13720/sunshine.myview2 E/ASD: 200++++10006-28 20:57:56.116 13720-13720/sunshine.myview2 E/ASD: 200----100

打开程序时候控件是会不断测量的(都这么说我也就当成定理了),应该看最后测量的结果。
getMeasuredWidth()获取的是200,getMeasuredHeight()获取的是1118.
getWidth()获取的是200,getHeight()获取的是100.
width_size是200,height_size是100.
获取到100的肯定都是像素了,获取到200应该是由于屏幕密度的原因,由dp转化为px时候是1:2的关系了,也就都是获取本控件的大小(px)。
1118是什么鬼呢,为啥前面是200,后面是1118!!!???

上网查了一下资料 觉得这里说的很好这里就不费时间了,主要内容如下:

①getMeasuredWidth方法获得的值是setMeasuredDimension方法设置的值,它的值在measure方法运行后就会确定
②getWidth方法获得是layout方法中传递的四个参数中的mRight-mLeft,它的值是在layout方法运行后确定的
③一般情况下在onLayout方法中使用getMeasuredWidth方法,而在除onLayout方法之外的地方用getWidth方法。

取两者中最小的作为矩形的边后(minWidth),我们发现还有个距离设备边框那边距的问题(相对于控件是margin),我们将边距预留为一份棋盘格子的minWidth,左右各1/2minWidth,也就是说我们画线的时候要预留1/2minWidth的边距。
画线代码(注意线的起点和重点,重复了就画不出来了 =.= 由于不熟练,折腾了一番才出来):

 @Override    protected void onDraw(Canvas canvas) {        for (int i = 0; i < 10; i++) {            //横线            canvas.drawLine(                    lineWidth / 2, (float) ((0.5 + i) * lineWidth),                    minWidth - lineWidth / 2, (float) ((0.5 + i) * lineWidth),                    paint_line);            //纵线            canvas.drawLine(                    (float) ((0.5 + i) * lineWidth), lineWidth / 2,                    (float) ((0.5 + i) * lineWidth), minWidth - lineWidth / 2,                    paint_line);        }    }

费了一番力气的效果图(画笔设置如下):

setBackgroundColor(0x99ff0000);
paint_line = new Paint();
paint_line.setColor(0xff00ff00);
paint_line.setStyle(Paint.Style.STROKE);
paint_line.setAntiAlias(true);
paint_line.setDither(true);

这里写图片描述

OK,下一步就是棋子了,要想显示棋子首先得先加载棋子,加载时候要先设定棋子大小,棋子大小要在onSizeChanged中设置(为什么呢,看方法名就能理解差不多了吧 - . - ),设置大小是用Bitmap.createScaledBitmap方法,一开始我写错成Bitmap.createBitmap了

createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,boolean filter)
createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)

后来去看了下才知道Bitmap.createScaledBitmap也是调用的Bitmap.createBitmap方法。

加载完之后就要显示出来啊,那怎么显示出来呢,肯定是触发了之后显示,那怎么触发呢,肯定找我们onTouchEvent(MotionEvent event)方法啊…..

    @Override    public boolean onTouchEvent(MotionEvent event) {    //如果没有ACTION_DOWN返回true 就不会执行ACTION_UP,不知道为什么        if (event.getAction() == MotionEvent.ACTION_DOWN) {            return true;        }        if (event.getAction() == MotionEvent.ACTION_UP) {            Point point = new Point(            (int) (event.getX() / lineWidth), (int) (event.getY() / lineWidth)            );            points.add(point);            invalidate();//重绘            return true;        }        return super.onTouchEvent(event);    }

重绘后再onDraw中画出棋子就Ok了

  for (int i = 0; i < points.size(); i++) {            Log.e("asd", points.get(i).x + "---" + points.get(i).y);            canvas.drawBitmap(stone_b,                    (int) (lineWidth / 2 - lineWidth * ratio / 2) + points.get(i).x * lineWidth,//x                    (int) (lineWidth / 2 - lineWidth * ratio / 2) + points.get(i).y * lineWidth,//y                    null);        }

看下最后的“成果”

这里写图片描述

1 0
原创粉丝点击