/****************从此出开始将代码拷贝到一个文件中*******************/package cc.util.android.view;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.Date;

import java.util.List;

import java.util.Locale;

import android.annotation.SuppressLint;

import android.content.Context;

import android.graphics.BitmapFactory;

import android.graphics.Color;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.graphics.drawable.StateListDrawable;

import android.text.TextUtils.TruncateAt;

import android.util.AttributeSet;

import android.view.GestureDetector;

import android.view.GestureDetector.OnGestureListener;

import android.view.Gravity;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.view.View.OnTouchListener;

import android.view.animation.Animation;

import android.view.animation.Animation.AnimationListener;

import android.view.animation.TranslateAnimation;

import android.widget.BaseAdapter;

import android.widget.GridView;

import android.widget.ImageButton;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;

import android.widget.TextView;

import android.widget.ViewFlipper;

import android.widget.AbsListView.LayoutParams;/**

* 日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写)

*

* @author wangcccong

* @version 1.406 create at: Mon, 03 Sep. 2014

*
update at: Mon, 23 Sep. 2014

*   新增日期标注和点击操作*/

public classCalendarView extends LinearLayout implements OnTouchListener,

AnimationListener, OnGestureListener {/**

* 点击日历*/

public interfaceOnCalendarViewListener {voidonCalendarItemClick(CalendarView view, Date date);

}/** 顶部控件所占高度*/

private final static int TOP_HEIGHT = 40;/** 日历item中默认id从0xff0000开始*/

private final static int DEFAULT_ID = 0xff0000;//判断手势用

private static final int SWIPE_MIN_DISTANCE = 120;private static final int SWIPE_MAX_OFF_PATH = 250;private static final int SWIPE_THRESHOLD_VELOCITY = 200;//屏幕宽度和高度

private intscreenWidth;//动画

privateAnimation slideLeftIn;privateAnimation slideLeftOut;privateAnimation slideRightIn;privateAnimation slideRightOut;privateViewFlipper viewFlipper;private GestureDetector mGesture = null;/** 上一月*/

privateGridView gView1;/** 当月*/

privateGridView gView2;/** 下一月*/

privateGridView gView3;

boolean bIsSelection= false;//是否是选择事件发生

private Calendar calStartDate = Calendar.getInstance();//当前显示的日历

private Calendar calSelected = Calendar.getInstance(); //选择的日历

privateCalendarGridViewAdapter gAdapter;privateCalendarGridViewAdapter gAdapter1;privateCalendarGridViewAdapter gAdapter3;privateLinearLayout mMainLayout;private TextView mTitle; //显示年月

private int iMonthViewCurrentMonth = 0; //当前视图月

private int iMonthViewCurrentYear = 0; //当前视图年

private static final int caltitleLayoutID = 66; //title布局ID

private static final int calLayoutID = 55; //日历布局ID

privateContext mContext;/** 标注日期*/

private final ListmarkDates;privateOnCalendarViewListener mListener;publicCalendarView(Context context) {this(context, null);

}publicCalendarView(Context context, AttributeSet attrs) {

super(context, attrs);//TODO Auto-generated constructor stub

mContext =context;

markDates= new ArrayList();

init();

}//初始化相关工作

protected voidinit() {//得到屏幕的宽度

screenWidth =mContext.getResources().getDisplayMetrics().widthPixels;//滑动的动画

slideLeftIn = new TranslateAnimation(screenWidth, 0, 0, 0);

slideLeftIn.setDuration(400);

slideLeftIn.setAnimationListener(this);

slideLeftOut= new TranslateAnimation(0, -screenWidth, 0, 0);

slideLeftOut.setDuration(400);

slideLeftOut.setAnimationListener(this);

slideRightIn= new TranslateAnimation(-screenWidth, 0, 0, 0);

slideRightIn.setDuration(400);

slideRightIn.setAnimationListener(this);

slideRightOut= new TranslateAnimation(0, screenWidth, 0, 0);

slideRightOut.setDuration(400);

slideRightOut.setAnimationListener(this);//手势操作

mGesture = new GestureDetector(mContext, this);//获取到当前日期

UpdateStartDateForMonth();//绘制界面

setOrientation(LinearLayout.HORIZONTAL);

mMainLayout= newLinearLayout(mContext);

LinearLayout.LayoutParams main_params= newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

mMainLayout.setLayoutParams(main_params);

mMainLayout.setGravity(Gravity.CENTER_HORIZONTAL);

mMainLayout.setOrientation(LinearLayout.VERTICAL);

addView(mMainLayout);//顶部控件

generateTopView();//中间显示星期

generateWeekGirdView();//底部显示日历

viewFlipper = newViewFlipper(mContext);

RelativeLayout.LayoutParams fliper_params= newRelativeLayout.LayoutParams(

LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

fliper_params.addRule(RelativeLayout.BELOW, caltitleLayoutID);

mMainLayout.addView(viewFlipper, fliper_params);

generateClaendarGirdView();//最下方的一条线条

LinearLayout br = newLinearLayout(mContext);

br.setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));

LinearLayout.LayoutParams params_br= newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT,3);

mMainLayout.addView(br, params_br);

}/** 生成顶部控件*/@SuppressWarnings("deprecation")private voidgenerateTopView() {//顶部显示上一个下一个,以及当前年月

RelativeLayout top = newRelativeLayout(mContext);

top.setBackgroundColor(Color.argb(0xff, 0x0e, 0x6b, 0xc2));

LinearLayout.LayoutParams top_params= newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT,

ViewUtil.dip2px(mContext, TOP_HEIGHT));

top.setLayoutParams(top_params);

mMainLayout.addView(top);//左方按钮、中间日期显示、右方按钮

mTitle = newTextView(mContext);

android.widget.RelativeLayout.LayoutParams title_params= newandroid.widget.RelativeLayout.LayoutParams(

android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,

android.widget.RelativeLayout.LayoutParams.MATCH_PARENT);

mTitle.setLayoutParams(title_params);

mTitle.setTextColor(Color.WHITE);

mTitle.setTextSize(18);

mTitle.setFocusableInTouchMode(true);

mTitle.setMarqueeRepeatLimit(-1);

mTitle.setEllipsize(TruncateAt.MARQUEE);

mTitle.setSingleLine(true);

mTitle.setGravity(Gravity.CENTER);

mTitle.setHorizontallyScrolling(true);

mTitle.setText("2014年9月");

top.addView(mTitle);//左方按钮

ImageButton mLeftView = newImageButton(mContext);

StateListDrawable stateListDrawableL= newStateListDrawable();

Drawable lDrawableNor= newBitmapDrawable(mContext.getResources(),

BitmapFactory.decodeStream(CalendarView.class.getResourceAsStream("image/left_arrow.png")));

Drawable lDrawablePre= newBitmapDrawable(mContext.getResources(),

BitmapFactory.decodeStream(CalendarView.class.getResourceAsStream("image/left_arrow_pre.png")));

stateListDrawableL.addState(new int[] { -android.R.attr.state_pressed }, lDrawableNor);

stateListDrawableL.addState(new int[] { android.R.attr.state_pressed },

lDrawablePre);

mLeftView.setBackgroundDrawable(stateListDrawableL);

android.widget.RelativeLayout.LayoutParams leftPP= newandroid.widget.RelativeLayout.LayoutParams(

ViewUtil.dip2px(mContext,25), ViewUtil.dip2px(mContext, 22));

