0

I am building an "Day View" calendar app. I have already created the empty calendar with a List View, and now need to add my appointments.

My cursor is all setup and I am able to retrieve my appointments, just need to draw them on the List View. The tricky part is that each list row is 30 minutes and some of my appointments may go longer, up to several hours. So need to be able to specify where on the List View the appointment should be drawn, even if it's currently off the screen.

Lucifer
  • 29,392
  • 25
  • 90
  • 143
dbDev
  • 1,553
  • 1
  • 15
  • 22

2 Answers2

2

I did the same kind of view. I developed my own CustomView and kept it in a ScrollView. This customView's height is 24 * 60 dip. So the height of the view will be increased as we kept dip instead of px (I hope you know difference between the px and dip) and the width will be the width of the device screen.

I can't share you the complete code. But, can partially paste here. This will bring you a clear picture handling every thing.

public class CustomDayView extends View implements OnTouchListener{

    private Paint p;
    private Paint textp;
    private Paint roundRectP;
    private int parentWidth = 0;
    private int parentHeight = 0;
    private int X_OFFSET = 5;
    private int Y_OFFSET = 5;
    private int HOUR_BLOCK_HEIGHT = 60;
    private int font_max_width;
    private ScrollView _scrollView;
    private int least_time_in_hours = 24*60;//6 * 60
    private RectF _rects[];
    private int font_height;
    private Context context;


    public CustomDayEmployeeView(Context context) {
        super(context);
        this.context = context;
        init();
    }
    public CustomDayEmployeeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }
    public CustomDayEmployeeView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }
     private void init(){
         //Creating Paint Objects
     //setting color
         //setting Fonts
         this.setOnTouchListener(this);
     calculateRectValues();
     }

    private void calculateRectValues() {
        // Calculating the Rects to draw in the paint this includes x,y points starting of the rect and width and height of the rectangle.
    int font_max_width = calculate the width needed to draw the hours from 0 to 24 hours;
    for(int i=0;i<no of appts;i++)
        _rects[j] = new RectF(font_max_width, convertTimetoSeconds("09:30"), screenwidth-font_max_width , convertTimetoSeconds("11:30");

    }

    private int convertTimetoSeconds(String _startTime) {
        // TODO Auto-generated method stub
        int total = Integer.parseInt(_startTime.substring(0,_startTime.indexOf(":"))) * 60;
        total += Integer.parseInt(_startTime.substring(_startTime.indexOf(":")+1, _startTime.length()));
        return total;
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        calculateRectValues();
        setMeasuredDimension(screenwidth,24 * HOUR_BLOCK_HEIGHT);
    }


    public void draw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.draw(canvas);

        for(int i=0;i<25;i++)
        {
            String preString = "";
            String poststring = "";

            if(i == 12)
            {
                preString = "Noon";
                poststring = "";

            }
            else if(i%12 == 0)
            {
                preString = "12";
                poststring = " AM";
            }
            else if(i<12)
            {
                preString = i+"";
                poststring = " AM";
            }
            else
            {
                preString = i%12+"";
                poststring = " PM";
            }
            canvas.drawText(preString, X_OFFSET+3, i * HOUR_BLOCK_HEIGHT + font_height, p);
            canvas.drawText(poststring, X_OFFSET+p.measureText(preString), i * HOUR_BLOCK_HEIGHT + font_height, p);
            p.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
            p.setColor(Color.parseColor("#cbcaca"));
            p.setStrokeWidth(0.2f);
            p.setPathEffect(new DashPathEffect(new float[] {1,2}, 0));
            canvas.drawLine(font_max_width, i * (HOUR_BLOCK_HEIGHT)+ font_height/2+HOUR_BLOCK_HEIGHT/2, parentWidth-8, i * (HOUR_BLOCK_HEIGHT)+ font_height/2+HOUR_BLOCK_HEIGHT/2, p);
            p.setColor(Color.parseColor("#f1f1f1"));
            p.setPathEffect(new PathEffect());
            p.setStrokeWidth(0.2f);
            canvas.drawLine(font_max_width, i * HOUR_BLOCK_HEIGHT+ font_height/2, parentWidth-8, i * HOUR_BLOCK_HEIGHT+ font_height/2, p);

        }
            for(int j=0;j<no of appts;j++)
            {
                    canvas.drawRoundRect(_rects[j], 3, 3, roundRectP);
                        canvas.drawText(obj._title, _rects[j].left+X_OFFSET,_rects[j].top + font_height + Y_OFFSET, textp);
            }
        }
    }


    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        int x = (int) event.getX();
        int y = (int) event.getY();
        for(int j=0;j<no of appts;j++)
        {
            if(_rects[j].contains(x, y))
            {
        //Selected J appointmrnt
        }
        }
        return true;
    }
}

I think this will help you. Just create Object and pass you appointments in an ArrayList to init of this object and do the tweaks that you need to it.

Pavandroid
  • 1,586
  • 2
  • 15
  • 30
  • thank you very much for the code, it is helping. One question, I see you declare a ScrollView, but when do you use it? – dbDev Mar 21 '12 at 15:14
  • Actually i had a problem in my project. I need to scroll the view to the first appointment visible on this view. So, in order scroll, i send the scrollview's object from the MainActivity to this CustomDayView. after that i make it global to make use of that to scroll to any x,y points through out the CustomView. – Pavandroid Mar 21 '12 at 15:21
  • Any update? If am correct please select this as the correct answer. – Pavandroid Mar 22 '12 at 01:36
  • Pavandroid, this example was very helpful and I used it as a guide as I built my first custom view. I'm now working on my third custom view for my app and will likely use custom views more often than not. So much more flexibility! Thanks! – dbDev Mar 25 '12 at 05:42
  • @ Pavandroid. I am looking for the same thing. I like know, where I can find the working example for drawing events over the listview I used to show the daily events. – Manikandan Aug 13 '12 at 15:59
-1

You don't need to draw anything if it's off the screen.

I would implement the list adapter this way: getItem(int position) method returns the time (time interval, actually) each list item represents. getView(int position, View convertView, ViewGroup parent) defines which appointments are within the interval of correspondent item at the given position, and updates the item's view basing on this information.

You may also need an endless adapter.

Community
  • 1
  • 1
a.ch.
  • 8,285
  • 5
  • 40
  • 53