绘制表格水平分割线(垂直同理)
/**
* 从右至左,分别表示有无left,top,right,bottom边框线(0 - 无,1 - 有)
*/
private int mFrameLine = 0x0101;
private void drawHorizontalFrameLine(Canvas canvas){
//记录水平横线路径
if ((0x0010 & mFrameLine) != 0 ){
mHorizontalFrameLinePath.moveTo(0,0);
mHorizontalFrameLinePath.lineTo(width,0);
}
if ((mContentLine & 0x01) != 0){
for(int i = 1 ; i < mVerticalGap; i++){
int y = cellHeight * i;
mHorizontalFrameLinePath.moveTo(0,y);
mHorizontalFrameLinePath.lineTo(width,y);
}
}
if ((0x1000 & mFrameLine) != 0 ){
mHorizontalFrameLinePath.moveTo(0,height);
mHorizontalFrameLinePath.lineTo(width,height);
}
canvas.drawPath(mHorizontalFrameLinePath,mFrameLinePaint);
}
创建水平和垂直Path路径变量,记录分割线路径,通过变量mFrameLine来控制表格四条边框的绘制路径。
绘制表格第一个分类单元格
如果设置了分类数据,第一个单元格绘制分类标题,如果没有者是空白
private void drawOneCell(Canvas canvas) {
//绘制第一个单元格分类
drawTableTitleLine(canvas);
String topTitle = mHorizontalTitle[0];
String leftTitle = mVerticalTitle[0];
int t = 0;
int b = mTableHeadTextHeight + 8;
int l = cellWidth / cellHeight * b;
int r = cellWidth;
int hX = l + (r - l) / 2;
int hY = b;
canvas.drawText(topTitle,hX,hY,mTableHeadPaint);
int vX = (cellWidth - l) / 2;
int vY = (int) (1.5*hY + mTableHeadTextHeight);
canvas.drawText(leftTitle,vX,vY,mTableHeadPaint);
}
绘制表格类容
类容绘制支持两种模式,
普通的数据填充模式:设置一个String数组数据给控件,控件会安装顺序填充。
编码模式:水平方向,分别表示4,2,1,单元格状态分别有1,0两种,通过&来确定单元格目前状态,然后给单元格绘制不同的图片数据。比如传入传入编码数据,比如“7654321”,7表示水平第一行三个单元格状态都是1,这样就在单元格里绘制相应的图片,比如打勾。
private void drawContentText(Canvas canvas) {
int startIndex = mStartRowIndex * mHorizontalGap + mStartColumnIndex -1;
startIndex = startIndex < 0 ? 0 : startIndex;
int num = mHorizontalGap * mVerticalGap;
for (int i = startIndex ; i < num; i++){
int hIndex = i % mHorizontalGap;
int vIndex = i / mHorizontalGap;
if (mStartRowIndex -1 >= hIndex){
continue;
}
if (hIndex >= mHorizontalGap || vIndex >= mVerticalGap){
return;
}
if (mMode == MODE_STRING_DATA){
int index = (vIndex - mStartRowIndex)*(mHorizontalGap - mStartColumnIndex) + hIndex - mStartColumnIndex;
if(index < 0 || index >= mContentStrData.length){
continue;
}
String str = mContentStrData[index];
drawCell(canvas,i,str);
}else if (mMode == MODE_ENCODER_DATA){
int encoderStart = hIndex - mStartColumnIndex;
encoderStart = encoderStart < 0 ? 0 : encoderStart;
if (encoderStart >= ENCODER.length){
return;
}
int encoder = ENCODER[encoderStart];
int vIndexStart = vIndex - mStartRowIndex;
vIndexStart = vIndexStart < 0 ? 0 : vIndexStart;
if(vIndexStart >= mContentIntData.length ){
return;
}
if ((encoder & mContentIntData[vIndexStart]) != 0){
if (null != oneBitmap){
drawCell(canvas,i,oneBitmap);
}else {
drawCell(canvas,i,oneStr);
}
}else {
if (null != zeroBitmap){
drawCell(canvas,i,zeroBitmap);
}else {
drawCell(canvas,i,zeroStr);
}
}
}
}
}
单元格点击事件和数据更新(在编码模式下)
通过重写onTouchEvent事件,通过坐标,算出当前触摸点所在的单元格,然后做区域判断,通过&更新数据,
完整思路请查看源码
源码