2013-07-17 10 views
7

Wykonuję niestandardowy kalendarz w Androidzie. Moim wymaganiem jest, aby dokonać wyboru wielu dat tak jak pokazano na obrazku. Każdy ma jakąkolwiek sugestię. Do tej pory robię kalendarz na widoku i próbuję narysować ścieżkę zgodnie z dotykiem, ale to nie działa dla mnie. tu jest mój kodu: -Jak wybrać wiele dat w niestandardowym kalendarzu?

public class CalendarView extends View { 

private float width; // width of one tile 
private float height; // height of one tile 
private int selX; // X index of selection 
private int selY; // Y index of selection 
private final Rect selRect = new Rect(); 
private GregorianCalendar month, itemmonth;// calendar instances. 
private CalendarAdapter adapter;// adapter instance 
private Context mContext ; 
private GregorianCalendar pmonthmaxset; 
private GregorianCalendar selectedDate; 
private ArrayList<String> items; 
private List<String> dayString; 
private GregorianCalendar pmonth; // calendar instance for previous month 
/** 
* calendar instance for previous month for getting complete view 
*/ 
private int firstDay; 
private int maxWeeknumber; 
private int maxP; 
private int calMaxP; 
private int lastWeekDay; 
private int leftDays; 
private int mnthlength; 
private String itemvalue, curentDateString; 
private DateFormat df; 
private Canvas macanvas; 
private Path mpath; 
private float cselX; // X index of selection 
private float cselY; // Y index of selection 

public CalendarView(Context context) { 
    super(context); 

    mpath = new Path(); 
    RectF mrectf = new RectF(selRect); 
    //mpath.ad 

    month = (GregorianCalendar) GregorianCalendar.getInstance(); 
    itemmonth = (GregorianCalendar) month.clone(); 
    Locale.setDefault(Locale.US); 
    selectedDate = (GregorianCalendar) month.clone(); 
    mContext = context; 
    month.set(GregorianCalendar.DAY_OF_MONTH, 1); 
    this.items = new ArrayList<String>(); 
    df = new SimpleDateFormat("yyyy-MM-dd", Locale.US); 
    curentDateString = df.format(selectedDate.getTime()); 
    dayString= new ArrayList<String>(); 
    macanvas = new Canvas(); 
    refreshDays(); 


} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    width = w/7f; 
    height = (w)/(7f); 
    getRect(selX, selY, selRect); 
    super.onSizeChanged(w, h, oldw, oldh); 
} 

@Override 
protected void onDraw(Canvas canvas) { 

    // Draw the background... 
     Paint background = new Paint(); 
     background.setColor(Color.GRAY); 
     canvas.drawRect(0, 0, getWidth(), getHeight(), background); 


     // Draw the board... 

     // Define colors for the grid lines 
     Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG); 
     foreground.setColor(Color.RED); 
     Paint dark = new Paint(); 
     dark.setColor(Color.BLUE); 
     Paint hilite = new Paint(); 
     hilite.setColor(Color.BLUE); 
     Paint light = new Paint(); 
     light.setColor(Color.BLUE); 
     // Draw the minor grid lines 
     for (int i = 0; i < 6; i++) { 
     canvas.drawLine(0, i * height, getWidth(), i * height, 
       light); 
     canvas.drawLine(0, i * height + 1, getWidth(), i * height 
        + 1, hilite); 

     } 
     for (int i = 0; i < 8; i++) { 

      canvas.drawLine(i * width, 0, i * width,width*5, 
        light); 
      canvas.drawLine(i * width+1, 0, i * width+1,width*5, 
        light); 
    } 

     foreground.setColor(Color.RED); 
     foreground.setStyle(Style.FILL); 
     foreground.setTextSize(height * 0.75f); 
     foreground.setTextScaleX(width/height); 
     foreground.setTextAlign(Paint.Align.CENTER); 

     // Draw the number in the center of the tile 
     FontMetrics fm = foreground.getFontMetrics(); 
     // Centering in X: use alignment (and X at midpoint) 
     float x = width/2; 
     // Centering in Y: measure ascent/descent first 
     float y = height/2 - (fm.ascent + fm.descent)/2; 

    int k =0; 
    for (int i = 0; i < 7; i++) { 
     for (int j = 0; j < 5; j++) { 
      String datevalue = fillDate(k++); 
      canvas.drawText(datevalue, i 
        * width + x, j * height + y, foreground); 

     } 
     } 

    if(mpath!=null) 
    { 
     Paint selected = new Paint(); 
     selected.setColor(Color.GREEN); 
     canvas.drawPath(mpath,selected); 
     // canvas.drawCircle(x, y, 25, selected); 
    } 

    super.onDraw(canvas); 
} 

