最近碰到同樣的問題。我已經開始關注framelayout的想法,並提供了一系列的觀點,但對於性能和我在繪製和定製項目下方的網格方面所做的大量工作並不滿意。
因此,我繼續和集成的解決方案是擴展View
類,覆蓋它的onDraw
和相關方法,並在那裏繪製任何我需要的東西。
在這種情況下,我對所發生的事情以及我想要的樣子有了大量的控制權。不用說,我可以並且確實實現了一些性能改進,例如將底層網格緩存到位圖以及什麼都不是,當您使用佈局和視圖組合等高級功能時很難實現這些功能。
在任何情況下,你,或誰是有同樣的問題,可能要開始簡單的東西,像(代碼是把我的頭頂部):
public class MyDayTimeline extends View {
String [] timeMarkers; // time strings, like "9.00 AM" or something
Rect [] eventRects; // a bunch of rectangles, which correspond to your events
final int rowCount;
final int rowHeightPx;
final int firstColumnWidthPx;
// ..... constructors, size and painting initialization, event position calculation and whatnot
@Override
protected void onDraw(Canvas canvas) {
canvas.drawLine(firstColumnWidthPx, 0, firstColumnWidthPx, getMeasuredHeight(), delimeterLinesPaint); // draw a delimeter between time markers and the rest of the control space
for (int i = 1; i < rowCount; i++) {
canvas.drawLine(0, i * rowHeightPx, getMeasuredWidth(), i * rowHeightPx, delimeterLinesPaint); // draw a bunch of lines separating each hour
}
for(int i = 0; i < eventRects.size(); i++) { // draw a bunch rectangles, each representing an event
canvas.drawRect(eventRects[i], eventPaintBackgroundPaint);
canvas.drawRect(eventRects[i], eventPaintBorderPaint);
}
}
}
一瞥的量需要完成的工作似乎相當令人難以置信,但實際上並不是這樣,如果你首先計劃你需要做的事情然後做。我走了這樣的事情:
- 開始繪製一個簡單的時間軸網格在
onDraw()
覆蓋,所有的大小和顏色被硬編碼。
- 覆蓋
onMeasure()
和onSizeChanged()
,開始相應地更改您的尺寸控制字段。我用簡單的尺寸去決定我在哪裏採用所有可用的空間寬度,並且大膽地要求高度方向24 * rowHeightPx
,而不考慮測量規格。
- 'canvas.drawText()'在時間網格中放置了一堆時間裏程碑。
- 想出一個結構來定義你的事件。我去了開始和結束日期/時間,一些主題字符串和一個矩形數組。當控件的大小發生變化時,我會重新計算每個事件應該採用的矩形。
- 執行
onDraw()
中的事件圖,使您的先前定義的結構和位置計算就緒。
- 處理特定情況,例如跨越幾天的事件。
- 開始處理水龍頭
onTouchEvent()
什麼的。添加一些日誌記錄以查看是否正確執行命中測試,如果需要和不需要的話,開始使用突出顯示的顏色重新繪製事件框架。
- 從可重用性的角度出發,讓您的控制更好。爲某些屬性定義getter和setter,在
attrs.xml
中定義自定義屬性,實現初始化代碼中的處理。公開一些自定義偵聽器,如EventClickedListener或其他。
- 在上面添加一些支持控件。將所有東西包裝在
ScrollView
中,我使用ViewPager
來處理水平滑動並顯示前一天/第二天/一週/一月。
- 給定幾乎準備好的日期時間表,從中提取基類並開始處理其他時間線,如周和月。
然後繼續改進你的控制,直到你和你的隊友對結果滿意爲止。顯然,你需要不斷地測試,調試和修復你每一步的控制,所以擁有一堆測試用例是非常有用的。
我在使用標準的Calendar API時也遇到了一些問題,當我在進行周和月概述時,所以您可能會考慮使用其他庫,如Joda Time,但這是另一回事。