Color 类
int color = Color.bule //蓝色
int color = Color.argb(255,255,255,255); //透明度,红,绿,蓝
在XML文件中定义颜色
Paint 类
Paint.setColor(Color.blue);
Canvas 类
Canvas.drawCircle(300, 400, 100, paint);
矩形。圆形、空心、实心、线、文字、……
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setARGB(255, 0, 255, 0);
paint.setStyle(Paint.Style.STROKE);// 空心
paint.setStrokeWidth(10);// 边的宽度
canvas.drawRect(100, 100, 500, 500, paint);// 矩形
paint.setStyle(Paint.Style.FILL);// 实心
paint.setColor(Color.CYAN);
canvas.drawCircle(500, 500, 100, paint);// 圆形
paint.setTextSize(100);
paint.setColor(Color.BLUE);
canvas.drawText("Apple ggGG", 50, 800, paint);
paint.setColor(Color.RED);
paint.setStrokeWidth(5);// 边的宽度
canvas.drawLine(0, 800, 720, 800, paint);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher), 200, 200, paint);
super.onDraw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
// 首先取得屏幕的宽度和高度
width = this.getWidth();
cell_width = width / 9f;
height = this.getHeight();
cell_height = height / 9f;
// 首先画出背景
Paint bgPaint = new Paint();// 用于绘制背景
bgPaint.setColor(getResources().getColor(R.color.shudu_background));
canvas.drawRect(0, 0, width, height, bgPaint);
// 画出九宫格
Paint darkPaint = new Paint();// 暗色
darkPaint.setColor(getResources().getColor(R.color.shudu_dark));
Paint lightPaint = new Paint();// 亮色
darkPaint.setColor(getResources().getColor(R.color.shudu_light));
Paint hilitePaint = new Paint();// 线条
darkPaint.setColor(getResources().getColor(R.color.shudu_hilite));
for (int i = 0; i < 9; i++) {
if (i % 3 == 0) {
canvas.drawLine(0, i * cell_height, width, i * cell_height,
lightPaint);
canvas.drawLine(i * cell_width, 0, i * cell_width, height,
lightPaint);
} else {
canvas.drawLine(0, i * cell_height, width, i * cell_height,
darkPaint);
canvas.drawLine(i * cell_width, 0, i * cell_width, height,
darkPaint);
}
canvas.drawLine(0, i * cell_height + 1, width, i * cell_height + 1,
hilitePaint);
canvas.drawLine(i * cell_width + 1, 0, i * cell_width + 1, height,
hilitePaint);
}
// 绘制文字
Paint numPaint = new Paint();
numPaint.setColor(Color.BLUE);
numPaint.setStyle(Paint.Style.STROKE);
numPaint.setTextSize(cell_height * 0.25f);
numPaint.setTextAlign(Paint.Align.CENTER);
float x = cell_width / 2;
float y = cell_height / 2;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
canvas.drawText("" + i + "," + j, i * cell_width
+ x, j * cell_height + y, numPaint);
}
}
super.onDraw(canvas);
}
FontMtrics类
FontMetrics fontMetrics = paint.get FontMetrics();
FontMetrics fm = numPaint.getFontMetrics();
float x = cell_width / 2;
float y = cell_height / 2 - (fm.ascent + fm.descent) / 2;
把逻辑处理放在Activity外部,新建一个类
package com.arlen.android.game.shudu03;
public class Game {
private final String str = "450890000000000000008700090607005030090020040040900102070006300000000000000048016";
private int shuduku[] = new int[81];
public Game() {
shuduku = fromPuzzleString(str);
}
private int getTitle(int x, int y) {
return shuduku[y * 9 + x];
}
public String getTitleString(int x, int y) {
int v = getTitle(x, y);
if (v == 0) {
return "";
} else {
return String.valueOf(v);
}
}
protected int[] fromPuzzleString(String src) {
int sudu[] = new int[src.length()];
for (int i = 0; i < sudu.length; i++) {
sudu[i] = src.charAt(i) - '0';
}
return sudu;
}
}
在View中调用
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
canvas.drawText(game.getTitleString(i, j), i * cell_width + x,
j * cell_height + y, numPaint);
}
}
在为初始化数字的空格中点击,然后输入数字
public Boolean onTouchEvent(MotionEvent event){
//获取事件的类型
event.getAction();
//获取点击坐标
Event.getX();
Event.getY();
}
// 生成一个layoutInflater对象
LayoutInflater layoutInflater = LayoutInflater.from(this.getContext());
// 使用layoutInflater对象更具一个布局文件生成一个view对象
View layoutView = layoutInflater.inflate(R.layout.dialog, null);
// 从生成好的textView中取出相应的控件
TextView textView = (TextView) layoutView
.findViewById(R.id.textViewUsedId);
// 设置textView的内容
textView.setText(sb.toString());
// 生成一个对话框的builder对象
AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
// 设置地对话框所要显示的内容
builder.setView(layoutView);
// 生成对话框对象并将其显示出来
AlertDialog dialog = builder.create();
dialog.show();
用户点击屏幕之后,确定用户点击的位置属于哪一个格子
取得用户点击的坐标,判断是否在startX、startY与stopX、stopY之间
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN) {
return super.onTouchEvent(event);
}
int selectX = (int) (event.getX() / cell_width);
int selectY = (int) (event.getY() / cell_height);
int used[] = game.getUsedTileByCoor(selectY, selectY);
for (int i = 0; i < used.length; i++) {
System.out.println(used[i]);
}
return true;
}
在每一行、每一列、每一个小的九宫格中已有的数据禁止重复输入,
//用于计算所有单元格对应的不可用的数据
public void calculateAllUsedTitles() {
for (int x = 0; x < 9; x++) {
for (int y = 0; y < 9; y++) {
used[x][y] = calculateUsedTiles(x, y);
}
}
}
//取出某一单元格已经不可用的数据
public int[] getUsedTileByCoor(int x, int y) {
return used[x][y];
}
// 计算某一单元格中已经用过的数据
public int[] calculateUsedTiles(int x, int y) {
int c[] = new int[9];
for (int i = 0; i < 9; i++) {
if (i == y) {
}
int t = getTitle(x, i);
if (t != 0) {
c[t - 1] = t;
}
}
for (int i = 0; i < 9; i++) {
if (i == x) {
continue;
}
int t = getTitle(i, y);
if (t != 0) {
c[t - 1] = t;
}
}
int startX = (x / 3) * 3;
int startY = (y / 3) * 3;
for (int i = startX; i < startX + 3; i++) {
for (int j = startY; j < startY + 3; j++) {
if (i == x && j == y) {
continue;
}
int t = getTitle(i, y);
if (t != 0) {
c[t - 1] = t;
}
}
}
// compress
int nused = 0;
for (int t : c) {
if (t != 0) {
nused++;
}
}
int c1[] = new int[nused];
nused = 0;
for (int t : c) {
if (t != 0) {
c1[nused++] = t;
}
}
return c1;
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keypad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TableRow>
<Button
android:id="@+id/button1"
android:text="1" />
<Button
android:id="@+id/button2"
android:text="2" />
<Button
android:id="@+id/button3"
android:text="3" />
</TableRow>
<TableRow>
<Button
android:id="@+id/button4"
android:text="4" />
<Button
android:id="@+id/button5"
android:text="5" />
<Button
android:id="@+id/button6"
android:text="6" />
</TableRow>
<TableRow>
<Button
android:id="@+id/button7"
android:text="7" />
<Button
android:id="@+id/button8"
android:text="8" />
<Button
android:id="@+id/button9"
android:text="9" />
</TableRow>
</TableLayout>
根据点击的位置不同,弹出的窗口不同
package com.arlen.android.game.shudu03;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
public class KeyDialog extends Dialog {
// 用来存放代表对话框中按钮的对象
private final View keys[] = new View[9];
private final int used[];
// 构造函数的第二个参数保存当前单元格已经用过的数据
public KeyDialog(Context context, int[] used) {
super(context);
this.used = used;
}
// 当对话框第一次被调用的时候,会调用其onCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 标题
this.setTitle("Key Dialog");
// 为该对话框设置布局文件
this.setContentView(R.layout.keypad);
findViews();
// 便利整个used数组
for (int i = 0; i < used.length; i++) {
if (used[i] != 0) {
keys[used[i] - 1].setVisibility(View.INVISIBLE);
}
}
}
private void findViews() {
keys[0] = findViewById(R.id.button1);
keys[1] = findViewById(R.id.button2);
keys[2] = findViewById(R.id.button3);
keys[3] = findViewById(R.id.button4);
keys[4] = findViewById(R.id.button5);
keys[5] = findViewById(R.id.button6);
keys[6] = findViewById(R.id.button7);
keys[7] = findViewById(R.id.button8);
keys[8] = findViewById(R.id.button9);
}
}