1. 程式人生 > >Android自定義元件之日曆控制元件-精美日曆實現(內容、樣式可擴充套件)

Android自定義元件之日曆控制元件-精美日曆實現(內容、樣式可擴充套件)

需求
我們知道,Android系統本身有自帶的日曆控制元件,網路上也有很多開源的日曆控制元件資源,但是這些日曆控制元件往往樣式較單一,API較多,不易於在實際專案中擴充套件並實現出符合具體樣式風格的,內容可定製的效果。本文通過自定義日曆控制元件,實現了在內容和樣式上可高度擴充套件的精美日曆demo,有需要的Android應用開發人員可迅速移植並按需擴充套件實現。

在某個應用中,需要查詢使用者的歷史考勤記錄,根據實際考勤資料在日曆中標記出不同的狀態(如正常出勤、請假、遲到等),並在頁面中顯示相應的說明文字。

/2016.05.03更新說明=/
有讀者下載原始碼後發現執行的效果和示意圖不同,因為筆者是在2015年8月份上傳的程式碼,也只對該日期以前的宮格設定了樣式和響應事件。讀者只需手動更改原始版程式碼中CalendarGridViewAdapter.java類和MainActivity.java類中指定的日期即可(先前是2015.8,前者用於設定介面日期內宮格樣式,後者用於設定點選日期宮格的響應事件),或下載更新的程式碼


http://download.csdn.net/detail/daijin888888/9508732
GitHub(給個星杯~):
https://github.com/VingeDai/CalendarDemo
更新的程式碼裡增加了日期處理工具類,使得專案一直以當前系統時間的年月日作為樣式和事件響應的設定條件。
DataUtil.java:

public class DataUtil {
	static Calendar c = Calendar.getInstance();

	/**
	 * 獲取當前年
	 * 
	 * @return
	 */
	public static int getCurrentYear() {
		return c.get(Calendar.YEAR);
	}

	/**
	 * 獲取當前月
	 */
	public static int getCurrentMonth() {
		return c.get(Calendar.MONTH) + 1;
	}

	/**
	 * 獲取當前天
	 */
	public static int getCurrentDay() {
		return c.get(Calendar.DAY_OF_MONTH);
	}
}

PS:再次強調,本文主要是提供一種解決問題的方法和該方法的一種應用場景,請讀者自行閱讀程式碼並修改擴充套件成自己希望的效果。只會copy程式碼而不知其所以然的人,難以在技術的道路上走遠,願共勉之。

效果
實現的效果如下
正常出勤

請假

遲到

正常出勤

實現方式
首先說明涉及的主要知識點:

  • GridView+Adapter
  • 日曆演算法
    因為是GridView,我們可以控制每個item的樣式,實現樣式擴充套件,比如本文的程式,每個item裡就包含了兩個縱向排列的textview,上面的textview通過日曆演算法賦值,下面高5dp的可填充顏色的textview則可以根據當天日期的屬性和Adapter中的條件變更顏色,這也是***本文的重點***!!!

專案結構圖如下:
專案結構圖
com.widget.mycalendar 包下是主要的實現部分:

  1. CalendarGridView.java: 自定義日曆GridView,此處可擴充套件樣式,可實現日曆中每個網格(對應某一天)的長按效果。
  2. CalendarGridViewAdapter.java: 日曆介面卡,對具體的網格賦值和選擇性控制樣式(實現多樣化)。
  3. CalendarTool.java: 獲取日曆資料工具類,主要工具類,實現日曆演算法,包括閏年判斷。
  4. DateEntity.java: 日曆實體類,新增的引數在獲取日曆實體集合的時候設定,可以控制日期屬性(比如某一天對應的年、月、日、星期、是否為當前日期、是否為本月日期)

首先看自定義日曆GridView,
CalendarGridView.java:自定義日曆GridView,此處可擴充套件樣式,可實現日曆中每個網格(對應某一天)的長按效果。

package com.widget.mycalendar;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;

