【Android自定義View】- 表格控制元件
簡介
記得第一次寫文章是自己剛開始自學Android的時候,當時不知道怎麼地,從一個學習硬體,控制轉向學習java,畢業找了一份機頂盒上的Android應用開發,兩年多跳了兩家公司,每次簡歷都不知道寫些啥,時隔兩年多,重新開始寫文章,只希望逼迫自己不斷學習,分享也是快樂。
效果

螢幕快照 2018-12-10 上午10.01.11.png

jjj.gif
功能
1. 繪製類似excel第一個單元格分類樣式 2. 設定水平和垂直標題 3. 通過編碼控制單元格顯示圖片 4. 單元格點選事件和自動更新編碼資料 5. 常規的表格資料展示
實現
-
繪製表格水平分割線(垂直同理)
/**
* 從右至左,分別表示有無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事件,通過座標,算出當前觸控點所在的單元格,然後做區域判斷,通過&更新資料,
完整思路請檢視原始碼
ofollow,noindex">原始碼