最近在公司的功能需求中,需要实现可以签到的日历,签到后在签到过的日期做标志。本功能参考了网上一些大神的日历控件,在此基础上进行修改,已满足本公司的需求,现已完成,记录一下。

布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@color/white"
 android:orientation="vertical">

 <LinearLayout
  android:id="@+id/i8show_attention_rl"
  android:layout_width="match_parent"
  android:layout_height="60dp"
  android:orientation="horizontal">

  <RelativeLayout
   android:layout_width="match_parent"
   android:layout_height="60dp"
   android:background="@color/white"
   android:gravity="center_vertical"
   android:padding="@dimen/I8d6">

   <ImageView
    android:id="@+id/i8show_attention_back"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:src="@drawable/i8live_nav_bcak" />

   <TextView
    android:id="@+id/i8show_attention_tittle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:ellipsize="end"
    android:gravity="center"
    android:singleLine="true"
    android:text="我的签到"
    android:textColor="@android:color/black"
    android:textSize="@dimen/i8_text_size_18" />

  </RelativeLayout>
 </LinearLayout>

 <RelativeLayout
  android:id="@+id/rl_current_date"
  android:layout_width="match_parent"
  android:layout_height="49dp"
  android:layout_below="@id/i8show_attention_rl">

  <TextView
   android:id="@+id/tv_sign_year_month"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerVertical="true"
   android:layout_marginLeft="60dp"
   android:text="2017年11月"
   android:textColor="#000000"
   android:textSize="17sp" />
 </RelativeLayout>

 <com.i8dayou.an.zb.userinfo.signcalendar.SignCalendar
  android:id="@+id/sc_main"
  android:layout_width="match_parent"
  android:layout_height="320dp"
  android:layout_below="@id/rl_current_date"
  android:layout_marginLeft="15dp"
  android:layout_marginRight="15dp"
  android:layout_marginTop="15dp"
  android:clickable="true"></com.i8dayou.an.zb.userinfo.signcalendar.SignCalendar>


 <RelativeLayout
  android:id="@+id/rl_btn_sign"
  android:layout_width="135dp"
  android:layout_height="49dp"
  android:layout_centerInParent="true"
  android:layout_marginBottom="50dp"
  android:layout_alignParentBottom="true"
  android:background="@drawable/btn_sign_calendar"
  android:orientation="horizontal">

  <TextView
   android:id="@+id/btn_sign"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerInParent="true"
   android:layout_marginLeft="15dp"
   android:layout_marginRight="15dp"
   android:text="签 到"
   android:textColor="#fff"
   android:textSize="17sp" />
 </RelativeLayout>

 <RelativeLayout
  android:id="@+id/rl_get_gift_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#dd000000"
  android:visibility="gone"
  android:clickable="false">

  <ImageView
   android:id="@+id/iv_huode"
   android:layout_width="229dp"
   android:layout_height="59dp"
   android:layout_centerHorizontal="true"
   android:layout_marginTop="120dp"
   android:src="@drawable/i8live_huoede" />

  <RelativeLayout
   android:id="@+id/rl_sun"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_below="@id/iv_huode"
   android:layout_centerHorizontal="true">

   <ImageView
    android:id="@+id/iv_sun_bg"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerInParent="true"
    android:src="@drawable/signed_on_rotate_bg" />

   <ImageView
    android:id="@+id/iv_sun"
    android:layout_width="98dp"
    android:layout_height="95dp"
    android:layout_centerInParent="true"
    android:src="@drawable/i8live_sun" />
  </RelativeLayout>


  <RelativeLayout
   android:id="@+id/rl_text_info"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_below="@id/rl_sun"
   android:layout_marginTop="10dp">

   <TextView
    android:id="@+id/tv_text_one"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:text="第一天签到可获得20个人气币,经验200,免费弹幕1次"
    android:textColor="#ffffff"
    android:textSize="13sp" />
  </RelativeLayout>

  <RelativeLayout
   android:id="@+id/rl_queding_btn"
   android:layout_width="218dp"
   android:layout_height="38dp"
   android:layout_below="@id/rl_text_info"
   android:layout_centerHorizontal="true"
   android:layout_marginTop="19dp"
   android:background="@drawable/online_get_gift_btn">

   <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="确定"
    android:textColor="#ffffff"
    android:textSize="16sp" />
  </RelativeLayout>
 </RelativeLayout>