leftPP.addRule(RelativeLayout.ALIGN_PARENT_LEFT);

leftPP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);

leftPP.setMargins(20, 0, 0, 0);

mLeftView.setLayoutParams(leftPP);

mLeftView.setOnClickListener(newOnClickListener() {

@Overridepublic voidonClick(View v) {//TODO Auto-generated method stub

viewFlipper.setInAnimation(slideRightIn);

viewFlipper.setOutAnimation(slideRightOut);

viewFlipper.showPrevious();

setPrevViewItem();

}

});

top.addView(mLeftView);//右方按钮

ImageButton mRightView = newImageButton(mContext);

StateListDrawable stateListDrawable= newStateListDrawable();

Drawable rDrawableNor= newBitmapDrawable(mContext.getResources(),

BitmapFactory.decodeStream(CalendarView.class.getResourceAsStream("image/right_arrow.png")));

Drawable rDrawablePre= newBitmapDrawable(mContext.getResources(),

BitmapFactory.decodeStream(CalendarView.class.getResourceAsStream("image/right_arrow_pre.png")));

stateListDrawable.addState(new int[] { -android.R.attr.state_pressed },

rDrawableNor);

stateListDrawable.addState(new int[] { android.R.attr.state_pressed },

rDrawablePre);

mRightView.setBackgroundDrawable(stateListDrawable);

android.widget.RelativeLayout.LayoutParams rightPP= newandroid.widget.RelativeLayout.LayoutParams(

ViewUtil.dip2px(mContext,25), ViewUtil.dip2px(mContext, 22));

rightPP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

rightPP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);

rightPP.setMargins(0, 0, 20, 0);

mRightView.setLayoutParams(rightPP);

mRightView.setOnClickListener(newOnClickListener() {

@Overridepublic voidonClick(View v) {//TODO Auto-generated method stub

viewFlipper.setInAnimation(slideLeftIn);

viewFlipper.setOutAnimation(slideLeftOut);

viewFlipper.showNext();

setNextViewItem();

}

});

top.addView(mRightView);

}/** 生成中间显示week*/

private voidgenerateWeekGirdView() {

GridView gridView= newGridView(mContext);

LinearLayout.LayoutParamsparams = newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

gridView.setLayoutParams(params);

gridView.setNumColumns(7);//设置每行列数

gridView.setGravity(Gravity.CENTER_VERTICAL);//位置居中

gridView.setVerticalSpacing(1);//垂直间隔

gridView.setHorizontalSpacing(1);//水平间隔

gridView.setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));int i = screenWidth / 7;int j = screenWidth - (i * 7);int x = j / 2;

gridView.setPadding(x,0, 0, 0);//居中

WeekGridAdapter weekAdapter = newWeekGridAdapter(mContext);

gridView.setAdapter(weekAdapter);//设置菜单Adapter

mMainLayout.addView(gridView);

}/** 生成底部日历*/

private voidgenerateClaendarGirdView() {

Calendar tempSelected1= Calendar.getInstance(); //临时

Calendar tempSelected2 = Calendar.getInstance(); //临时

Calendar tempSelected3 = Calendar.getInstance(); //临时

tempSelected1.setTime(calStartDate.getTime());

tempSelected2.setTime(calStartDate.getTime());

tempSelected3.setTime(calStartDate.getTime());

gView1= newCalendarGridView(mContext);

tempSelected1.add(Calendar.MONTH,-1);

gAdapter1= newCalendarGridViewAdapter(mContext, tempSelected1,

markDates);

gView1.setAdapter(gAdapter1);//设置菜单Adapter

gView1.setId(calLayoutID);

gView2= newCalendarGridView(mContext);

gAdapter= newCalendarGridViewAdapter(mContext, tempSelected2,

markDates);

gView2.setAdapter(gAdapter);//设置菜单Adapter

gView2.setId(calLayoutID);

gView3= newCalendarGridView(mContext);

tempSelected3.add(Calendar.MONTH,1);

gAdapter3= newCalendarGridViewAdapter(mContext, tempSelected3,

markDates);

gView3.setAdapter(gAdapter3);//设置菜单Adapter

gView3.setId(calLayoutID);

gView2.setOnTouchListener(this);

gView1.setOnTouchListener(this);

gView3.setOnTouchListener(this);if (viewFlipper.getChildCount() != 0) {

viewFlipper.removeAllViews();

}

viewFlipper.addView(gView2);

viewFlipper.addView(gView3);

viewFlipper.addView(gView1);

String title= calStartDate.get(Calendar.YEAR)+ "年"

+NumberHelper.LeftPad_Tow_Zero(calStartDate

.get(Calendar.MONTH) + 1) + "月";

mTitle.setText(title);

}//上一个月

private voidsetPrevViewItem() {

iMonthViewCurrentMonth--;//当前选择月--//如果当前月为负数的话显示上一年

if (iMonthViewCurrentMonth == -1) {

iMonthViewCurrentMonth= 11;

iMonthViewCurrentYear--;

}

calStartDate.set(Calendar.DAY_OF_MONTH, 1); //设置日为当月1日

calStartDate.set(Calendar.MONTH, iMonthViewCurrentMonth); //设置月

calStartDate.set(Calendar.YEAR, iMonthViewCurrentYear); //设置年

}//下一个月

private voidsetNextViewItem() {

iMonthViewCurrentMonth++;if (iMonthViewCurrentMonth == 12) {

iMonthViewCurrentMonth= 0;

iMonthViewCurrentYear++;

}

calStartDate.set(Calendar.DAY_OF_MONTH, 1);

calStartDate.set(Calendar.MONTH, iMonthViewCurrentMonth);

calStartDate.set(Calendar.YEAR, iMonthViewCurrentYear);

}//根据改变的日期更新日历//填充日历控件用

private voidUpdateStartDateForMonth() {

calStartDate.set(Calendar.DATE, 1); //设置成当月第一天

iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);//得到当前日历显示的月

iMonthViewCurrentYear = calStartDate.get(Calendar.YEAR);//得到当前日历显示的年//星期一是2 星期天是1 填充剩余天数

int iDay = 0;int iFirstDayOfWeek =Calendar.MONDAY;int iStartDay =iFirstDayOfWeek;if (iStartDay ==Calendar.MONDAY) {

iDay= calStartDate.get(Calendar.DAY_OF_WEEK) -Calendar.MONDAY;if (iDay < 0)

iDay= 6;

}if (iStartDay ==Calendar.SUNDAY) {

iDay= calStartDate.get(Calendar.DAY_OF_WEEK) -Calendar.SUNDAY;if (iDay < 0)

iDay= 6;

}

calStartDate.add(Calendar.DAY_OF_WEEK,-iDay);

}/**

* 设置标注的日期

*

* @param markDates*/

public void setMarkDates(ListmarkDates) {this.markDates.clear();this.markDates.addAll(markDates);

gAdapter.notifyDataSetChanged();

gAdapter1.notifyDataSetChanged();

gAdapter3.notifyDataSetChanged();

}/**

* 设置点击日历监听

*

* @param listener*/

public voidsetOnCalendarViewListener(OnCalendarViewListener listener) {this.mListener =listener;

}

@Overridepublicboolean onDown(MotionEvent e) {//TODO Auto-generated method stub

return false;

}

@SuppressLint("ClickableViewAccessibility")

@Overridepublic boolean onTouch(View v, MotionEvent event) {return mGesture.onTouchEvent(event);

}