/**
 * @author daij
 * @version 1.0 自定義日曆GridView
 */
public class CalendarGridView extends GridView implements
		android.widget.AdapterView.OnItemLongClickListener {

	private Context mContext;

	public CalendarGridView(Context context) {
		super(context);
		this.mContext = context;
		initGridView();
	}

	public CalendarGridView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.mContext = context;
		initGridView();
	}

	public CalendarGridView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
		initGridView();
	}

	/**
	 * 初始化GirdView
	 * 
	 * @param <引數名稱>
	 *            <引數型別> <引數說明>
	 * @return <返回值型別>
	 * @throws <異常>
	 */
	public void initGridView() {

	}

	@Override
	public boolean onItemLongClick(AdapterView<?> parent, View view,
			int position, long id) {
		return false;
	}

}

CalendarGridViewAdapter.java:日曆介面卡,這裡提供的是模擬資料,根據不同日期的屬性控制不同顯示,對具體的網格賦值和選擇性控制樣式(實現多樣化)。

package com.widget.mycalendar;

import java.util.List;

import android.content.Context;
import android.content.res.Resources;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.mycalendar.R;

/**
 * @author daij
 * @version 1.0 日曆介面卡
 */
public class CalendarGridViewAdapter extends BaseAdapter {

	private Resources mRes;
	/** 上下文 */
	private Context mContext;
	/** 日期實體集合 */
	private List<DateEntity> mDataList;
	/** 因為position是從0開始的,所以用當做一箇中間者,用來加1.以達到判斷除數時,為哪個星期 */
	private int temp;

	public CalendarGridViewAdapter(Context context, Resources res) {
		this.mContext = context;
		this.mRes = res;
	}

	/** 設定日期資料 */
	public void setDateList(List<DateEntity> dataList) {
		this.mDataList = dataList;
	}

	@Override
	public int getCount() {
		if (mDataList == null) {
			return 0;
		}
		return mDataList.size();
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// 通過傳遞過來的MenuItem值給每一個item設定資料
		LinearLayout layout = (LinearLayout) LayoutInflater.from(mContext)
				.inflate(R.layout.calendar_item_layout, null);
		TextView textView = (TextView) layout
				.findViewById(R.id.calendar_item_tv_day);
		TextView tv_tip = (TextView) layout.findViewById(R.id.calendar_tip);
		if (mDataList != null) {
			textView.setText(mDataList.get(position).day + "");
			if ((TextUtils.equals(CalendarTool.SATURDAY,
					mDataList.get(position).weekDay))
					|| TextUtils.equals(CalendarTool.SUNDAY,
							mDataList.get(position).weekDay)) {
				// 週末背景為白,字型為灰色
				textView.setBackgroundColor(mRes.getColor(R.color.white));
				textView.setTextColor(mRes.getColor(R.color.weekend_day_txt));
			}// TODO 在非週末時候設定顏色
			else {
				if (((mDataList.get(position).year == 2015 && mDataList
						.get(position).month <= 8) || (mDataList.get(position).year < 2015 && mDataList
						.get(position).month <= 12))
						&& mDataList.get(position).isSelfMonthDate) {// 2015.8以前,且日期在當月
					if (mDataList.get(position).day > 0
							&& mDataList.get(position).day <= 20
							|| mDataList.get(position).day == 25) {
						tv_tip.setBackgroundColor(mRes
								.getColor(R.color.tip_normal));
					} else if (mDataList.get(position).day == 21
							|| mDataList.get(position).day == 22) {
						tv_tip.setBackgroundColor(mRes
								.getColor(R.color.tip_leave));
					} else if (mDataList.get(position).day == 23
							|| mDataList.get(position).day == 24) {
						tv_tip.setBackgroundColor(mRes
								.getColor(R.color.tip_late));
					} else {
						tv_tip.setBackgroundColor(mRes
								.getColor(R.color.tip_normal));
						if (mDataList.get(position).month == 8
								&& mDataList.get(position).day >= 25) {
							tv_tip.setBackgroundColor(mRes
									.getColor(R.color.white));
						}
					}
				}
			}
			if (mDataList.get(position).isNowDate
					&& mDataList.get(position).isSelfMonthDate) {
				// 如果為當前號數,則設定為白色背景並,字型為藍色
				textView.setBackgroundColor(mRes.getColor(R.color.white));
				textView.setTextColor(mRes.getColor(R.color.current_day_txt));
			}
			if (!mDataList.get(position).isSelfMonthDate) {// 是否為本月的號數,不是本月號數顯示白色,及不顯示
				textView.setTextColor(mRes.getColor(R.color.white));
			}
			layout.setTag(mDataList.get(position));// 把當前日曆實體放入GridView 的Item中
		}

		return layout;
	}
}