</RelativeLayout>

主界面Activity代码:

public class SignCalendarActivity extends Activity {
 private SignCalendar calendar;
 private String date;
 private TextView btn_sign;
 private TextView tv_sign_year_month;
 private SignCalendarReq signCalendarReq;
 private SignCalendarReq.DataBean dataBean;
 List<String> list = new ArrayList<String>();
 private int month;
 private int year;
 private RelativeLayout rlGetGiftData;
 private TextView tvGetSunValue;
 private ImageView ivSun;
 private ImageView ivSunBg;
 private RelativeLayout rlQuedingBtn;
 private RelativeLayout rlBtnSign;
 private ImageView signBack;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_sign_calendar);

  //接收传递过来的初始化数据
  SignCalendarReq signCalendarReq = (SignCalendarReq) getIntent().getSerializableExtra("userInfos");

  month = Calendar.getInstance().get(Calendar.MONTH);
  year = Calendar.getInstance().get(Calendar.YEAR);

  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
  Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
  date = formatter.format(curDate);
  calendar = (SignCalendar) findViewById(R.id.sc_main);
  btn_sign = (TextView) findViewById(R.id.btn_sign);
  tv_sign_year_month = (TextView) findViewById(R.id.tv_sign_year_month);
  rlGetGiftData = (RelativeLayout) findViewById(R.id.rl_get_gift_view);
  tvGetSunValue = (TextView) findViewById(R.id.tv_text_one);
  ivSun = (ImageView) findViewById(R.id.iv_sun);
  ivSunBg = (ImageView) findViewById(R.id.iv_sun_bg);
  signBack = (ImageView) findViewById(R.id.i8show_attention_back);
  rlQuedingBtn = (RelativeLayout) findViewById(R.id.rl_queding_btn);
  rlBtnSign = (RelativeLayout) findViewById(R.id.rl_btn_sign);

  tv_sign_year_month.setText(year + "年" + (month + 1) + "月");//设置日期

  if (signCalendarReq != null) {
   if (signCalendarReq.getState().getCode() == 1) {
    dataBean = signCalendarReq.getData();
    String signDay = dataBean.getSignDay();
    String[] splitDay = signDay.split(",");
    for (int i = 0; i < splitDay.length; i++) {
     if (Integer.parseInt(splitDay[i]) < 10) {
      list.add(year + "-" + (month + 1) + "-0" + splitDay[i]);
     } else {
      list.add(year + "-" + (month + 1) + "-" + splitDay[i]);
     }
    }
    calendar.addMarks(list, 0);

    if (dataBean.getIsSign() == 1) {//1是已签到,0是未签到
     rlBtnSign.setBackgroundResource(R.drawable.btn_sign_calendar_no);
     btn_sign.setText("已签到");
     rlBtnSign.setClickable(false);
    } else {
     rlBtnSign.setBackgroundResource(R.drawable.btn_sign_calendar);
     btn_sign.setText("签 到");
    }
   }
  }

  btn_sign.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
    initSignCalendarData(2);//判断是否签到成功接口
   }
  });

  rlQuedingBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    rlGetGiftData.setVisibility(View.GONE);
   }
  });

  signBack.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    finish();
   }
  });
 }


 //点击签到按钮网络请求数据
 private void initSignCalendarData(int requestType) {
  Map<String, String> map = new HashMap<String, String>();
  map.put("uid", I8ShowSharePre.getHomeId(getApplicationContext()));
  map.put("token", I8ShowSharePre.getToken(getApplicationContext()));
  map.put("type", requestType + "");
  I8ShowHttpEngine.getInstance().postNotJson(I8ShowAppClient.QUERY_GET_SIGN_CALENDAR_RESULT, map, new I8ShowHttpEngine.Listener() {
   @Override
   public void onResponseSuccess(Object data) {
    Log.i("aaa", "签到数据:" + data.toString());
    IsSignSuccessReq isSignSuccessReq = new Gson().fromJson(data.toString(), IsSignSuccessReq.class);
    if (isSignSuccessReq.getState().getCode() == 1) {
     rlGetGiftData.setVisibility(View.VISIBLE);
     rlBtnSign.setBackgroundResource(R.drawable.btn_sign_calendar_no);
     btn_sign.setText("已签到");

     if (isSignSuccessReq.getData().getValueType() == 0) {//0是sun
      ivSun.setImageResource(R.drawable.i8live_sun);
      tvGetSunValue.setText("恭喜获得" + isSignSuccessReq.getData().getAddValue() + "个");
      I8ShowUserInfoSP.setSunValue(getApplicationContext(), isSignSuccessReq.getData().getAllValue());//保存领取礼物后的数据
     } else if ((isSignSuccessReq.getData().getValueType() == 1)) {//1是zuan
      ivSun.setImageResource(R.drawable.i8live_zuan_sign);
      tvGetSunValue.setText("恭喜获得" + isSignSuccessReq.getData().getAddValue() + "个");
      I8SP.setDiamonds(getApplicationContext(), isSignSuccessReq.getData().getAllValue());
     }

     Animation operatingAnim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotate_anim_online_gift);
     LinearInterpolator lin = new LinearInterpolator();
     operatingAnim.setInterpolator(lin);
     ivSunBg.startAnimation(operatingAnim);

     //list.add("2017-11-18");
     list.add(date);
     // calendar.setCalendarDaysBgColor(list,R.drawable.bg_sign_today);
     calendar.addMarks(list, 0);
    }
   }

   @Override
   public void onResponseFailed(String failedMsg) {
    Log.i("aaa", "签到数据:" + failedMsg);
   }
  });
 }
}

