@Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
   super.onLayout(changed, l, t, r, b);
   if (changed && cells.size() > 0) {
     int size = (r - l) / 7;
     for (CheckableLayout cell : cells) {
       cell.getLayoutParams().height = size;
     }
   }
 }
  private void init(Context ctx) {
    if (isInEditMode()) return;
    View layout = LayoutInflater.from(ctx).inflate(R.layout.card_view, null, false);

    if (dateDisplay == null) dateDisplay = Calendar.getInstance();

    cardTitle = (TextView) layout.findViewById(R.id.cardTitle);
    cardGrid = (LinearLayout) layout.findViewById(R.id.cardGrid);

    cardTitle.setText(
        new SimpleDateFormat("MMM yyyy", Locale.getDefault()).format(dateDisplay.getTime()));

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    ((TextView) layout.findViewById(R.id.cardDay1))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));
    cal.add(Calendar.DAY_OF_WEEK, 1);
    ((TextView) layout.findViewById(R.id.cardDay2))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));
    cal.add(Calendar.DAY_OF_WEEK, 1);
    ((TextView) layout.findViewById(R.id.cardDay3))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));
    cal.add(Calendar.DAY_OF_WEEK, 1);
    ((TextView) layout.findViewById(R.id.cardDay4))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));
    cal.add(Calendar.DAY_OF_WEEK, 1);
    ((TextView) layout.findViewById(R.id.cardDay5))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));
    cal.add(Calendar.DAY_OF_WEEK, 1);
    ((TextView) layout.findViewById(R.id.cardDay6))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));
    cal.add(Calendar.DAY_OF_WEEK, 1);
    ((TextView) layout.findViewById(R.id.cardDay7))
        .setText(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()));

    LayoutInflater la = LayoutInflater.from(ctx);
    for (int y = 0; y < cardGrid.getChildCount(); y++) {
      LinearLayout row = (LinearLayout) cardGrid.getChildAt(y);
      for (int x = 0; x < row.getChildCount(); x++) {
        CheckableLayout cell = (CheckableLayout) row.getChildAt(x);
        cell.setOnClickListener(
            new OnClickListener() {
              @Override
              public void onClick(View v) {
                for (CheckableLayout c : cells) c.setChecked(false);
                ((CheckableLayout) v).setChecked(true);

                if (getOnCellItemClick() != null)
                  getOnCellItemClick().onCellClick(v, (CardGridItem) v.getTag()); // TODO
                // create
                // item
              }
            });

        View cellContent = la.inflate(itemLayout, cell, false);
        cell.addView(cellContent);
        cells.add(cell);
      }
    }

    addView(layout);

    mOnItemRenderDefault =
        new OnItemRender() {
          @Override
          public void onRender(CheckableLayout v, CardGridItem item) {
            ((TextView) v.getChildAt(0)).setText(item.getDayOfMonth().toString());
          }
        };
    layout
        .findViewById(R.id.iv_calendar_left)
        .setOnClickListener(
            new OnClickListener() {

              @Override
              public void onClick(View v) {
                // TODO Auto-generated method stub
                dateDisplay.add(Calendar.MONTH, -1);
                updateCells();
              }
            });
    layout
        .findViewById(R.id.iv_calendar_right)
        .setOnClickListener(
            new OnClickListener() {

              @Override
              public void onClick(View v) {
                // TODO Auto-generated method stub
                dateDisplay.add(Calendar.MONTH, 1);
                updateCells();
              }
            });
    updateCells();
  }
  private void updateCells() {
    Calendar cal;
    Integer counter = 0;
    if (dateDisplay != null) cal = (Calendar) dateDisplay.clone();
    else cal = Calendar.getInstance();

    cal.set(Calendar.DAY_OF_MONTH, 1);
    cardTitle.setText(new SimpleDateFormat("MMM yyyy", Locale.getDefault()).format(cal.getTime()));
    int daySpacing = getDaySpacing(cal.get(Calendar.DAY_OF_WEEK));

    // INFO : wrong calculations of first line - fixed
    if (daySpacing > 0) {
      Calendar prevMonth = (Calendar) cal.clone();
      prevMonth.add(Calendar.MONTH, -1);
      prevMonth.set(
          Calendar.DAY_OF_MONTH,
          prevMonth.getActualMaximum(Calendar.DAY_OF_MONTH) - daySpacing + 1);
      for (int i = 0; i < daySpacing; i++) {
        CheckableLayout cell = cells.get(counter);
        cell.setTag(
            new CardGridItem(Integer.valueOf(prevMonth.get(Calendar.DAY_OF_MONTH)))
                .setEnabled(false));
        cell.setEnabled(false);
        (mOnItemRender == null ? mOnItemRenderDefault : mOnItemRender)
            .onRender(cell, (CardGridItem) cell.getTag());
        counter++;
        prevMonth.add(Calendar.DAY_OF_MONTH, 1);
      }
    }

    int firstDay = cal.get(Calendar.DAY_OF_MONTH);
    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
    int lastDay = cal.get(Calendar.DAY_OF_MONTH) + 1;
    for (int i = firstDay; i < lastDay; i++) {
      cal.set(Calendar.DAY_OF_MONTH, i - 1);
      Calendar date = (Calendar) cal.clone();
      date.add(Calendar.DAY_OF_MONTH, 1);
      CheckableLayout cell = cells.get(counter);
      cell.setTag(new CardGridItem(i).setEnabled(true).setDate(date));
      cell.setEnabled(true);
      cell.setVisibility(View.VISIBLE);
      (mOnItemRender == null ? mOnItemRenderDefault : mOnItemRender)
          .onRender(cell, (CardGridItem) cell.getTag());
      counter++;
    }

    if (dateDisplay != null) cal = (Calendar) dateDisplay.clone();
    else cal = Calendar.getInstance();

    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));

    daySpacing = getDaySpacingEnd(cal.get(Calendar.DAY_OF_WEEK));

    if (daySpacing > 0) {
      for (int i = 0; i < daySpacing; i++) {
        CheckableLayout cell = cells.get(counter);
        cell.setTag(new CardGridItem(i + 1).setEnabled(false)); // .setDate((Calendar)cal.clone())
        cell.setEnabled(false);
        cell.setVisibility(View.VISIBLE);
        (mOnItemRender == null ? mOnItemRenderDefault : mOnItemRender)
            .onRender(cell, (CardGridItem) cell.getTag());
        counter++;
      }
    }

    if (counter < cells.size()) {
      for (int i = counter; i < cells.size(); i++) {
        cells.get(i).setVisibility(View.GONE);
      }
    }
  }