@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, floatvelocityX,floatvelocityY) {//TODO Auto-generated method stub

try{if (Math.abs(e1.getY() - e2.getY()) >SWIPE_MAX_OFF_PATH)return false;//right to left swipe

if (e1.getX() - e2.getX() >SWIPE_MIN_DISTANCE&& Math.abs(velocityX) >SWIPE_THRESHOLD_VELOCITY) {

viewFlipper.setInAnimation(slideLeftIn);

viewFlipper.setOutAnimation(slideLeftOut);

viewFlipper.showNext();

setNextViewItem();return true;

}else if (e2.getX() - e1.getX() >SWIPE_MIN_DISTANCE&& Math.abs(velocityX) >SWIPE_THRESHOLD_VELOCITY) {

viewFlipper.setInAnimation(slideRightIn);

viewFlipper.setOutAnimation(slideRightOut);

viewFlipper.showPrevious();

setPrevViewItem();return true;

}

}catch(Exception e) {//nothing

}return false;

}

@Overridepublic voidonLongPress(MotionEvent e) {//TODO Auto-generated method stub

}

@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, floatdistanceX,floatdistanceY) {//TODO Auto-generated method stub

return false;

}

@Overridepublic voidonShowPress(MotionEvent e) {//TODO Auto-generated method stub

}

@Overridepublicboolean onSingleTapUp(MotionEvent e) {//TODO Auto-generated method stub//得到当前选中的是第几个单元格

int pos = gView2.pointToPosition((int) e.getX(), (int) e.getY());

LinearLayout txtDay=(LinearLayout) gView2.findViewById(pos+DEFAULT_ID);if (txtDay != null) {if (txtDay.getTag() != null) {

Date date=(Date) txtDay.getTag();

calSelected.setTime(date);

gAdapter.setSelectedDate(calSelected);

gAdapter.notifyDataSetChanged();

gAdapter1.setSelectedDate(calSelected);

gAdapter1.notifyDataSetChanged();

gAdapter3.setSelectedDate(calSelected);

gAdapter3.notifyDataSetChanged();if (mListener != null)

mListener.onCalendarItemClick(this, date);

}

}return false;

}

@Overridepublic voidonAnimationEnd(Animation animation) {//TODO Auto-generated method stub

generateClaendarGirdView();

}

@Overridepublic voidonAnimationRepeat(Animation animation) {//TODO Auto-generated method stub

}

@Overridepublic voidonAnimationStart(Animation animation) {//TODO Auto-generated method stub

}

}/**

* 显示week的布局adapter

**/

classWeekGridAdapter extends BaseAdapter {

final String[] titles= new String[] { "日", "一", "二", "三", "四", "五", "六"};privateContext mContext;publicWeekGridAdapter(Context context) {this.mContext =context;

}

@Overridepublic intgetCount() {returntitles.length;

}

@Overridepublic Object getItem(intposition) {returntitles[position];

}

@Overridepublic long getItemId(intposition) {returnposition;

}

@Overridepublic View getView(intposition, View convertView, ViewGroup parent) {

TextView week= newTextView(mContext);

android.view.ViewGroup.LayoutParams week_params= newLayoutParams(

android.view.ViewGroup.LayoutParams.MATCH_PARENT,

android.view.ViewGroup.LayoutParams.MATCH_PARENT);

week.setLayoutParams(week_params);

week.setPadding(0, 0, 0, 0);

week.setGravity(Gravity.CENTER);

week.setFocusable(false);

week.setBackgroundColor(Color.TRANSPARENT);if (position == 6) { //周六

week.setBackgroundColor(Color.argb(0xff, 0x52, 0x9b, 0xd0));

week.setTextColor(Color.WHITE);

}else if (position == 0) { //周日

week.setBackgroundColor(Color.argb(0xff, 0xbc, 0x44, 0x45));

week.setTextColor(Color.WHITE);

}else{

week.setTextColor(Color.BLACK);

}

week.setText(getItem(position)+ "");returnweek;

}

}/**

* 显示日期的adapter*/

classCalendarGridViewAdapter extends BaseAdapter {/** 日历item中默认id从0xff0000开始*/

private final static int DEFAULT_ID = 0xff0000;private Calendar calStartDate = Calendar.getInstance();//当前显示的日历

private Calendar calSelected = Calendar.getInstance(); //选择的日历

/** 标注的日期*/

private ListmarkDates;privateContext mContext;private Calendar calToday = Calendar.getInstance(); //今日

private ArrayListtitles;private ArrayListgetDates() {

UpdateStartDateForMonth();

ArrayList alArrayList = new ArrayList();for (int i = 1; i <= 42; i++) {

alArrayList.add(calStartDate.getTime());

calStartDate.add(Calendar.DAY_OF_MONTH,1);

}returnalArrayList;

}//construct

public CalendarGridViewAdapter(Context context, Calendar cal, Listdates) {

calStartDate=cal;this.mContext =context;

titles=getDates();this.markDates =dates;

}publicCalendarGridViewAdapter(Context context) {this.mContext =context;

}

@Overridepublic intgetCount() {returntitles.size();

}

@Overridepublic Object getItem(intposition) {return titles.get(position);

}

@Overridepublic long getItemId(intposition) {returnposition;

}

@SuppressWarnings("deprecation")

@Overridepublic View getView(intposition, View convertView, ViewGroup parent) {//整个Item

LinearLayout itemLayout = newLinearLayout(mContext);

itemLayout.setId(position+DEFAULT_ID);

itemLayout.setGravity(Gravity.CENTER);

itemLayout.setOrientation(1);

itemLayout.setBackgroundColor(Color.WHITE);

Date myDate=(Date) getItem(position);

itemLayout.setTag(myDate);

Calendar calCalendar=Calendar.getInstance();

calCalendar.setTime(myDate);//显示日期day

TextView textDay = new TextView(mContext);//日期

LinearLayout.LayoutParams text_params = newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

textDay.setGravity(Gravity.CENTER_HORIZONTAL);int day = myDate.getDate(); //日期

textDay.setText(String.valueOf(day));

textDay.setId(position+DEFAULT_ID);

itemLayout.addView(textDay, text_params);//显示公历

TextView chineseDay = newTextView(mContext);

LinearLayout.LayoutParams chinese_params= newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

chineseDay.setGravity(Gravity.CENTER_HORIZONTAL);

chineseDay.setTextSize(9);

CalendarUtil calendarUtil= newCalendarUtil(calCalendar);

chineseDay.setText(calendarUtil.toString());

itemLayout.addView(chineseDay, chinese_params);//如果是当前日期则显示不同颜色

if(equalsDate(calToday.getTime(), myDate)) {

itemLayout.setBackgroundColor(Color.argb(0xff, 0x6d, 0xd6, 0x97));

}//这里用于比对是不是比当前日期小,如果比当前日期小则显示浅灰色

if (!CalendarUtil.compare(myDate, calToday.getTime())) {

itemLayout.setBackgroundColor(Color.argb(0xff, 0xee, 0xee, 0xee));

textDay.setTextColor(Color.argb(0xff, 0xc0, 0xc0, 0xc0));

chineseDay.setTextColor(Color.argb(0xff, 0xc0, 0xc0, 0xc0));

}else{

chineseDay.setTextColor(Color.argb(0xff, 0xc2, 0xa5, 0x3d));

chineseDay.setTextColor(Color.argb(0xff, 0x60, 0x3b, 0x07));//设置背景颜色

if(equalsDate(calSelected.getTime(), myDate)) {//选择的

itemLayout.setBackgroundColor(Color.argb(0xff, 0xdc, 0xe2, 0xff));

}else{if(equalsDate(calToday.getTime(), myDate)) {//当前日期faedda

itemLayout.setBackgroundColor(Color.argb(0xff, 0xfa, 0xed, 0xda));

}

}

}/** 设置标注日期颜色*/

if (markDates != null) {

final SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);for(Date date : markDates) {if(format.format(myDate).equals(format.format(date))) {

itemLayout.setBackgroundColor(Color.argb(0xff, 0xd3, 0x3a, 0x3a));break;

}

}

}returnitemLayout;

}