日历自定义控件代码:

public class SignCalendar extends ViewFlipper implements GestureDetector.OnGestureListener {
 public static final int COLOR_BG_WEEK_TITLE = Color.parseColor("#FF5959"); // 星期标题背景颜色
 public static final int COLOR_TX_WEEK_TITLE = Color.parseColor("#FFFFFF"); // 星期标题文字颜色
 public static final int BEFORE_TODAY_BACKGROUND = Color.parseColor("#FFE4E4E4"); // 星期标题文字颜色
 public static final int COLOR_TX_THIS_MONTH_DAY = Color.parseColor("#000000"); // 当前月日历数字颜色
 public static final int COLOR_TX_OTHER_MONTH_DAY = Color.parseColor("#ff999999"); // 其他月日历数字颜色
 public static final int COLOR_TX_THIS_DAY = Color.parseColor("#00ff00"); // 当天日历数字颜色
 public static final int COLOR_BG_THIS_DAY = Color.parseColor("#ffcccccc"); // 当天日历背景颜色
 public static final int COLOR_BG_CALENDAR = Color.parseColor("#FFFFFF"); // 日历背景色

 private GestureDetector gd; // 手势监听器
 private Animation push_left_in; // 动画-左进
 private Animation push_left_out; // 动画-左出
 private Animation push_right_in; // 动画-右进
 private Animation push_right_out; // 动画-右出

 private int ROWS_TOTAL = 6; // 日历的行数
 private int COLS_TOTAL = 7; // 日历的列数
 private String[][] dates = new String[6][7]; // 当前日历日期
 private float tb;

 private OnCalendarClickListener onCalendarClickListener; // 日历翻页回调
 private OnCalendarDateChangedListener onCalendarDateChangedListener; // 日历点击回调

 private String[] weekday = new String[] { "日", "一", "二", "三", "四", "五", "六" }; // 星期标题

 private int calendarYear; // 日历年份
 private int calendarMonth; // 日历月份
 private Date thisday = new Date(); // 今天
 private Date calendarday; // 日历这个月第一天(1号)

 private LinearLayout firstCalendar; // 第一个日历
 private LinearLayout secondCalendar; // 第二个日历
 private LinearLayout currentCalendar; // 当前显示的日历

 private Map<String, Integer> marksMap = new HashMap<String, Integer>(); // 储存某个日子被标注(Integer
 // 为bitmap
 // res
 // id)
 private Map<String, Integer> dayBgColorMap = new HashMap<String, Integer>(); // 储存某个日子的背景色

