Android可签到日历控件的实现方法

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

布局文件:

<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; 
  } 
} 

运行的效果图:

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

代码技巧

转载请关注公众号:代码技巧 回复:授权

本文链接地址:http://www.oudahe.com/p/54523/