@Overridepublic voidnotifyDataSetChanged() {

super.notifyDataSetChanged();

}

@SuppressWarnings("deprecation")privateBoolean equalsDate(Date date1, Date date2) {if (date1.getYear() ==date2.getYear()&& date1.getMonth() ==date2.getMonth()&& date1.getDate() ==date2.getDate()) {return true;

}else{return false;

}

}//根据改变的日期更新日历//填充日历控件用

private voidUpdateStartDateForMonth() {

calStartDate.set(Calendar.DATE, 1); //设置成当月第一天//星期一是2 星期天是1 填充剩余天数

int iDay = 0;int iFirstDayOfWeek =Calendar.MONDAY;int iStartDay =iFirstDayOfWeek;if (iStartDay ==Calendar.MONDAY) {

iDay= calStartDate.get(Calendar.DAY_OF_WEEK) -Calendar.MONDAY;if (iDay < 0)

iDay= 6;

}if (iStartDay ==Calendar.SUNDAY) {

iDay= calStartDate.get(Calendar.DAY_OF_WEEK) -Calendar.SUNDAY;if (iDay < 0)

iDay= 6;

}

calStartDate.add(Calendar.DAY_OF_WEEK,-iDay);

calStartDate.add(Calendar.DAY_OF_MONTH,-1);//周日第一位

}public voidsetSelectedDate(Calendar cal) {

calSelected=cal;

}

}/**

* 用于生成日历展示的GridView布局*/

classCalendarGridView extends GridView {/**

* 当前操作的上下文对象*/

privateContext mContext;/**

* CalendarGridView 构造器

*

* @param context

* 当前操作的上下文对象*/

publicCalendarGridView(Context context) {

super(context);

mContext=context;

initGirdView();

}/**

* 初始化gridView 控件的布局*/

private voidinitGirdView() {

LinearLayout.LayoutParamsparams = newLinearLayout.LayoutParams(

LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

setLayoutParams(params);

setNumColumns(7);//设置每行列数

setGravity(Gravity.CENTER_VERTICAL);//位置居中

setVerticalSpacing(1);//垂直间隔

setHorizontalSpacing(1);//水平间隔

setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));int i = mContext.getResources().getDisplayMetrics().widthPixels / 7;int j =mContext.getResources().getDisplayMetrics().widthPixels- (i * 7);int x = j / 2;

setPadding(x,0, 0, 0);//居中

}

}/**

* 把公历时间处理成农历时间

**/

classCalendarUtil {/**

* 用于保存中文的月份*/

private final static String CHINESE_NUMBER[] = { "一", "二", "三", "四", "五","六", "七", "八", "九", "十", "十一", "腊"};/**

* 用于保存展示周几使用*/

private final static String WEEK_NUMBER[] = { "日", "一", "二", "三", "四", "五","六"};private final static long[] LUNAR_INFO = new long[] { 0x04bd8, 0x04ae0,0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0,0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540,0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5,0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3,0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0,0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0,0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8,0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570,0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5,0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0,0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50,0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0,0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7,0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50,0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954,0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260,0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0,0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0,0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20,0x0ada0};/**

* 转换为2012年11月22日格式*/

private static SimpleDateFormat chineseDateFormat = newSimpleDateFormat("yyyy年MM月dd日");/**

* 转换为2012-11-22格式*/

private static SimpleDateFormat simpleDateFormat = newSimpleDateFormat("yyyy-MM-dd");/**

* 计算得到农历的年份*/

private intmLuchYear;/**

* 计算得到农历的月份*/

private intmLuchMonth;/**

* 计算得到农历的日期*/

private intmLuchDay;/**

* 用于标识是事为闰年*/

privateboolean isLoap;/**

* 用于记录当前处理的时间*/

privateCalendar mCurrenCalendar;/**

* 传回农历 year年的总天数

*

* @param year

* 将要计算的年份

* @return 返回传入年份的总天数*/

private static int yearDays(intyear) {int i, sum = 348;for (i = 0x8000; i > 0x8; i >>= 1) {if ((LUNAR_INFO[year - 1900] & i) != 0)

sum+= 1;

}return (sum +leapDays(year));

}/**

* 传回农历 year年闰月的天数

*

* @param year

* 将要计算的年份

* @return 返回 农历 year年闰月的天数*/

private static int leapDays(intyear) {if (leapMonth(year) != 0) {if ((LUNAR_INFO[year - 1900] & 0x10000) != 0)return 30;else

return 29;

}else

return 0;

}/**

* 传回农历 year年闰哪个月 1-12 , 没闰传回 0

*

* @param year

* 将要计算的年份

* @return 传回农历 year年闰哪个月 1-12 , 没闰传回 0*/

private static int leapMonth(intyear) {return (int) (LUNAR_INFO[year - 1900] & 0xf);

}/**

* 传回农历 year年month月的总天数

*

* @param year

* 将要计算的年份

* @param month

* 将要计算的月份

* @return 传回农历 year年month月的总天数*/

private static int monthDays(int year, intmonth) {if ((LUNAR_INFO[year - 1900] & (0x10000 >> month)) == 0)return 29;else

return 30;

}/**

* 传回农历 y年的生肖

*

* @return 传回农历 y年的生肖*/

publicString animalsYear() {

final String[] Animals= new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇","马", "羊", "猴", "鸡", "狗", "猪"};return Animals[(mLuchYear - 4) % 12];

}//====== 传入 月日的offset 传回干支, 0=甲子

private static String cyclicalm(intnum) {

final String[] Gan= new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚","辛", "壬", "癸"};

final String[] Zhi= new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午","未", "申", "酉", "戌", "亥"};return (Gan[num % 10] + Zhi[num % 12]);

}//====== 传入 offset 传回干支, 0=甲子

publicString cyclical() {int num = mLuchYear - 1900 + 36;return(cyclicalm(num));

}/**

* 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数

* dayCyl5:与1900年1月31日相差的天数,再加40 ?

*

* @param cal

* @return*/

publicCalendarUtil(Calendar cal) {

mCurrenCalendar=cal;int leapMonth = 0;

Date baseDate= null;try{

baseDate= chineseDateFormat.parse("1900年1月31日");

}catch(ParseException e) {

e.printStackTrace();//To change body of catch statement use//Options | File Templates.

}//求出和1900年1月31日相差的天数

int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);//用offset减去每农历年的天数//计算当天是农历第几天//i最终结果是农历的年份//offset是当年的第几天

int iYear, daysOfYear = 0;for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {

daysOfYear=yearDays(iYear);

offset-=daysOfYear;

}if (offset < 0) {

offset+=daysOfYear;

iYear--;

}//农历年份

mLuchYear =iYear;

leapMonth= leapMonth(iYear); //闰哪个月,1-12

isLoap = false;//用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天

int iMonth, daysOfMonth = 0;for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {//闰月

if (leapMonth > 0 && iMonth == (leapMonth + 1) && !isLoap) {--iMonth;

isLoap= true;

daysOfMonth=leapDays(mLuchYear);

}elsedaysOfMonth=monthDays(mLuchYear, iMonth);

offset-=daysOfMonth;//解除闰月

if (isLoap && iMonth == (leapMonth + 1))

isLoap= false;if (!isLoap) {

}

}//offset为0时,并且刚才计算的月份是闰月,要校正

if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {if(isLoap) {

isLoap= false;

}else{

isLoap= true;--iMonth;

}

}//offset小于0时,也要校正

if (offset < 0) {

offset+=daysOfMonth;--iMonth;

}

mLuchMonth=iMonth;

mLuchDay= offset + 1;

}/**

* 返化成中文格式

*

* @param day

* @return*/