 public SignCalendar(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public SignCalendar(Context context) {
  super(context);
  init();
 }

 private void init() {
  setBackgroundColor(COLOR_BG_CALENDAR);
  // 实例化收拾监听器
  gd = new GestureDetector(this.getContext(), this);
  // 初始化日历翻动动画
  push_left_in = AnimationUtils.loadAnimation(getContext(), R.anim.anim_slice_in_left);
  push_left_out = AnimationUtils.loadAnimation(getContext(), R.anim.anim_slice_out_left);
  push_right_in = AnimationUtils.loadAnimation(getContext(), R.anim.anim_slice_in_right);
  push_right_out = AnimationUtils.loadAnimation(getContext(), R.anim.anim_slice_out_right);
  // 初始化第一个日历
  firstCalendar = new LinearLayout(getContext());
  firstCalendar.setOrientation(LinearLayout.VERTICAL);
  firstCalendar.setLayoutParams(new LinearLayout.LayoutParams(-1, -1));
  // 初始化第二个日历
  secondCalendar = new LinearLayout(getContext());
  secondCalendar.setOrientation(LinearLayout.VERTICAL);
  secondCalendar.setLayoutParams(new LinearLayout.LayoutParams(-1, -1));
  // 设置默认日历为第一个日历
  currentCalendar = firstCalendar;
  // 加入ViewFlipper
  addView(firstCalendar);
  addView(secondCalendar);
  // 绘制线条框架
  drawFrame(firstCalendar);
  drawFrame(secondCalendar);
  // 设置日历上的日子(1号)
  calendarYear = thisday.getYear() + 1900;
  calendarMonth = thisday.getMonth();
  calendarday = new Date(calendarYear - 1900, calendarMonth, 1);
  // 填充展示日历
  setCalendarDate();
 }

 private void drawFrame(LinearLayout oneCalendar) {
  // 添加周末线性布局
  LinearLayout title = new LinearLayout(getContext());
  title.setBackgroundColor(COLOR_BG_WEEK_TITLE);
  title.setOrientation(LinearLayout.HORIZONTAL);
  LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(MarginLayoutParams.MATCH_PARENT,
    MarginLayoutParams.WRAP_CONTENT, 0.5f);
  Resources res = getResources();
  tb = res.getDimension(R.dimen.activity_horizontal_margin);
  // layout.setMargins(0, 0, 0, (int) (tb * 1.2));
  title.setLayoutParams(layout);
  oneCalendar.addView(title);

  // 添加周末TextView
  for (int i = 0; i < COLS_TOTAL; i++) {
   TextView view = new TextView(getContext());
   view.setGravity(Gravity.CENTER);
   view.setPadding(0, 10, 0, 10);
   view.setText(weekday[i]);
   view.setTextColor(Color.WHITE);
   view.setLayoutParams(new LinearLayout.LayoutParams(0, -1, 1));
   title.addView(view);
  }

  // 添加日期布局
  LinearLayout content = new LinearLayout(getContext());
  content.setOrientation(LinearLayout.VERTICAL);
  content.setLayoutParams(new LinearLayout.LayoutParams(-1, 0, 7f));
  oneCalendar.addView(content);

  // 添加日期TextView
  for (int i = 0; i < ROWS_TOTAL; i++) {
   LinearLayout row = new LinearLayout(getContext());
   row.setOrientation(LinearLayout.HORIZONTAL);
   row.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
   content.addView(row);
   // 绘制日历上的列
   for (int j = 0; j < COLS_TOTAL; j++) {
    RelativeLayout col = new RelativeLayout(getContext());
    col.setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1));
    //col.setBackgroundResource(R.drawable.bg);
    // col.setBackgroundResource(R.drawable.sign_dialog_day_bg);
    col.setClickable(false);
    row.addView(col); // 给每一个日子加上监听
    col.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
      ViewGroup parent = (ViewGroup) v.getParent();
      int row = 0, col = 0;

      // 获取列坐标
      for (int i = 0; i < parent.getChildCount(); i++) {
       if (v.equals(parent.getChildAt(i))) {
        col = i;
        break;
       }
      }
      // 获取行坐标
      ViewGroup pparent = (ViewGroup) parent.getParent();
      for (int i = 0; i < pparent.getChildCount(); i++) {
       if (parent.equals(pparent.getChildAt(i))) {
        row = i;
        break;
       }
      }
      if (onCalendarClickListener != null) {
       onCalendarClickListener.onCalendarClick(row, col, dates[row][col]);
      }
     }
    });
   }
  }
 }

 /**
  * 填充日历(包含日期、标记、背景等)
  */
 private void setCalendarDate() {
  // 根据日历的日子获取这一天是星期几
  int weekday = calendarday.getDay();
  // 每个月第一天
  int firstDay = 1;
  // 每个月中间号,根据循环会自动++
  int day = firstDay;
  // 每个月的最后一天
  int lastDay = getDateNum(calendarday.getYear(), calendarday.getMonth());
  // 下个月第一天
  int nextMonthDay = 1;
  int lastMonthDay = 1;

  // 填充每一个空格
  for (int i = 0; i < ROWS_TOTAL; i++) {
   for (int j = 0; j < COLS_TOTAL; j++) {
    // 这个月第一天不是礼拜天,则需要绘制上个月的剩余几天
    if (i == 0 && j == 0 && weekday != 0) {
     int year = 0;
     int month = 0;
     int lastMonthDays = 0;
     // 如果这个月是1月,上一个月就是去年的12月
     if (calendarday.getMonth() == 0) {
      year = calendarday.getYear() - 1;
      month = Calendar.DECEMBER;
     } else {
      year = calendarday.getYear();
      month = calendarday.getMonth() - 1;
     }
     // 上个月的最后一天是几号
     lastMonthDays = getDateNum(year, month);
     // 第一个格子展示的是几号
     int firstShowDay = lastMonthDays - weekday + 1;
     // 上月
     for (int k = 0; k < weekday; k++) {
      lastMonthDay = firstShowDay + k;
      RelativeLayout group = getDateView(0, k);
      group.setGravity(Gravity.TOP);
      TextView view = null;
      if (group.getChildCount() > 0) {
       view = (TextView) group.getChildAt(0);
      } else {
       LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, -1);
       view = new TextView(getContext());
       view.setLayoutParams(params);
       view.setGravity(Gravity.CENTER);
       group.addView(view);
      }
      view.setText(Integer.toString(lastMonthDay));
      view.setTextColor(COLOR_TX_OTHER_MONTH_DAY);
      dates[0][k] = format(new Date(year, month, lastMonthDay));
      // 设置日期背景色
      if (dayBgColorMap.get(dates[0][k]) != null) {
       view.setBackgroundResource(dayBgColorMap.get(dates[0][k]));
      } else {
       view.setBackgroundColor(Color.TRANSPARENT);
      }
      // 设置标记
      setMarker(group, 0, k);
     }
     j = weekday - 1;
     // 这个月第一天是礼拜天,不用绘制上个月的日期,直接绘制这个月的日期
    } else {
     RelativeLayout group = getDateView(i, j);
     group.setGravity(Gravity.TOP);
     TextView view = null;
     if (group.getChildCount() > 0) {
      view = (TextView) group.getChildAt(0);
     } else {
      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, -1);
      view = new TextView(getContext());
      view.setLayoutParams(params);
      view.setGravity(Gravity.CENTER);
      group.addView(view);
     }

     // 本月
     if (day <= lastDay) {
      dates[i][j] = format(new Date(calendarday.getYear(), calendarday.getMonth(), day));
      view.setText(Integer.toString(day));
      // 当天
      if (thisday.getDate() == day && thisday.getMonth() == calendarday.getMonth()
        && thisday.getYear() == calendarday.getYear()) {
       // view.setText("今天");
       view.setTextColor(COLOR_TX_THIS_DAY);
       // view.setBackgroundResource(R.drawable.bg_sign_today);
      } else if (thisday.getMonth() == calendarday.getMonth()
        && thisday.getYear() == calendarday.getYear()) {
       // 绘制本月的颜色
       view.setTextColor(COLOR_TX_THIS_MONTH_DAY);
      } else {
       // 其他日期
       view.setTextColor(COLOR_TX_OTHER_MONTH_DAY);
      }
      // 上面首先设置了一下默认的"当天"背景色,当有特殊需求时,才给当日填充背景色
      // 设置日期背景色
      if (dayBgColorMap.get(dates[i][j]) != null) {
       // view.setTextColor(Color.WHITE);
       // view.setBackgroundResource(dayBgColorMap.get(dates[i][j]));
      }
      // 设置标记
      setMarker(group, i, j);
      day++;
      // 下个月
     } else {
      if (calendarday.getMonth() == Calendar.DECEMBER) {
       dates[i][j] = format(new Date(calendarday.getYear() + 1, Calendar.JANUARY, nextMonthDay));
      } else {
       dates[i][j] = format(
         new Date(calendarday.getYear(), calendarday.getMonth() + 1, nextMonthDay));
      }
      view.setText(Integer.toString(nextMonthDay));
      view.setTextColor(COLOR_TX_OTHER_MONTH_DAY);
      // 设置日期背景色
      if (dayBgColorMap.get(dates[i][j]) != null) {
       // view.setBackgroundResource(dayBgColorMap
       // .get(dates[i][j]));
      } else {
       view.setBackgroundColor(Color.TRANSPARENT);
      }
      // 设置标记
      setMarker(group, i, j);
      nextMonthDay++;
     }
    }
   }
  }
 }

 /**
  * onClick接口回调
  */
 public interface OnCalendarClickListener {
  void onCalendarClick(int row, int col, String dateFormat);
 }

 /**
  * ondateChange接口回调
  */
 public interface OnCalendarDateChangedListener {
  void onCalendarDateChanged(int year, int month);
 }

 /**
  * 根据具体的某年某月,展示一个日历
  *
  * @param year
  * @param month
  */
 public void showCalendar(int year, int month) {
  calendarYear = year;
  calendarMonth = month - 1;
  calendarday = new Date(calendarYear - 1900, calendarMonth, 1);
  setCalendarDate();
 }

 /**
  * 根据当前月,展示一个日历
  *
  */
 public void showCalendar() {
  Date now = new Date();
  calendarYear = now.getYear() + 1900;
  calendarMonth = now.getMonth();
  calendarday = new Date(calendarYear - 1900, calendarMonth, 1);
  setCalendarDate();
 }

 /**
  * 下一月日历
  */
 public synchronized void nextMonth() {
  // 改变日历上下顺序
  if (currentCalendar == firstCalendar) {
   currentCalendar = secondCalendar;
  } else {
   currentCalendar = firstCalendar;
  }
  // 设置动画
  setInAnimation(push_left_in);
  setOutAnimation(push_left_out);
  // 改变日历日期
  if (calendarMonth == Calendar.DECEMBER) {
   calendarYear++;
   calendarMonth = Calendar.JANUARY;
  } else {
   calendarMonth++;
  }
  calendarday = new Date(calendarYear - 1900, calendarMonth, 1);
  // 填充日历
  setCalendarDate();
  // 下翻到下一月
  showNext();
  // 回调
  if (onCalendarDateChangedListener != null) {
   onCalendarDateChangedListener.onCalendarDateChanged(calendarYear, calendarMonth + 1);
  }
 }

 /**
  * 上一月日历
  */
 public synchronized void lastMonth() {
  if (currentCalendar == firstCalendar) {
   currentCalendar = secondCalendar;
  } else {
   currentCalendar = firstCalendar;
  }
  setInAnimation(push_right_in);
  setOutAnimation(push_right_out);
  if (calendarMonth == Calendar.JANUARY) {
   calendarYear--;
   calendarMonth = Calendar.DECEMBER;
  } else {
   calendarMonth--;
  }
  calendarday = new Date(calendarYear - 1900, calendarMonth, 1);
  setCalendarDate();
  showPrevious();
  if (onCalendarDateChangedListener != null) {
   onCalendarDateChangedListener.onCalendarDateChanged(calendarYear, calendarMonth + 1);
  }
 }

 /**
  * 获取日历当前年份
  */
 public int getCalendarYear() {
  return calendarday.getYear() + 1900;
 }

 /**
  * 获取日历当前月份
  */
 public int getCalendarMonth() {
  return calendarday.getMonth() + 1;
 }

 /**
  * 在日历上做一个标记
  *
  * @param date
  *   日期
  * @param id
  *   bitmap res id
  */
 public void addMark(Date date, int id) {
  addMark(format(date), id);
 }

 /**
  * 在日历上做一个标记
  *
  * @param date
  *   日期
  * @param id
  *   bitmap res id
  */
 public void addMark(String date, int id) {
  marksMap.put(date, id);
  setCalendarDate();
 }

 /**
  * 在日历上做一组标记
  *
  * @param date
  *   日期
  * @param id
  *   bitmap res id
  */
 public void addMarks(Date[] date, int id) {
  for (int i = 0; i < date.length; i++) {
   marksMap.put(format(date[i]), id);
  }
  setCalendarDate();
 }

 /**
  * 在日历上做一组标记
  *
  * @param date
  *   日期
  * @param id
  *   bitmap res id
  */
 public void addMarks(List<String> date, int id) {
  for (int i = 0; i < date.size(); i++) {
   marksMap.put(date.get(i), id);
  }
  setCalendarDate();
 }

 /**
  * 移除日历上的标记
  */
 public void removeMark(Date date) {
  removeMark(format(date));
 }

 /**
  * 移除日历上的标记
  */
 public void removeMark(String date) {
  marksMap.remove(date);
  setCalendarDate();
 }

 /**
  * 移除日历上的所有标记
  */
 public void removeAllMarks() {
  marksMap.clear();
  setCalendarDate();
 }

 /**
  * 设置日历具体某个日期的背景色
  *
  * @param date
  * @param color
  */
 public void setCalendarDayBgColor(Date date, int color) {
  setCalendarDayBgColor(format(date), color);
 }

 /**
  * 设置日历具体某个日期的背景色
  *
  * @param date
  * @param color
  */
 public void setCalendarDayBgColor(String date, int color) {
  dayBgColorMap.put(date, color);
  setCalendarDate();
 }

 /**
  * 设置日历一组日期的背景色
  *
  * @param date
  * @param color
  */
 public void setCalendarDaysBgColor(List<String> date, int color) {
  for (int i = 0; i < date.size(); i++) {
   dayBgColorMap.put(date.get(i), color);
  }
  setCalendarDate();
 }

 /**
  * 设置日历一组日期的背景色
  *
  * @param date
  * @param color
  */
 public void setCalendarDayBgColor(String[] date, int color) {
  for (int i = 0; i < date.length; i++) {
   dayBgColorMap.put(date[i], color);
  }
  setCalendarDate();
 }

 /**
  * 移除日历具体某个日期的背景色
  *
  * @param date
  */
 public void removeCalendarDayBgColor(Date date) {
  removeCalendarDayBgColor(format(date));
 }

 /**
  * 移除日历具体某个日期的背景色
  *
  * @param date
  */
 public void removeCalendarDayBgColor(String date) {
  dayBgColorMap.remove(date);
  setCalendarDate();
 }

 /**
  * 移除日历具体某个日期的背景色
  *
  */
 public void removeAllBgColor() {
  dayBgColorMap.clear();
  setCalendarDate();
 }

 /**
  * 根据行列号获得包装每一个日子的LinearLayout
  *
  * @param row
  * @param col
  * @return
  */
 public String getDate(int row, int col) {
  return dates[row][col];
 }

 /**
  * 某天是否被标记了
  *
  * @return
  */
 public boolean hasMarked(String date) {
  return marksMap.get(date) == null ? false : true;
 }

 /**
  * 清除所有标记以及背景
  */
 public void clearAll() {
  marksMap.clear();
  dayBgColorMap.clear();
 }

 /***********************************************
  * private methods
  **********************************************/
 // 设置标记
 private void setMarker(RelativeLayout group, int i, int j) {
  int childCount = group.getChildCount();
  // dates[i][j]=2015-12-20等为要对比的日期,marksMap中包括了dates[i][j]时就进入下面的if语句
  if (marksMap.get(dates[i][j]) != null) {
   if (childCount < 2) {
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) (tb * 2), (int) (tb * 2));
    // params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    // params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    params.setMargins(0, 0, 1, 1);
    params.addRule(RelativeLayout.CENTER_IN_PARENT);
    ImageView markView = new ImageView(getContext());
    markView.setImageResource(marksMap.get(dates[i][j]));
    markView.setLayoutParams(params);

    //标记图片 可自定义
    //markView.setBackgroundResource(R.drawable.calendar_bg_tag);
    markView.setBackgroundResource(R.drawable.i8live_signin);

    group.addView(markView);
   }
  } else {
   if (childCount > 1) {
    group.removeView(group.getChildAt(1));
   }
  }
 }

 /**
  * 计算某年某月有多少天
  *
  * @param year
  * @param month
  * @return
  */
 private int getDateNum(int year, int month) {
  Calendar time = Calendar.getInstance();
  time.clear();
  time.set(Calendar.YEAR, year + 1900);
  time.set(Calendar.MONTH, month);
  return time.getActualMaximum(Calendar.DAY_OF_MONTH);
 }

 /**
  * 根据行列号获得包装每一个日子的LinearLayout
  *
  * @param row
  * @param col
  * @return
  */
 private RelativeLayout getDateView(int row, int col) {
  return (RelativeLayout) ((LinearLayout) ((LinearLayout) currentCalendar.getChildAt(1)).getChildAt(row))
    .getChildAt(col);
 }

 /**
  * 将Date转化成字符串->2013-3-3
  */
 private String format(Date d) {
  return addZero(d.getYear() + 1900, 4) + "-" + addZero(d.getMonth() + 1, 2) + "-" + addZero(d.getDate(), 2);
 }

 // 2或4
 private static String addZero(int i, int count) {
  if (count == 2) {
   if (i < 10) {
    return "0" + i;
   }
  } else if (count == 4) {
   if (i < 10) {
    return "000" + i;
   } else if (i < 100 && i > 10) {
    return "00" + i;
   } else if (i < 1000 && i > 100) {
    return "0" + i;
   }
  }
  return "" + i;
 }

 /***********************************************
  * Override methods
  **********************************************/
 public boolean dispatchTouchEvent(MotionEvent ev) {
  if (gd != null) {
   if (gd.onTouchEvent(ev))
    return true;
  }
  return super.dispatchTouchEvent(ev);
 }

 public boolean onTouchEvent(MotionEvent event) {
  return this.gd.onTouchEvent(event);
 }

 public boolean onDown(MotionEvent e) {
  return false;
 }

 public void onShowPress(MotionEvent e) {
 }

 public boolean onSingleTapUp(MotionEvent e) {
  return false;
 }

 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
  return false;
 }

 public void onLongPress(MotionEvent e) {
 }

 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  // 向左/上滑动
  if (e1.getX() - e2.getX() > 20) {
   // nextMonth();
  }
  // 向右/下滑动
  else if (e1.getX() - e2.getX() < -20) {
   // lastMonth();
  }
  return false;
 }

 /***********************************************
  * get/set methods
  **********************************************/

 public OnCalendarClickListener getOnCalendarClickListener() {
  return onCalendarClickListener;
 }

 public void setOnCalendarClickListener(OnCalendarClickListener onCalendarClickListener) {
  this.onCalendarClickListener = onCalendarClickListener;
 }

 public OnCalendarDateChangedListener getOnCalendarDateChangedListener() {
  return onCalendarDateChangedListener;
 }

 public void setOnCalendarDateChangedListener(OnCalendarDateChangedListener onCalendarDateChangedListener) {
  this.onCalendarDateChangedListener = onCalendarDateChangedListener;
 }

 public Date getThisday() {
  return thisday;
 }

 public void setThisday(Date thisday) {
  this.thisday = thisday;
 }

 public Map<String, Integer> getDayBgColorMap() {
  return dayBgColorMap;
 }

 public void setDayBgColorMap(Map<String, Integer> dayBgColorMap) {
  this.dayBgColorMap = dayBgColorMap;
 }
}

运行的效果图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

02-02 22:27