CalendarTool.java: 獲取日曆資料工具類,實現日曆演算法,包括閏年判斷,配有詳細註釋可參考

package com.widget.mycalendar;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.graphics.Point;
import android.util.Log;

/**
 * @author daij
 * @version 1.0 獲取日曆資料工具類
 */
public class CalendarTool {
	public static final String MONDAY = "週一";
	public static final String TUESDAY = "週二";
	public static final String WEDNESDAY = "週三";
	public static final String THURSDAY = "週四";
	public static final String FRIDAY = "週五";
	public static final String SATURDAY = "週六";
	public static final String SUNDAY = "週日";
	public static final String[] weekDayRow = { SUNDAY, MONDAY, TUESDAY,
			WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

	private List<DateEntity> mDataList = new ArrayList<DateEntity>();
	private DateEntity mDateEntity;
	private int mYear;
	private int mMonth;
	private int mDay;
	private int mDays;

	/** 系統當前年月日 */
	private int mCurrenYear;
	private int mCurrenMonth;
	private int mCurrenDay;
	private Context mContext;
	/** 用於演算法的變數 */
	/** 已過去的年份總天數 */
	int mGoneYearDays = 0;
	/** 本年包括今天的過去天數 */
	int thisYearDays = 0;
	/** 是否為閏年 */
	boolean isLeapYear = false;
	/** 平年月天數陣列 */
	int commonYearMonthDay[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	/** 閏年月天數陣列 */
	int leapYearMonthDay[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	public CalendarTool(Context context) {
		this.mContext = context;
		initNowDate();
	}

	/** 獲取當前日曆的年月 x為年,y為月 */
	public Point getNowCalendar() {
		Point p = new Point(mYear, mMonth);
		return p;
	}

	/** 通過年月獲取日期實體集合 集合大小為7*6=42,星期為7,6行以顯示足夠數量日期 */
	public List<DateEntity> getDateEntityList(int year, int month) {
		mDataList.clear();
		int dayOfNowCalendar = 42;// 當前日曆板的日期總數 7*6個數
		int dayOfWeek = 0;// 得到當前年月的每一天為星期幾
		int selfDaysEndWeek = 0;// 本月的最後一天是星期幾
		int startDate = 0;// 當前月的上一個月在本日曆的開始日期
		int days = 0;// 得到本月的總共天數
		/** 修改部分 */
		int endDate = 0;// 得到上一個月的天數,作為上一個月在本日曆的結束日期
		if ((year - 1) == this.mYear || month == 1) {// 說明向前翻了一年,那麼上個月的天數就應該是上一年的12月的天數,或者到翻到一月份的時候,那麼上一個月的天數也是上一年的12月份的天數
			endDate = this.getDays(year - 1, 12);
		} else {// 得到上一個月的天數,作為上一個月在本日曆的結束日期
			endDate = this.getDays(year, month - 1);
		}
		/** 修改部分結束 */
		this.mYear = year;// 當前日曆上顯示的年
		this.mMonth = month;// 當前日曆上顯示的月
		int previoursMonthDays = 0;// 上一個月在本月顯示的天數
		int nextMonthDays = 0;// 下一個月在本月顯示的天數
		days = this.getDays(year, month);
		dayOfWeek = this.getWeekDay(year, month);
		if (dayOfWeek == 0) {
			startDate = endDate - 7 + 1;
		} else {
			startDate = endDate - dayOfWeek + 1;
		}
		previoursMonthDays = endDate - startDate + 1;
		nextMonthDays = dayOfNowCalendar - days - previoursMonthDays;
		/** 先新增前面不屬於本月的 */
		for (int i = startDate, j = 0; i <= endDate; i++, j++) {
			mDateEntity = new DateEntity();
			mDateEntity.day = i;
			mDateEntity.isSelfMonthDate = false;
			mDateEntity.year = year;
			mDateEntity.month = month - 1;
			mDateEntity.weekDay = weekDayRow[j];
			mDataList.add(mDateEntity);
		}
		/** 新增本月的 */
		for (int i = 1, j = dayOfWeek; i <= days; i++, j++) {
			mDateEntity = new DateEntity();
			mDateEntity.day = i;
			mDateEntity.isSelfMonthDate = true;
			mDateEntity.year = year;
			mDateEntity.month = month;
			if (j >= 7) {
				j = 0;
			}
			selfDaysEndWeek = j;
			mDateEntity.weekDay = weekDayRow[j];
			if ((year == mCurrenYear) && (month == mCurrenMonth)
					&& i == mCurrenDay) {
				mDateEntity.isNowDate = true;
			}
			mDataList.add(mDateEntity);
		}
		/*** 新增後面下一個月的 */
		for (int i = 1, j = selfDaysEndWeek + 1; i <= nextMonthDays; i++, j++) {
			mDateEntity = new DateEntity();
			mDateEntity.day = i;
			mDateEntity.isSelfMonthDate = false;
			mDateEntity.year = year;
			mDateEntity.month = month + 1;
			if (j >= 7) {
				j = 0;
			}
			mDateEntity.weekDay = weekDayRow[j];
			mDataList.add(mDateEntity);
		}
		return mDataList;
	}

	/** 通過年月,獲取這個月一共有多少天 */
	public int getDays(int year, int month) {
		int days = 0;

		if ((year % 4 == 0 && (year % 100 != 0)) || (year % 400 == 0)) {
			if (month > 0 && month <= 12) {
				days = leapYearMonthDay[month - 1];
			}
		} else {
			if (month > 0 && month <= 12) {
				days = commonYearMonthDay[month - 1];
			}
		}
		return days;
	}

	/** 獲取星期的排列 */
	public String[] getWeekDayRow() {
		return weekDayRow;
	}

	/** 初始化當前系統的日期 */
	public void initNowDate() {
		Date date = new Date();
		SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-M-d");
		String currentDate = simpleFormat.format(date); // 當期日期
		mCurrenYear = Integer.parseInt(currentDate.split("-")[0]);
		mCurrenMonth = Integer.parseInt(currentDate.split("-")[1]);
		mCurrenDay = Integer.parseInt(currentDate.split("-")[2]);
		this.mYear = mCurrenYear;
		this.mMonth = mCurrenMonth;
	}

	/** 通過年,月獲取當前月的第一天1日為星期幾 ,返回0是星期天,1是星期一,依次類推 */
	public int getWeekDay(int year, int month) {
		int dayOfWeek;
		int goneYearDays = 0;
		int thisYearDays = 0;
		boolean isLeapYear = false;
		int commonYearMonthDay[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
				30, 31 };
		int leapYearMonthDay[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30,
				31 };
		for (int i = 1900; i < year; i++) {// 從1900年開始算起,1900年1月1日為星期一
			if ((i % 4 == 0 && (i % 100 != 0)) || (i % 400 == 0)) {
				goneYearDays = goneYearDays + 366;
			} else {
				goneYearDays = goneYearDays + 365;
			}
		}
		if ((year % 4 == 0 && (year % 100 != 0)) || (year % 400 == 0)) {
			isLeapYear = true;
			for (int i = 0; i < month - 1; i++) {
				thisYearDays = thisYearDays + leapYearMonthDay[i];
			}
		} else {
			isLeapYear = false;
			for (int i = 0; i < month - 1; i++) {
				thisYearDays = thisYearDays + commonYearMonthDay[i];
			}
		}
		dayOfWeek = (goneYearDays + thisYearDays + 1) % 7;
		Log.d(this.getClass().getName(), "從1990到現在有"
				+ (goneYearDays + thisYearDays + 1) + "天");
		Log.d(this.getClass().getName(), year + "年" + month + "月" + 1 + "日是星期"
				+ dayOfWeek);
		return dayOfWeek;
	}
}

DateEntity.java:實體類,比較簡單

package com.widget.mycalendar;

import java.io.Serializable;

/**
 * @author daij
 * @version 1.0 日曆實體類,新增的引數在獲取日曆實體集合的時候設定
 */
public class DateEntity implements Serializable {

	private static final long serialVersionUID = -6053739977785155088L;
	/** 年 */
	public int year;
	/** 月 */
	public int month;
	/** 日 */
	public int day;
	/** 星期 */
	public String weekDay;
	/** 是否為當前日期 */
	public boolean isNowDate;
	/** 是否為本月日期 */
	public boolean isSelfMonthDate;
}

MainActivity.java:主Activity,用於提供模擬資料和實現互動,程式碼如下:

package com.example.mycalendar;

import java.util.List;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.widget.mycalendar.CalendarGridView;
import com.widget.mycalendar.CalendarGridViewAdapter;
import com.widget.mycalendar.CalendarTool;
import com.widget.mycalendar.DateEntity;

/**
 * @author daij
 * @version 1.0 日曆:考勤記錄
 */
public class MainActivity extends Activity {
	private CalendarGridViewAdapter mAdapter;
	private CalendarTool mCalendarTool;
	private CalendarGridView mGridView;
	private List<DateEntity> mDateEntityList;
	private Point mNowCalendarPoint;
	private ImageView mPrevioursIv;
	private ImageView mNextIv;
	private ImageView ivBack;
	private TextView mCalendarTv;
	private TextView tvDetail;

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

		initView();// 初始化View
		setListeners();
		// requestXmas();//請求資料
	}

	/** 初始化view */
	public void initView() {
		mPrevioursIv = (ImageView) findViewById(R.id.calendar_bar_iv_previours);
		mNextIv = (ImageView) findViewById(R.id.calendar_bar_iv_next);
		ivBack = (ImageView) findViewById(R.id.iv_back);
		mCalendarTv = (TextView) findViewById(R.id.calendar_bar_tv_date);
		tvDetail = (TextView) findViewById(R.id.tv_detail);

		mGridView = (CalendarGridView) findViewById(R.id.calendar_gridview);
		mGridView.setSelector(new ColorDrawable(Color.TRANSPARENT));
		mGridView.setOnItemClickListener(new CalendarItemClickListener());

		mPrevioursIv.setOnClickListener(new ImageViewClickListener());
		mNextIv.setOnClickListener(new ImageViewClickListener());
		mCalendarTool = new CalendarTool(this);
		mNowCalendarPoint = mCalendarTool.getNowCalendar();
		mCalendarTv.setText(mNowCalendarPoint.x + "年" + mNowCalendarPoint.y
				+ "月");
		mDateEntityList = mCalendarTool.getDateEntityList(mNowCalendarPoint.x,
				mNowCalendarPoint.y);
		mAdapter = new CalendarGridViewAdapter(this, getResources());
		mAdapter.setDateList(mDateEntityList);
		mGridView.setAdapter(mAdapter);
	}

	/** 日曆監聽類 */
	class CalendarItemClickListener implements OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			// TODO 模擬資料
			DateEntity itemDate = (DateEntity) view.getTag();

			if (!((TextUtils.equals(CalendarTool.SATURDAY, itemDate.weekDay)) || TextUtils
					.equals(CalendarTool.SUNDAY, itemDate.weekDay))) {// 非週末
				if (((itemDate.year == 2015 && itemDate.month <= 8) || (itemDate.year < 2015 && itemDate.month <= 12))
						&& itemDate.isSelfMonthDate) {// 2015.8以前,且日期在當月
					if (itemDate.day > 0 && itemDate.day <= 20
							|| itemDate.day == 25) {// 正常出勤
						tvDetail.setText("備註:" + "\n" + "        "
								+ itemDate.year + "年" + itemDate.month + "月"
								+ itemDate.day + "日" + "--" + itemDate.weekDay
								+ "\n" + "正常出勤。");
					} else if (itemDate.day == 21 || itemDate.day == 22) {// 請假
						tvDetail.setText("備註:" + "\n" + "        "
								+ itemDate.year + "年" + itemDate.month + "月"
								+ itemDate.day + "日" + "--" + itemDate.weekDay
								+ "\n" + "請假兩天,從" + itemDate.month + "月21日到"
								+ itemDate.month + "月22日");
					} else if (itemDate.day == 23 || itemDate.day == 24) {// 遲到、早退
						if (itemDate.day == 23) {

							tvDetail.setText("備註:" + "\n" + "        "
									+ itemDate.year + "年" + itemDate.month
									+ "月" + itemDate.day + "日" + "--"
									+ itemDate.weekDay + "\n"
									+ "上午8:36打卡,下午5:40打卡" + "\n" + "上午遲到6分鐘");
						} else if (itemDate.day == 24) {

							tvDetail.setText("備註:" + "\n" + "        "
									+ itemDate.year + "年" + itemDate.month
									+ "月" + itemDate.day + "日" + "--"
									+ itemDate.weekDay + "\n"
									+ "上午8:25打卡,下午5:29打卡" + "\n" + "下午早退1分鐘");
						}
					} else {
						if (itemDate.month == 8 && itemDate.day > 25) {
							return;
						}
						tvDetail.setText("備註:" + "\n" + "        "
								+ itemDate.year + "年" + itemDate.month + "月"
								+ itemDate.day + "日" + "--" + itemDate.weekDay
								+ "\n" + "正常出勤。");
					}
				}
			}

			// Toast.makeText(
			// RecordCalendar.this,
			// "選中的是" + itemDate.year + "年" + itemDate.month + "月"
			// + itemDate.day + "日" + "--" + itemDate.weekDay,
			// Toast.LENGTH_SHORT).show();
		}
	}