public static String getChinaDayString(intday) {

String chineseTen[]= { "初", "十", "廿", "卅"};int n = day % 10 == 0 ? 9 : day % 10 - 1;if (day > 30)return "";if (day == 10)return "初十";else

return chineseTen[day / 10] +CHINESE_NUMBER[n];

}/**

* 用于显示农历的初几这种格式

*

* @return 农历的日期*/

publicString toString() {

String message= "";//int n = mLuchDay % 10 == 0 ? 9 : mLuchDay % 10 - 1;

message =getChinaCalendarMsg(mLuchYear, mLuchMonth, mLuchDay);if(StringUtil.isNullOrEmpty(message)) {

String solarMsg= newSolarTermsUtil(mCurrenCalendar)

.getSolartermsMsg();//判断当前日期是否为节气

if (!StringUtil.isNullOrEmpty(solarMsg)) {

message=solarMsg;

}else{/**

* 判断当前日期是否为公历节日*/String gremessage= newGregorianUtil(mCurrenCalendar)

.getGremessage();if (!StringUtil.isNullOrEmpty(gremessage)) {

message=gremessage;

}else if (mLuchDay == 1) {

message= CHINESE_NUMBER[mLuchMonth - 1] + "月";

}else{

message=getChinaDayString(mLuchDay);

}

}

}returnmessage;

}/**

* 返回农历的年月日

*

* @return 农历的年月日格式*/

publicString getDay() {return (isLoap ? "闰" : "") + CHINESE_NUMBER[mLuchMonth - 1] + "月"

+getChinaDayString(mLuchDay);

}/**

* 把calendar转化为当前年月日

*

* @param calendar

* Calendar

* @return 返回成转换好的 年月日格式*/

public staticString getDay(Calendar calendar) {returnsimpleDateFormat.format(calendar.getTime());

}/**

* 用于比对二个日期的大小

*

* @param compareDate

* 将要比对的时间

* @param currentDate

* 当前时间

* @return true 表示大于当前时间 false 表示小于当前时间*/

public staticboolean compare(Date compareDate, Date currentDate) {returnchineseDateFormat.format(compareDate).compareTo(

chineseDateFormat.format(currentDate))>= 0;

}/**

* 获取当前周几

*

* @param calendar

* @return*/

public staticString getWeek(Calendar calendar) {return "周" + WEEK_NUMBER[calendar.get(Calendar.DAY_OF_WEEK) - 1] + "";

}/**

* 将当前时间转换成要展示的形式

*

* @param calendar

* @return*/

public staticString getCurrentDay(Calendar calendar) {return getDay(calendar) + "农历" + newCalendarUtil(calendar).getDay()+ " " +getWeek(calendar);

}/**

* 用于获取中国的传统节日

*

* @param month

* 农历的月

* @param day

* 农历日

* @return 中国传统节日*/

private String getChinaCalendarMsg(int year, int month, intday) {

String message= "";if (((month) == 1) && day == 1) {

message= "春节";

}else if (((month) == 1) && day == 15) {

message= "元宵";

}else if (((month) == 5) && day == 5) {

message= "端午";

}else if ((month == 7) && day == 7) {

message= "七夕";

}else if (((month) == 8) && day == 15) {

message= "中秋";

}else if ((month == 9) && day == 9) {

message= "重阳";

}else if ((month == 12) && day == 8) {

message= "腊八";

}else{if (month == 12) {if ((((monthDays(year, month) == 29) && day == 29))|| ((((monthDays(year, month) == 30) && day == 30)))) {

message= "除夕";

}

}

}returnmessage;

}

}/**

* 字符串的处理类*/

classStringUtil {/**

* 判断是否为null或空值

*

* @param str

* String

* @return true or false*/

public staticboolean isNullOrEmpty(String str) {return str == null || str.trim().length() == 0;

}/**

* 判断str1和str2是否相同

*

* @param str1

* str1

* @param str2

* str2

* @return true or false*/

public staticboolean equals(String str1, String str2) {return str1 == str2 || str1 != null &&str1.equals(str2);

}/**

* 判断str1和str2是否相同(不区分大小写)

*

* @param str1

* str1

* @param str2

* str2

* @return true or false*/

public staticboolean equalsIgnoreCase(String str1, String str2) {return str1 != null &&str1.equalsIgnoreCase(str2);

}/**

* 判断字符串str1是否包含字符串str2

*

* @param str1

* 源字符串

* @param str2

* 指定字符串

* @return true源字符串包含指定字符串,false源字符串不包含指定字符串*/

public staticboolean contains(String str1, String str2) {return str1 != null &&str1.contains(str2);

}/**

* 判断字符串是否为空,为空则返回一个空值,不为空则返回原字符串

*

* @param str

* 待判断字符串

* @return 判断后的字符串*/

public staticString getString(String str) {return str == null ? "": str;

}

}/**

* 主要用于把公历日期处理成24节气*/

