有一个项目要使用工作表,选择使用canvas来绘制,实现显示工作日程的选择,可点击添加和取消,效果图:http://jwzhangjie.com/workplan.gif
自定义控件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; } }
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(); } }
<?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>
http://jwzhangjie.com/workplan.gif