	/** 按鈕 */
	class ImageViewClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.calendar_bar_iv_previours:// 上月
				mDateEntityList.clear();
				mNowCalendarPoint = mCalendarTool.getNowCalendar();
				if (mNowCalendarPoint.x >= 1990 && mNowCalendarPoint.x < 2038) {
					if (mNowCalendarPoint.y - 1 <= 0) {
						mDateEntityList = mCalendarTool.getDateEntityList(
								mNowCalendarPoint.x - 1, 12);
					} else {
						mDateEntityList = mCalendarTool.getDateEntityList(
								mNowCalendarPoint.x, mNowCalendarPoint.y - 1);
					}

					mAdapter.setDateList(mDateEntityList);
					mAdapter.notifyDataSetChanged();
					mNowCalendarPoint = mCalendarTool.getNowCalendar();
					mCalendarTv.setText(mNowCalendarPoint.x + "年"
							+ mNowCalendarPoint.y + "月");
				}

				break;
			case R.id.calendar_bar_iv_next:// 下月
				mNowCalendarPoint = mCalendarTool.getNowCalendar();
				mDateEntityList.clear();
				if (mNowCalendarPoint.x >= 1990 && mNowCalendarPoint.x < 2038) {
					if (mNowCalendarPoint.y + 1 > 12) {
						mDateEntityList = mCalendarTool.getDateEntityList(
								mNowCalendarPoint.x + 1, 1);
					} else {
						mDateEntityList = mCalendarTool.getDateEntityList(
								mNowCalendarPoint.x, mNowCalendarPoint.y + 1);
					}
					mAdapter.setDateList(mDateEntityList);
					mAdapter.notifyDataSetChanged();
					mNowCalendarPoint = mCalendarTool.getNowCalendar();
					mCalendarTv.setText(mNowCalendarPoint.x + "年"
							+ mNowCalendarPoint.y + "月");
				}
				break;
			}
		}

	}

	private void setListeners() {
		ivBack.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				MainActivity.this.finish();
			}
		});
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

}

