有一个项目要使用工作表,选择使用canvas来绘制。实现显示工作日程的选择,可点击加入和取消​

自己定义控件FormView:

package com.sun.elderly.comm.widget;

import com.sun.elderly.comm.ui.interfaces.IFormListener;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;

/**
* 绘制表格
*
* @author jwzhangjie
*/
public class FormView extends View {

private int firstX = 0; // 起始点x
private int firstY = 0; // 起始点y
private int secondX = 80; // 第二点x
private int secondY = 50; // 第二点y
private int widthNum = 8; // 列
private int heightNum = 10; // 行
private int secondSideX = 150; // 第二列的宽
private int sideY = 50; // 行高
private int firstSidesX = 80; // 第一列的宽
private int workColor = 0xffADFF2F;
private int restColor = 0xffAD0F2F;
private int selectColor = 0xffAD00FF;

private String[] rowText = null;
private String[] colText = null;
private String noData = "-1";

public void setRowAndColText(String[] rowText, String[] colText) {
this.rowText = rowText;
this.colText = colText;
invalidate();
}

public SparseArray<String> list = new SparseArray<String>();
private SparseArray<String> backList = new SparseArray<String>();

IFormListener myFormListener;

public IFormListener getFormListener() {
return myFormListener;
}

public void setFormListener(IFormListener myFormListener) {
this.myFormListener = myFormListener;
}

public FormView(Context context) {
super(context);
}

public FormView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void init(int width, int height) {
secondSideX = (width - firstSidesX) / (widthNum - 1);
// invalidate();
}

public void setList(SparseArray<String> list) {
this.list = list;
backList.clear();// 重置
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (colText != null && rowText != null) {
drawForm(canvas);
}
}

private void drawForm(Canvas canvas) {
Paint paint = new Paint();

paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);

paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
int cellX = 0, cellY = 0, cellBX = 0, cellBY = 0;
for (int i = 0; i < widthNum; i++){

for (int j = 0; j < heightNum; j++) {
if (i == 0) { // 假设是第一列绘制第一列的宽度
cellX = firstX + i * firstSidesX;
cellY = firstY + j * sideY;
cellBX = firstX + (i + 1) * firstSidesX;
cellBY = firstY + (j + 1) * sideY;
} else {
cellX = secondX + (i - 1) * secondSideX;
cellY = secondY + (j - 1) * sideY;
cellBX = secondX + i * secondSideX;
cellBY = secondY + j * sideY;
}

canvas.drawRect(cellX, cellY, cellBX, cellBY, paint);
int cellsNum = i + j * widthNum;
if (j == 0) {
drawCellText(canvas, cellX, cellY, cellBX, cellBY,
rowText[i]);
}
if (cellsNum % widthNum != 0) {
if (!noData.equals(list.get(cellsNum, noData))) {
if (list.get(cellsNum).equals("0")) {
drawCellColor(canvas, cellX, cellY, cellBX, cellBY,
workColor);
} else {
drawCellColor(canvas, cellX, cellY, cellBX, cellBY,
restColor);
}
} else if (!noData.equals(backList.get(cellsNum, noData))) {
drawCellColor(canvas, cellX, cellY, cellBX, cellBY,
selectColor);
} else {
drawCellColor(canvas, cellX, cellY, cellBX, cellBY,
0xFFF);
}
} else {// 绘制第一列
drawCellText(canvas, cellX, cellY, cellBX, cellBY,
colText[cellsNum / widthNum]);
}
}
}
}

// 绘制单元格中的文字
private void drawCellText(Canvas canvas, int cellX, int cellY, int cellBX,
int cellBY, String text) {
Paint paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLUE);
int textSize = (cellBY - cellY) / 5 * 2;
paint.setTextSize(textSize);
int textX = cellX + (cellBX - cellX) / 10;
int textY = cellBY - (cellBY - cellY) / 3;
canvas.drawText(text, textX, textY, paint);
}

// 绘制单元格中的颜色
private void drawCellColor(Canvas canvas, int cellX, int cellY, int cellBX,
int cellBY, int color) {
Paint paint = new Paint();
// 绘制备选颜色边框以及当中颜色
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(cellX + 1, cellY + 1, cellBX - 1, cellBY - 1, paint);
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {

float touchX = event.getX();
float touchY = event.getY();

int antion = event.getAction();
if (antion == MotionEvent.ACTION_DOWN) {
testTouchColorPanel(touchX, touchY);
}
return super.onTouchEvent(event);
}

// 检測点击事件所在的格数
public boolean testTouchColorPanel(float x, float y) {
if (x > secondX && y > secondY
&& x < firstX + firstSidesX + secondSideX * widthNum
&& y < firstY + sideY * heightNum) {

int ty = (int) ((y - firstY) / sideY);
int tx;

if (x - firstX - firstSidesX > 0) {
tx = (int) ((x - firstX - firstSidesX) / secondSideX + 1);
} else {
tx = 0;
}
int index = ty * widthNum + tx;
if (noData.equals(list.get(index, noData))) {
if (!noData.equals(backList.get(index, noData))) {
backList.remove(index);
myFormListener.showNum(index, 1);
} else {
backList.put(index, "2");
myFormListener.showNum(index, 2);
}
invalidate();
} else {
myFormListener.showNum(index, 0);
}
return true;
}
return false;
}
}


主界面DrawFormActivity:

package com.sun.elderly.test;

import com.sun.elderly.R;
import com.sun.elderly.comm.ui.interfaces.IFormListener;
import com.sun.elderly.comm.widget.FormView;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.SparseArray;
import android.view.ViewTreeObserver;
import android.widget.Toast;

public class DrawFormActivity extends FragmentActivity implements IFormListener {

private FormView myFormView;
private SparseArray<String> list = new SparseArray<String>();
private String[] rowText = { "", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六",
"星期日" };
private String[] colText = { "", "9:00", "10:00", "11:00", "12:00",
"13:00", "14:00", "15:00", "16:00", "17:00" };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("工作表");
setContentView(R.layout.test_drawform);
myFormView = (FormView) findViewById(R.id.formId);
list.put(12, "0");// key:位置 ,value:0--已经预约 1--歇息时间 2--预备预约占用
list.put(18, "1");
list.put(19, "1");
list.put(21, "0");
list.put(33, "0");
list.put(46, "1");
myFormView.setList(list);
myFormView.setFormListener(this);
ViewTreeObserver vto = myFormView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myFormView.getViewTreeObserver().removeOnPreDrawListener(this);
int height = myFormView.getMeasuredHeight();
int width = myFormView.getMeasuredWidth();
myFormView.init(width, height);
myFormView.setRowAndColText(rowText, colText);
return true;
}
});
}

@Override
public void showNum(int num, int status) {
switch (status) {
case 0:
showInfo(num + "当前时间已经被占用");
break;
case 1:
showInfo("取消选择:" + num);
break;
case 2:
showInfo("选择工作时间: " + num);
break;
}
}

private void showInfo(String text) {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT)
.show();
}
}


布局test_drawform:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<com.sun.elderly.comm.widget.FormView
android:id="@+id/formId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dip"
/>

</LinearLayout>


显示效果:

安卓使用Canvas绘制工作日程表_xml

安卓使用Canvas绘制工作日程表_android_02

安卓使用Canvas绘制工作日程表_ide_03

安卓使用Canvas绘制工作日程表_android_04


安卓使用Canvas绘制工作日程表_xml_05