您的位置:首页 > 其它

通过2048学习自定义view(一)

2018-01-30 16:26 316 查看

简介

在刚学安卓的时候就尝试着用TextView和LinearLayout写过一个没有动画的2048,现在自学了快半年了,想着写一个2048View来巩固一下之前学的自定义view的知识。(写这篇文章时只完成了开始部分,后面的下一篇文章再补)

在这里强烈推荐 :HenCoder 的自定义view教程

本篇目标

作为自定义view,所有的绘制过程都应该在
onDraw()
里完成,而且应该满足各种尺寸。效果如下:





正片

几个重要的属性:(Coordinate是一个存放坐标的类下文给出)

private int length;//view的长宽
private int[][] numOfGrid = new int[4][4];//记录每一个格中的数字
private Coordinate[][] coor;//坐标
private int padding;//方格之间的距离


首先为了保持整个view一直是正方形,重写
onMeasure()
方法:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSize < heightSize) {
length = widthSize;
} else {
length = heightSize;
}
setMeasuredDimension(length, length);//使长和宽相等,且为二者最小的那个
coor = Coordinate.CreateCoordinate(length);//创建坐标,计算各个方格的坐标
padding = length / 50;
}


Coordinate类:

public class Coordinate {
public final int X;
public final int Y;
public Coordinate(int y, int x) {
X = x;
Y = y;
}
//创建16个方块对应的坐标
public static Coordinate[][] CreateCoordinate(int width) {
Coordinate[][] res = new Coordinate[4][4];
int part = width / 4;
for (int i = 0; i < 4; i++) {   //j是x,i是y
for (int j = 0; j < 4; j++) {
res[i][j] = new Coordinate(part * i, part * j);
}
}
return res;
}
}


之后就是重头戏
onDraw()


我的想法是自底向上一层一层地铺。首先画一个大正方形作为背景,然后换颜色画16个小的空白的带圆角的正方形(通过循环画的,用到了之前计算出来的各个方格的坐标),一个空的棋盘就画好了。

@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(getResources().getColor(R.color.paint));
//画背景 and 16个格子
canvas.drawRect(0, 0, length, length, paint);
paint.setColor(getResources().getColor(R.color.background));
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
canvas.drawRoundRect(coor[i][j].X + padding, coor[i][j].Y + padding,
coor[i][j].X + length / 4 - padding, coor[i][j].Y + length / 4 - padding,
padding, padding, paint);
}
}
drawGrid(canvas, paint);//根据 numOfGrid 画每一个格子
}


之后便是画带数字的格子了:

首先随机生成两个数字‘2’,即令
numOfGrid
数组中的两个随机位置的值等于2(默认为0)。接着循环遍历一遍
numOfGrid
,当里面的值不为0的时候,在对应的xy坐标的位置画一个正方形(颜色与数字相关,通过
color.set.get(2-2048)
得到,相关代码请脑补)。

数字是用
canvas.drawText()
画的,这个方法与其他draw方法不一样,起始坐标是从左下角开始算的(其他的
drawXXX()
是从左上角开始算的),请务必注意。为了满足所有尺寸都可以,数字的size必须与总长度相关,试了几次感觉size为总长度的1/8最好。

<
4000
span class="hljs-keyword">private void drawGrid(Canvas canvas, Paint paint) {
int num = 0;
for (int i = 0; i < 4; i++) {   //j是x,i是y
for (int j = 0; j < 4; j++) {
num = numOfGrid[i][j];
if (num == 0) continue;
paint.setColor(Color.parseColor(color.set.get(num)));
canvas.drawRoundRect(coor[i][j].X + padding, coor[i][j].Y + padding,
coor[i][j].X + length / 4 - padding, coor[i][j].Y + length / 4 - padding,
padding, padding, paint);
//画数字
paint.setColor(Color.parseColor(color.set.get(0)));
paint.setTextSize(length / 8);//这个8是试出来的。。
canvas.drawText(num + "", coor[i][j].X + length / 11, coor[i][j].Y + length / 6, paint);
}
}
}


剩下的内容下篇再见。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  2048 自定义view