模擬資料說明:在2015年8月25日(包含這天)前均有打卡記錄,模擬每月21、22號請假,23、24號遲到或早退,其他工作日正常出勤。模擬資料僅作展示效果之用。

程式碼是最好的語言,再加上詳細的註釋,相信有一定Java程式設計基礎和Android應用開發經驗的人都能看懂。因為需要自己按照專案去擴充套件,本文只提供解決思路,希望讀者不要懶惰,只有讀懂本文的程式碼邏輯才能擴展出你所需的程式碼。

相關推薦

Android定義元件日曆控制元件-精美日曆實現內容樣式擴充套件

需求 我們知道,Android系統本身有自帶的日曆控制元件,網路上也有很多開源的日曆控制元件資源,但是這些日曆控制元件往往樣式較單一,API較多,不易於在實際專案中擴充套件並實現出符合具體樣式風格的,內容可定製的效果。本文通過自定義日曆控制元件,實現了在內容和樣

Android 表格控制元件-動態實現表格效果內容樣式擴充套件

說明:表格是很常用的控制元件,Android本身提供了TableLayout供佈局實現,但本文介紹另外一種思路,用動態佈局的方式實現,這種方式更靈活,內容、樣式能高度擴充套件,熟練的人可隨意運用到任何檢

Android定義View組合控制元件 ---- LED數字時鐘

