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

作者:龙旋 时间:2023-11-18 15:11:28 

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

布局文件:


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

运行的效果图:

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

来源:https://blog.csdn.net/longxuanzhigu/article/details/78625132

标签:Android,日历控件,签到
0
投稿

猜你喜欢

  • springmvc实现自定义类型转换器示例

    2021-09-29 23:46:53
  • flutter ExpansionTile 层级菜单的实现

    2023-06-15 16:04:01
  • Android传递Bitmap对象在两个Activity之间

    2023-09-01 22:30:17
  • C#使用WebSocket与网页实时通信的实现示例

    2023-02-15 01:22:24
  • java实现在线预览--poi实现word、excel、ppt转html的方法

    2022-09-29 20:29:41
  • 一小时迅速入门Mybatis之初识篇

    2023-07-20 10:27:23
  • C#获取USB事件API实例分析

    2021-09-01 13:55:07
  • 基于C#实现简易的键盘记录器

    2023-07-02 21:32:41
  • kotlin之协程的理解与使用详解

    2023-10-21 15:55:57
  • C#之Android手机App开发

    2023-10-19 05:18:04
  • Android ListView UI组件使用说明

    2022-06-14 16:04:09
  • 一篇文章带你复习java知识点

    2023-01-15 09:39:38
  • C#格式化json字符串的方法分析

    2023-12-23 00:20:36
  • C#异常捕获机制图文详解

    2023-05-22 19:39:20
  • C#中if语句使用概述

    2022-08-31 23:22:09
  • 利用Lambda表达式创建新线程案例

    2023-08-26 23:16:00
  • C#集合之队列的用法

    2022-11-24 16:15:38
  • Java中包装类介绍与其注意事项

    2023-03-20 18:26:36
  • 详解Java实现设计模式之责任链模式

    2023-11-08 10:32:07
  • Java TCP协议通信超详细讲解

    2021-05-30 20:53:35
  • asp之家 软件编程 m.aspxhome.com