I want to create Timeline like in iPhone
The event time can be 9.42 and it should start drawing below dash line of 9.30 with the % of how far from 9.30.
The only way I can think of is using ScrollView
with FrameLayout
and programatically add timeline.
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<FrameLayout
android:id="@+id/timeline"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</FrameLayout>
</ScrollView>
It can be better if I able to use ListView
instead of ScrollView
but I don't know how to freedomly place The event across the cells because If event start from 10.50.
The text that describes this event has to cross the cell.
Can someone suggest me? Thanks.
Bumped into the same issue recently. I've started with your idea of framelayout with a bunch of views on top of it, but wasn't really pleased with performance and an amount of work I have to do to draw and customize, say, a grid below items.
So a solution I went ahead and integrated was to extend View
class, override its onDraw
and related methods and just draw whatever I need there.
In this case I get an enormous amount of control over what's happening and how I want it to look like. Needless to say that I could and did implement some performance improvements like caching underlying grid into a bitmap and whatnot, which is quite hard to achieve when you work with something as high-level as composition of layouts and views.
In any case you, or whoever is having the same issue, might want to start with something simple, like (code is off the top of my head):
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);
}
}
}
At a glance an amount of work needed to be done seems to be quite overwhelming, but it's not actually, if you first plan what you need to do and then do it. I went with something like this:
onDraw()
override, with all sizes and colors being hardcoded.onMeasure()
and onSizeChanged()
, start changing your size-controlling fields accordingly. I went with simple size determining where I take all available space width-wise and boldly require 24 * rowHeightPx
height-wise, regardless of measure specifications.onDraw()
having your previously defined structure and position calculation in place.onTouchEvent()
or something. Add some logging to see if you perform your hit tests correctly, start redrawing your event frames with highlighted colors if needed and whatnot.attrs.xml
, implement handling of those in your intialization code. Expose some custom listeners, like an EventClickedListener, or something.ScrollView
, I went with a ViewPager
to handle horizontal swipes and show previous/next day/week/month.And then just continue improving your control(s) until you and your teammates are happy with the result. Obviously, you'll need to constantly test, debug and fix your control on each step, so having a bunch of testcases is very helpful.
I also had some problems using standard Calendar API, when I was working on week and month overviews, so you might consider using other libraries, like Joda Time, but that's another story.