最近碰到同样的问题。我已经开始关注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,但这是另一回事。