classSolarTermsUtil {/**

* 计算得到公历的年份*/

private intgregorianYear;/**

* 计算得到公历的月份*/

private intgregorianMonth;/**

* 用于计算得到公历的日期*/

private intgregorianDate;private intchineseYear;private intchineseMonth;private intchineseDate;//初始日,公历农历对应日期://公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日

private static int baseYear = 1901;private static int baseMonth = 1;private static int baseDate = 1;private static int baseIndex = 0;private static int baseChineseYear = 4598 - 1;private static int baseChineseMonth = 11;private static int baseChineseDate = 11;private static char[] daysInGregorianMonth = { 31, 28, 31, 30, 31, 30, 31,31, 30, 31, 30, 31};private intsectionalTerm;private intprincipleTerm;private static char[][] sectionalTermMap ={

{7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5,5, 5, 5, 4, 5, 5},

{5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3,3, 4, 4, 3, 3, 3},

{6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,5, 5, 4, 5, 5, 5, 5},

{5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4,4, 5, 4, 4, 4, 4, 5},

{6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,5, 5, 4, 5, 5, 5, 5},

{6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5,5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5},

{7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,7, 7, 6, 6, 6, 7, 7},

{8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7},

{8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,7, 7, 6, 7, 7, 7, 7},

{9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8,8, 8, 7, 7, 8, 8, 8},

{8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7,7, 7, 6, 6, 7, 7, 7},

{7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,7, 7, 6, 6, 6, 7, 7} };private static char[][] sectionalTermYear ={

{13, 49, 85, 117, 149, 185, 201, 250, 250},

{13, 45, 81, 117, 149, 185, 201, 250, 250},

{13, 48, 84, 112, 148, 184, 200, 201, 250},

{13, 45, 76, 108, 140, 172, 200, 201, 250},

{13, 44, 72, 104, 132, 168, 200, 201, 250},

{5, 33, 68, 96, 124, 152, 188, 200, 201},

{29, 57, 85, 120, 148, 176, 200, 201, 250},

{13, 48, 76, 104, 132, 168, 196, 200, 201},

{25, 60, 88, 120, 148, 184, 200, 201, 250},

{16, 44, 76, 108, 144, 172, 200, 201, 250},

{28, 60, 92, 124, 160, 192, 200, 201, 250},

{17, 53, 85, 124, 156, 188, 200, 201, 250} };private static char[][] principleTermMap ={

{21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20,20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20},

{20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19,19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18},

{21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21,20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20},

{20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20,19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20},

{21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21,20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21},

{22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22,21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21},

{23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23,22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23},

{23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23},

{23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23},

{24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24,23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23},

{23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23,22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22},

{22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22,21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22} };private static char[][] principleTermYear ={

{13, 45, 81, 113, 149, 185, 201},

{21, 57, 93, 125, 161, 193, 201},

{21, 56, 88, 120, 152, 188, 200, 201},

{21, 49, 81, 116, 144, 176, 200, 201},

{17, 49, 77, 112, 140, 168, 200, 201},

{28, 60, 88, 116, 148, 180, 200, 201},

{25, 53, 84, 112, 144, 172, 200, 201},

{29, 57, 89, 120, 148, 180, 200, 201},

{17, 45, 73, 108, 140, 168, 200, 201},

{28, 60, 92, 124, 160, 192, 200, 201},

{16, 44, 80, 112, 148, 180, 200, 201},

{17, 53, 88, 120, 156, 188, 200, 201} };private static char[] chineseMonths ={//农历月份大小压缩表,两个字节表示一年。两个字节共十六个二进制位数,//前四个位数表示闰月月份,后十二个位数表示十二个农历月份的大小。

0x00, 0x04, 0xad, 0x08, 0x5a, 0x01, 0xd5, 0x54, 0xb4, 0x09, 0x64,0x05, 0x59, 0x45, 0x95, 0x0a, 0xa6, 0x04, 0x55, 0x24, 0xad, 0x08,0x5a, 0x62, 0xda, 0x04, 0xb4, 0x05, 0xb4, 0x55, 0x52, 0x0d, 0x94,0x0a, 0x4a, 0x2a, 0x56, 0x02, 0x6d, 0x71, 0x6d, 0x01, 0xda, 0x02,0xd2, 0x52, 0xa9, 0x05, 0x49, 0x0d, 0x2a, 0x45, 0x2b, 0x09, 0x56,0x01, 0xb5, 0x20, 0x6d, 0x01, 0x59, 0x69, 0xd4, 0x0a, 0xa8, 0x05,0xa9, 0x56, 0xa5, 0x04, 0x2b, 0x09, 0x9e, 0x38, 0xb6, 0x08, 0xec,0x74, 0x6c, 0x05, 0xd4, 0x0a, 0xe4, 0x6a, 0x52, 0x05, 0x95, 0x0a,0x5a, 0x42, 0x5b, 0x04, 0xb6, 0x04, 0xb4, 0x22, 0x6a, 0x05, 0x52,0x75, 0xc9, 0x0a, 0x52, 0x05, 0x35, 0x55, 0x4d, 0x0a, 0x5a, 0x02,0x5d, 0x31, 0xb5, 0x02, 0x6a, 0x8a, 0x68, 0x05, 0xa9, 0x0a, 0x8a,0x6a, 0x2a, 0x05, 0x2d, 0x09, 0xaa, 0x48, 0x5a, 0x01, 0xb5, 0x09,0xb0, 0x39, 0x64, 0x05, 0x25, 0x75, 0x95, 0x0a, 0x96, 0x04, 0x4d,0x54, 0xad, 0x04, 0xda, 0x04, 0xd4, 0x44, 0xb4, 0x05, 0x54, 0x85,0x52, 0x0d, 0x92, 0x0a, 0x56, 0x6a, 0x56, 0x02, 0x6d, 0x02, 0x6a,0x41, 0xda, 0x02, 0xb2, 0xa1, 0xa9, 0x05, 0x49, 0x0d, 0x0a, 0x6d,0x2a, 0x09, 0x56, 0x01, 0xad, 0x50, 0x6d, 0x01, 0xd9, 0x02, 0xd1,0x3a, 0xa8, 0x05, 0x29, 0x85, 0xa5, 0x0c, 0x2a, 0x09, 0x96, 0x54,0xb6, 0x08, 0x6c, 0x09, 0x64, 0x45, 0xd4, 0x0a, 0xa4, 0x05, 0x51,0x25, 0x95, 0x0a, 0x2a, 0x72, 0x5b, 0x04, 0xb6, 0x04, 0xac, 0x52,0x6a, 0x05, 0xd2, 0x0a, 0xa2, 0x4a, 0x4a, 0x05, 0x55, 0x94, 0x2d,0x0a, 0x5a, 0x02, 0x75, 0x61, 0xb5, 0x02, 0x6a, 0x03, 0x61, 0x45,0xa9, 0x0a, 0x4a, 0x05, 0x25, 0x25, 0x2d, 0x09, 0x9a, 0x68, 0xda,0x08, 0xb4, 0x09, 0xa8, 0x59, 0x54, 0x03, 0xa5, 0x0a, 0x91, 0x3a,0x96, 0x04, 0xad, 0xb0, 0xad, 0x04, 0xda, 0x04, 0xf4, 0x62, 0xb4,0x05, 0x54, 0x0b, 0x44, 0x5d, 0x52, 0x0a, 0x95, 0x04, 0x55, 0x22,0x6d, 0x02, 0x5a, 0x71, 0xda, 0x02, 0xaa, 0x05, 0xb2, 0x55, 0x49,0x0b, 0x4a, 0x0a, 0x2d, 0x39, 0x36, 0x01, 0x6d, 0x80, 0x6d, 0x01,0xd9, 0x02, 0xe9, 0x6a, 0xa8, 0x05, 0x29, 0x0b, 0x9a, 0x4c, 0xaa,0x08, 0xb6, 0x08, 0xb4, 0x38, 0x6c, 0x09, 0x54, 0x75, 0xd4, 0x0a,0xa4, 0x05, 0x45, 0x55, 0x95, 0x0a, 0x9a, 0x04, 0x55, 0x44, 0xb5,0x04, 0x6a, 0x82, 0x6a, 0x05, 0xd2, 0x0a, 0x92, 0x6a, 0x4a, 0x05,0x55, 0x0a, 0x2a, 0x4a, 0x5a, 0x02, 0xb5, 0x02, 0xb2, 0x31, 0x69,0x03, 0x31, 0x73, 0xa9, 0x0a, 0x4a, 0x05, 0x2d, 0x55, 0x2d, 0x09,0x5a, 0x01, 0xd5, 0x48, 0xb4, 0x09, 0x68, 0x89, 0x54, 0x0b, 0xa4,0x0a, 0xa5, 0x6a, 0x95, 0x04, 0xad, 0x08, 0x6a, 0x44, 0xda, 0x04,0x74, 0x05, 0xb0, 0x25, 0x54, 0x03};/**

* 用于保存24节气*/

private static String[] principleTermNames = { "大寒", "雨水", "春分", "谷雨","小满", "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至"};/**

* 用于保存24节气*/

private static String[] sectionalTermNames = { "小寒", "立春", "惊蛰", "清明","立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪"};publicSolarTermsUtil(Calendar calendar) {

gregorianYear= calendar.get(Calendar.YEAR);

gregorianMonth= calendar.get(Calendar.MONTH) + 1;

gregorianDate= calendar.get(Calendar.DATE);

computeChineseFields();

computeSolarTerms();

}public intcomputeChineseFields() {if (gregorianYear < 1901 || gregorianYear > 2100)return 1;int startYear =baseYear;int startMonth =baseMonth;int startDate =baseDate;

chineseYear=baseChineseYear;

chineseMonth=baseChineseMonth;

chineseDate=baseChineseDate;//第二个对应日,用以提高计算效率//公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日

if (gregorianYear >= 2000) {

startYear= baseYear + 99;

startMonth= 1;

startDate= 1;

chineseYear= baseChineseYear + 99;

chineseMonth= 11;

chineseDate= 25;

}int daysDiff = 0;for (int i = startYear; i < gregorianYear; i++) {

daysDiff+= 365;if(isGregorianLeapYear(i))

daysDiff+= 1; //leap year

}for (int i = startMonth; i < gregorianMonth; i++) {

daysDiff+=daysInGregorianMonth(gregorianYear, i);

}

daysDiff+= gregorianDate -startDate;

chineseDate+=daysDiff;int lastDate =daysInChineseMonth(chineseYear, chineseMonth);int nextMonth =nextChineseMonth(chineseYear, chineseMonth);while (chineseDate >lastDate) {if (Math.abs(nextMonth)

chineseYear++;

chineseMonth=nextMonth;

chineseDate-=lastDate;

lastDate=daysInChineseMonth(chineseYear, chineseMonth);

nextMonth=nextChineseMonth(chineseYear, chineseMonth);

}return 0;

}public intcomputeSolarTerms() {if (gregorianYear < 1901 || gregorianYear > 2100)return 1;

sectionalTerm=sectionalTerm(gregorianYear, gregorianMonth);

principleTerm=principleTerm(gregorianYear, gregorianMonth);return 0;

}public static int sectionalTerm(int y, intm) {if (y < 1901 || y > 2100)return 0;int index = 0;int ry = y - baseYear + 1;while (ry >= sectionalTermYear[m - 1][index])

index++;int term = sectionalTermMap[m - 1][4 * index + ry % 4];if ((ry == 121) && (m == 4))

term= 5;if ((ry == 132) && (m == 4))

term= 5;if ((ry == 194) && (m == 6))

term= 6;returnterm;

}public static int principleTerm(int y, intm) {if (y < 1901 || y > 2100)return 0;int index = 0;int ry = y - baseYear + 1;while (ry >= principleTermYear[m - 1][index])

index++;int term = principleTermMap[m - 1][4 * index + ry % 4];if ((ry == 171) && (m == 3))

term= 21;if ((ry == 181) && (m == 5))

term= 21;returnterm;

}/**

* 用于判断输入的年份是否为闰年

*

* @param year

* 输入的年份

* @return true 表示闰年*/

public static boolean isGregorianLeapYear(intyear) {

boolean isLeap= false;if (year % 4 == 0)

isLeap= true;if (year % 100 == 0)

isLeap= false;if (year % 400 == 0)

isLeap= true;returnisLeap;

}public static int daysInGregorianMonth(int y, intm) {int d = daysInGregorianMonth[m - 1];if (m == 2 &&isGregorianLeapYear(y))

d++; //公历闰年二月多一天

returnd;

}public static int daysInChineseMonth(int y, intm) {//注意:闰月 m < 0

int index = y - baseChineseYear +baseIndex;int v = 0;int l = 0;int d = 30;if (1 <= m && m <= 8) {

v= chineseMonths[2 *index];

l= m - 1;if (((v >> l) & 0x01) == 1)

d= 29;

}else if (9 <= m && m <= 12) {

v= chineseMonths[2 * index + 1];

l= m - 9;if (((v >> l) & 0x01) == 1)

d= 29;

}else{

v= chineseMonths[2 * index + 1];

v= (v >> 4) & 0x0F;if (v !=Math.abs(m)) {

d= 0;

}else{

d= 29;for (int i = 0; i < bigLeapMonthYears.length; i++) {if (bigLeapMonthYears[i] ==index) {

d= 30;break;

}

}

}

}returnd;

}public static int nextChineseMonth(int y, intm) {int n = Math.abs(m) + 1;if (m > 0) {int index = y - baseChineseYear +baseIndex;int v = chineseMonths[2 * index + 1];

v= (v >> 4) & 0x0F;if (v ==m)

n= -m;

}if (n == 13)

n= 1;returnn;

}//大闰月的闰年年份

private static int[] bigLeapMonthYears = { 6, 14, 19, 25, 33, 36, 38, 41,44, 52, 55, 79, 117, 136, 147, 150, 155, 158, 185, 193};/**

* 用于获取24节气的值

*

* @return 24节气的值*/

publicString getSolartermsMsg() {

String str= "";

String gm=String.valueOf(gregorianMonth);if (gm.length() == 1)

gm= ' ' +gm;

String cm=String.valueOf(Math.abs(chineseMonth));if (cm.length() == 1)

cm= ' ' +cm;

String gd=String.valueOf(gregorianDate);if (gd.length() == 1)

gd= ' ' +gd;

String cd=String.valueOf(chineseDate);if (cd.length() == 1)

cd= ' ' +cd;if (gregorianDate ==sectionalTerm) {

str= " " + sectionalTermNames[gregorianMonth - 1];

}else if (gregorianDate ==principleTerm) {

str= " " + principleTermNames[gregorianMonth - 1];

}returnstr;

}

}/**

* 对公历日期的处理类*/

classGregorianUtil {private final static String[][] GRE_FESTVIAL ={//一月

{ "元旦", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//二月

{ "", "", "", "", "", "", "", "", "", "", "", "", "", "情人", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", ""},//三月

{ "", "", "", "", "", "", "", "妇女", "", "", "", "植树", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", "",""},//四月

{ "愚人", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//五月

{ "劳动", "", "", "青年", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", "",""},//六月

{ "儿童", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//七月

{ "建党", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//八月

{ "建军", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//九月

{ "", "", "", "", "", "", "", "", "", "教师", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//十月

{ "国庆", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//十一月

{ "", "", "", "", "", "", "", "", "", "", "光棍", "", "", "", "", "","", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},//十二月

{ "艾滋病", "", "", "", "", "", "", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "", "圣诞", "", "", "", "","", ""}, };private intmMonth;private intmDay;publicGregorianUtil(Calendar calendar) {

mMonth= calendar.get(Calendar.MONTH);

mDay= calendar.get(Calendar.DATE);

}publicString getGremessage() {return GRE_FESTVIAL[mMonth][mDay - 1];

}

}classNumberHelper {public static String LeftPad_Tow_Zero(intstr) {

java.text.DecimalFormat format= new java.text.DecimalFormat("00");returnformat.format(str);

}

}/*****************将代码拷贝到一个文件中(end)***********************/

//辅助类

package cc.util.android.view;

import android.content.Context;

import android.content.res.Resources;

import android.view.View;

import android.view.ViewGroup;

import android.view.ViewGroup.MarginLayoutParams;

import android.widget.AbsListView;

import android.widget.GridView;

import android.widget.ListAdapter;

import android.widget.ListView;/**

* @author wangcccong

* @version 1.140122

* create at:2014-02-26*/

public classViewUtil {/**

* 获取屏幕的宽度

* @param context

* @return*/

public intgetScreenWidth(Context context) {

Resources res=context.getResources();returnres.getDisplayMetrics().widthPixels;

}/**

* 获取屏幕高度

* @param context

* @return*/

public intgetScreenHeight(Context context) {

Resources res=context.getResources();returnres.getDisplayMetrics().heightPixels;

}/**

* 描述:根据分辨率获得字体大小.

*

* @param screenWidth the screen width

* @param screenHeight the screen height

* @param textSize the text size

* @return the int*/

public static int resizeTextSize(int screenWidth,int screenHeight,inttextSize){float ratio = 1;try{float ratioWidth = (float)screenWidth / 480;float ratioHeight = (float)screenHeight / 800;

ratio=Math.min(ratioWidth, ratioHeight);

}catch(Exception e) {

}return Math.round(textSize *ratio);

}/**

*

* 描述:dip转换为px

* @param context

* @param dipValue

* @return

* @throws*/

public static int dip2px(Context context, floatdipValue) {

finalfloat scale =context.getResources().getDisplayMetrics().density;return Math.round(dipValue *scale);

}/**

*

* 描述:px转换为dip

* @param context

* @param pxValue

* @return

* @throws*/

public static int px2dip(Context context, floatpxValue) {

finalfloat scale =context.getResources().getDisplayMetrics().density;return Math.round(pxValue /scale);

}/**

*

* 描述:px转换为sp

* @param context

* @param pxValue

* @return

* @throws*/

public static int px2sp(Context context, floatpxValue) {

finalfloat scale =context.getResources().getDisplayMetrics().scaledDensity;return Math.round(pxValue /scale);

}/**

*

* 描述:sp转换为px

* @param context

* @param spValue

* @return

* @throws*/

public static int sp2px(Context context, floatspValue) {

finalfloat scale =context.getResources().getDisplayMetrics().scaledDensity;return Math.round(spValue *scale);

}

}//使用方法//在xml中添加控件

android:id="@+id/calendar"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/white"/>

//在代码中

CalendarView calendarView =(CalendarView) findViewById(R.id.calendar);//设置标注日期

List markDates = new ArrayList();

markDates.add(newDate());

calendarView.setMarkDates(markDates);//设置点击操作

calendarView.setOnCalendarViewListener(newOnCalendarViewListener() {

@Overridepublic voidonCalendarItemClick(CalendarView view, Date date) {//TODO Auto-generated method stub

final SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);

Toast.makeText(MainActivity.this, format.format(date), Toast.LENGTH_SHORT).show();

}

农历 Android Java 节气_Android自定义日历,可以点击、标注日期、节气、旧历等相关推荐

  1. android java 圆角_Android自定义View实现带4圆角或者2圆角的效果

    1 问题 实现任意view经过自定义带4圆角或者2圆角的效果 2 原理 1) 实现view 4圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 2) 实现view上2圆角 我们只需要 ...

  2. android程序日历layout,Android使用GridLayout绘制自定义日历控件

    效果图 思路:就是先设置Gridlayout的行列数,然后往里面放置一定数目的自定义日历按钮控件,最后实现日历逻辑就可以了. 步骤: 第一步:自定义日历控件(初步) 第二步:实现自定义单个日期按钮控件 ...

  3. Android 使用RecycleView打造自定义日历

    1 大致思路 1) 初始化日历数据,作为list传入到RecyclerView.Adapter 2) 重写RecyclerView的onTouchEvent方法,监听手势的改变,然后更改list数据, ...

  4. android java标准时间_Android 时间 日期 相关

    一.概念 参考时间标准总结 IAT.UT.UTC.GMT.夏令时 1.格林尼治标准时间:Greenwich Mean Time(简称 GMT) GMT 以格林尼治天文台经线为 0 度经线,将世界分为 ...

  5. android java包_android SDk中常用的java包介绍

    下面是android SDK中API中的主要java包的功能简介: android.app :提供高层的程序模型.提供基本的运行环境 android.content :包含各种的对设备上的数据进行访问 ...

  6. android java 退出程序_android开发两种退出程序方式(killProcess,System.exit)

    KillProcess: 在android中我们如果想要程序的进程结束可以这样写: android.os.Process.killProcess(android.os.Process.myPid()) ...

  7. android 斜线 绘制_Android 自定义 斜线进度框 ,雨点式背景

    import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; impor ...

  8. android java加密_Android、iOS和Java通用的AES128加密解密示例代码

    前言 移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如android和iOS的打交道.为了让数据交互更安全,我们需要对数据进行加密传输. 这篇文章给大家分享AES的加密和解密. ...

  9. android java框架_Android 框架简介:java框架

    Android 框架简介:java框架 2015-10-15 14:43  来源: 正保IT教育网整理 这里简单的介绍了Android的java环境基础,在后面一节中会结合具体的实例来理解这一节的内容 ...

最新文章

  1. 使用vue-seamless-scroll自动滚动插件复制出来的数据点击事件无效的解决办法
  2. eventfd man
  3. pupload 文件分块 php,基于Plupload实现Base64分割的文件上传方案
  4. 特斯拉地图数据服务以后由百度地图提供
  5. poj 3321 Apple Tree 树状数组
  6. SDWebImage之SDImageCache
  7. python中的对象有哪些_python中的对象
  8. 英语单词词性顺口溜_英语单词词性顺口溜
  9. 七款好看文字样式纯css
  10. u盘怎么安装计算机系统,教您如何用u盘装系统
  11. IBM Spectrum LSF-手册
  12. unity渲染篇:烘焙模型贴图
  13. C语言程序设计——从入门到进阶,C语言程序设计——从入门到进阶-巨同升主编.pdf(3)...
  14. 黑马程序员——java 泛型
  15. 张驰咨询:关于企业选择六西格玛绿带培训人员,你需要知道这些
  16. 第 三 十 八 天:Apache 选 项 和 模 块 问 题 附:php
  17. 计算机与网络安全经历了几个阶段,计算机历史上计算范式经历了哪六个发展阶段?...
  18. 11省市联动 828 B2B企业节启动仪式(伟仕佳杰站)顺利举办
  19. 【小技巧】酒店Wifi不弹出登陆方案(Mac)
  20. pycharm 使用conda虚拟环境

热门文章

  1. 湖北一公司发生闪爆事故,这套化工厂巡检系统你有吗?
  2. MySQL小白快速入门笔记
  3. 相机照片大小设置_我应该为运动照片使用哪些相机设置?
  4. docker命令介绍,镜像制作,容器启动,进入容器操作等
  5. 如何修改桌面的存放路径?(将桌面放到D盘或E盘)
  6. 什么是软件测试及其分类?
  7. 浅谈四种常见的agv导航方式及各自的优缺点
  8. 深圳市专精特新企业申报条件及各区奖励政策重点介绍,补贴20-200万
  9. Linux系统 ·虚拟机安装· SecureCRT远程连接器
  10. 【无标题】c++日常练习(16)——从中序与前序遍历序列构造二叉树