private void getRect(int x, int y, Rect rect) { 
     rect.set((int) (x * width), (int) (y * height), (int) (x 
      * width + width), (int) (y * height + height)); 
    } 

public String fillDate(int index) 
{ 
    String date = ""; 

     // separates daystring into parts. 
     String[] separatedTime = dayString.get(index).split("-"); 
     // taking last part of date. ie; 2 from 2012-12-02 
     String gridvalue = separatedTime[2].replaceFirst("^0*", ""); 
     // checking whether the day is in current month or not. 
     if ((Integer.parseInt(gridvalue) > 1) && (index < firstDay)) { 
      // setting offdays to white color. 
      //dayView.setTextColor(Color.WHITE); 
      //dayView.setClickable(false); 
      //dayView.setFocusable(false); 
     } 
     else if ((Integer.parseInt(gridvalue) < 7) && (index > 28)) { 
      //dayView.setTextColor(Color.WHITE); 
      //dayView.setClickable(false); 
      //dayView.setFocusable(false); 
     } else { 
      // setting curent month's days in blue color. 
      //dayView.setTextColor(Color.BLUE); 
     } 

     if (dayString.get(index).equals(curentDateString)) { 
      //setSelected(v); 
      //previousView = v; 
     } else { 
      //v.setBackgroundResource(R.drawable.list_item_background); 
     } 

    return gridvalue; 

} 

public void refreshDays() { 
    // clear items 
    items.clear(); 
    dayString.clear(); 
    Locale.setDefault(Locale.US); 
    pmonth = (GregorianCalendar) month.clone(); 
    // month start day. ie; sun, mon, etc 
    firstDay = month.get(GregorianCalendar.DAY_OF_WEEK); 
    // finding number of weeks in current month. 
    maxWeeknumber = month.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH); 
    // allocating maximum row number for the gridview. 
    mnthlength = maxWeeknumber * 7; 
    maxP = getMaxP(); // previous month maximum day 31,30.... 
    calMaxP = maxP - (firstDay - 1);// calendar offday starting 24,25 ... 
    /** 
    * Calendar instance for getting a complete gridview including the three 
    * month's (previous,current,next) dates. 
    */ 
    pmonthmaxset = (GregorianCalendar) pmonth.clone(); 
    /** 
    * setting the start date as previous month's required date. 
    */ 
    pmonthmaxset.set(GregorianCalendar.DAY_OF_MONTH, calMaxP + 1); 

    /** 
    * filling calendar gridview. 
    */ 
    for (int n = 0; n < mnthlength; n++) { 

     itemvalue = df.format(pmonthmaxset.getTime()); 
     pmonthmaxset.add(GregorianCalendar.DATE, 1); 
     dayString.add(itemvalue); 

    } 
} 

private int getMaxP() { 
    int maxP; 
    if (month.get(GregorianCalendar.MONTH) == month 
      .getActualMinimum(GregorianCalendar.MONTH)) { 
     pmonth.set((month.get(GregorianCalendar.YEAR) - 1), 
       month.getActualMaximum(GregorianCalendar.MONTH), 1); 
    } else { 
     pmonth.set(GregorianCalendar.MONTH, 
       month.get(GregorianCalendar.MONTH) - 1); 
    } 
    maxP = pmonth.getActualMaximum(GregorianCalendar.DAY_OF_MONTH); 

    return maxP; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    switch(event.getAction()) 
    { 

    case MotionEvent.ACTION_DOWN: 
     //select((int) (event.getX()/width), 
        // (int) (event.getY()/height)); 
      mpath.moveTo(event.getX(), event.getY()); 
      mpath.lineTo(event.getX(), event.getY()); 

     break; 
    case MotionEvent.ACTION_MOVE: 
     invalidate(); 
     cselX = event.getX(); 
     cselY = event.getY(); 
     mpath.lineTo(cselX,cselY); 
     break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_CANCEL: 
     break; 

    } 
    return true; 
} 

private void select(int x, int y) { 
    selX = Math.min(Math.max(x, 0), 8); 
    selY = Math.min(Math.max(y, 0), 8); 
    getRect(selX, selY, selRect); 

     invalidate(selRect); 
    } 

}

+0

Sprawdź muliple data wybrać [@github] (https://github.com/square/android-times-square/tree/master/sample) – shailesh

+0

problem nie jest wielokrotnością data wybór problemem jest to, jak pokazać jak na powyższym obrazku. –

Odpowiedz

-1

można odznaczyć datę, dodać do tablicy, a następnie użytkownik może wybrać 2nd datę ...

+0

To nie jest odpowiedź na pytanie i ogólnie zły UX. – bluewhile

-1

Z mojej bibliotece, można wybrać jedną datę, ale ustawione daty wydarzeń. Lubi wielokrotny wybór.

MFCalendarView