先上圖 LEDView效果如圖所示。 之前看到一篇部落格使用兩個TextView實現了該效果,於是我想用自定義控制元件的方式實現一個LEDView,使用時即可直接使用該控制元件。 採用組合控制元件的方式,將兩個TextView疊放在一起,再使用digital-7.ttf字

Android定義View--翻書控制元件

0.前言 最近重看了一遍封神演義,感覺QQ閱讀那個翻書的效果挺好的,準備做一個。上週五下午用了兩個小時只寫了一部分功能,以後有時間再完善 1.分析 先看效果圖 這個空間,說簡單也簡單,說難也難,簡單就在於這個效果主要就是依賴canvas的clippath才見到部分canvas,難就難在裁

android 定義鍵盤輸入密碼控制元件

直接上程式碼 public class PwdInputView extends RelativeLayout { private Context mContext; private GridView

Android定義多TAB懸浮控制元件實現蘑菇街首頁效果

說明: 1.viewpager不能左右滑動; 2.轉載時程式碼略有改動(注:修復tab控制元件不能自動滑動的問題); 3.原始碼下載後不能直接執行,經過調整此問題已經修復。 核心程式碼: package com.Imy.Fuli.Fra

【安卓筆記】定義view組合控制元件

組合控制元件即將若干個系統已有的控制元件組合到一塊形成一個組合控制元件,比如帶返回按鈕的標題欄就是一個最簡單的組合控制元件。 使用組合控制元件的好處是提高程式碼的複用性,一處定義多處使用。 下面我們

Android 定義圓環倒計時控制元件

先來一張最終效果圖:主要思路: 在畫漸變色圓環的時候,設定一個屬性動畫,根據屬性動畫的執行時長,來作為倒計時的時長.監聽屬性動畫的進度,來達到 倒計時的目的.二話不說,直接貼程式碼.具體實現思路都在註釋上.自定義屬性:<declare-styleable name="C

Android定義View仿QQ側滑選單實現

最近,由於正在做的一個應用中要用到側滑選單,所以通過查資料看視訊,學習了一下自定義View,實現一個類似於QQ的側滑選單,順便還將其封裝為自定義元件,可以實現類似QQ的側滑選單和抽屜式側滑選單兩種選單。 下面先放上效果圖: 我們這裡的側

Android定義 view圖片裁剪從設計到實現

android圖片剪下是常用的功能,因為部落格開發的是SDK不涉及到activity,所以就需要自定義裁剪功能,參閱了網上的大部分資料後,在github上一個封裝好的裁剪庫cropper,正好符合要求,本著拿來主義的思想,直接把原始碼clone嵌入到專案裡,然後

Android定義View-----日曆控制元件

寫在前面 Android的系統的日曆控制元件十分簡陋,在專案中拿不出手啊,這也許就是蘋果和Android的顯式區別:系統控制元件美觀合理,各App統一,最後App和系統風格統一;而Android由於長相上先天不足,當然自從有了MD之後也十分fashion了

Android 定義控制元件標籤控制元件

一、首先這是效果 二、實現原理 通過繼承ViewGroup,然後在重寫 onMeasure測量每個View的寬度,重新onLayout控制每個控制元件的位置, 並新增點選事件 三、實現 1、在onMeasure方法中得到顯示方式,並得到寬高 int widt

Android定義ViewFairySearchView靈活的通用搜索控制元件

1.概述 FairySearchView是經過封裝的通用搜索控制元件,可以根據需求切換不同的佈局模式。內建多種事件監聽器,可以滿足不同場景的業務需求,使用方式非常靈活。 2.效果預覽 顯示所有控制元件(無輸入內容) 顯示所有控制元件(有輸

定義控制元件下載控制元件1DownloadView1

前段時間在乾貨集中營看到了兩個炫酷的下載按鈕:       可惜是隔壁 iOS 的孩子,怎麼辦,我也好喜歡,emmm,某該,只能自己模仿著實現一下了。先從第一個入手(第二個波浪效果暫時還不會)。 1 準備動作 寫過幾次自定義控制元件

定義控制元件組合式控制元件 下拉選擇框

自定義控制元件之組合式控制元件 下拉選擇框 文章目錄 自定義控制元件之組合式控制元件 下拉選擇框 零 組合控制元件下載 一 自定義控制元件思路 二 MainActivity核心程式碼 三 activity_main.xml

Android—點選定義dialog窗體的控制元件銷燬自己

注意藍色字型部分 /** * 自定義彈出更新對話方塊 */ @SuppressLint("NewApi") protected void shownewsDialog(String title1, String title2, String title3) { final

分分鐘搞定定義控制元件組合控制元件--定義View入門篇

今天給大家詳細講解一下如何實現自定義組合控制元件,組合控制元件其實很簡單。大家可以自由地組合任意控制元件。好了,下面開始我們的正文。 我們要實現的效果如右圖底部所示,其實呢!大家只要把握規律,還是挺容易的。 新建一個attrs.xml屬性集檔案,即你要自定義控制元件的

Android獲取dialog定義佈局中的控制元件

最近寫了一個自定義佈局的Dialog,執行效果如下: 然後我想獲取到自定義佈局中的EditText控制元件,並得到其中的字串,但是使用send_email = (EditText) findViewById(R.id.send_email_dialog_et);並不能

c# 定義事件傳參(控制元件資料同步更新)

下面是傳值的視窗程式碼   public partial class Form1 : Form {//自定義一個事件 public event EventHandler SetMsg; public Form1() {

Silverlight定義資料繫結控制元件應該如何處理IEditableObject和IEditableCollectionView物件

原文: Silverlight自定義資料繫結控制元件應該如何處理IEditableObject和IEditableCollectionView物件 原創文章,如需轉載,請註明出處。   最近在一直研究Silverlight下的資料繫結控制元件,發現有這樣兩個介面IEditableObject