1. [图片] 9A59974C-47D4-47E3-8136-3F873EB9BBDC.jpg

2. [图片] left_arrow_pre.png

3. [图片] left_arrow.png

4. [图片] right_arrow_pre.png

5. [图片] right_arrow.png

/****************从此出开始将代码拷贝到一个文件中*******************/
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
* <br>update at: Mon, 23 Sep. 2014
* &nbsp;&nbsp;新增日期标注和点击操作
*/
public class CalendarView extends LinearLayout implements OnTouchListener,
AnimationListener, OnGestureListener { /**
* 点击日历
*/
public interface OnCalendarViewListener {
void onCalendarItemClick(CalendarView view, Date date);
} /** 顶部控件所占高度 */
private final static int TOP_HEIGHT = ;
/** 日历item中默认id从0xff0000开始 */
private final static int DEFAULT_ID = 0xff0000; // 判断手势用
private static final int SWIPE_MIN_DISTANCE = ;
private static final int SWIPE_MAX_OFF_PATH = ;
private static final int SWIPE_THRESHOLD_VELOCITY = ; // 屏幕宽度和高度
private int screenWidth; // 动画
private Animation slideLeftIn;
private Animation slideLeftOut;
private Animation slideRightIn;
private Animation slideRightOut;
private ViewFlipper viewFlipper;
private GestureDetector mGesture = null; /** 上一月 */
private GridView gView1;
/** 当月 */
private GridView gView2;
/** 下一月 */
private GridView gView3; boolean bIsSelection = false;// 是否是选择事件发生
private Calendar calStartDate = Calendar.getInstance();// 当前显示的日历
private Calendar calSelected = Calendar.getInstance(); // 选择的日历
private CalendarGridViewAdapter gAdapter;
private CalendarGridViewAdapter gAdapter1;
private CalendarGridViewAdapter gAdapter3; private LinearLayout mMainLayout;
private TextView mTitle; // 显示年月 private int iMonthViewCurrentMonth = ; // 当前视图月
private int iMonthViewCurrentYear = ; // 当前视图年 private static final int caltitleLayoutID = ; // title布局ID
private static final int calLayoutID = ; // 日历布局ID
private Context mContext; /** 标注日期 */
private final List<Date> markDates; private OnCalendarViewListener mListener; public CalendarView(Context context) {
this(context, null);
} public CalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
mContext = context;
markDates = new ArrayList<Date>();
init();
} // 初始化相关工作
protected void init() {
// 得到屏幕的宽度
screenWidth = mContext.getResources().getDisplayMetrics().widthPixels; // 滑动的动画
slideLeftIn = new TranslateAnimation(screenWidth, , , );
slideLeftIn.setDuration();
slideLeftIn.setAnimationListener(this);
slideLeftOut = new TranslateAnimation(, -screenWidth, , );
slideLeftOut.setDuration();
slideLeftOut.setAnimationListener(this);
slideRightIn = new TranslateAnimation(-screenWidth, , , );
slideRightIn.setDuration();
slideRightIn.setAnimationListener(this);
slideRightOut = new TranslateAnimation(, screenWidth, , );
slideRightOut.setDuration();
slideRightOut.setAnimationListener(this); // 手势操作
mGesture = new GestureDetector(mContext, this); // 获取到当前日期
UpdateStartDateForMonth();
// 绘制界面
setOrientation(LinearLayout.HORIZONTAL);
mMainLayout = new LinearLayout(mContext);
LinearLayout.LayoutParams main_params = new LinearLayout.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 = new ViewFlipper(mContext);
RelativeLayout.LayoutParams fliper_params = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
fliper_params.addRule(RelativeLayout.BELOW, caltitleLayoutID);
mMainLayout.addView(viewFlipper, fliper_params);
generateClaendarGirdView(); // 最下方的一条线条
LinearLayout br = new LinearLayout(mContext);
br.setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));
LinearLayout.LayoutParams params_br = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, );
mMainLayout.addView(br, params_br);
} /** 生成顶部控件 */
@SuppressWarnings("deprecation")
private void generateTopView() {
// 顶部显示上一个下一个,以及当前年月
RelativeLayout top = new RelativeLayout(mContext);
top.setBackgroundColor(Color.argb(0xff, 0x0e, 0x6b, 0xc2));
LinearLayout.LayoutParams top_params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
ViewUtil.dip2px(mContext, TOP_HEIGHT));
top.setLayoutParams(top_params);
mMainLayout.addView(top);
// 左方按钮、中间日期显示、右方按钮
mTitle = new TextView(mContext);
android.widget.RelativeLayout.LayoutParams title_params = new android.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();
mTitle.setFocusableInTouchMode(true);
mTitle.setMarqueeRepeatLimit(-);
mTitle.setEllipsize(TruncateAt.MARQUEE);
mTitle.setSingleLine(true);
mTitle.setGravity(Gravity.CENTER);
mTitle.setHorizontallyScrolling(true);
mTitle.setText("2014年9月");
top.addView(mTitle); // 左方按钮
ImageButton mLeftView = new ImageButton(mContext);
StateListDrawable stateListDrawableL = new StateListDrawable();
Drawable lDrawableNor = new BitmapDrawable(mContext.getResources(),
BitmapFactory.decodeStream(CalendarView.class
.getResourceAsStream("image/left_arrow.png")));
Drawable lDrawablePre = new BitmapDrawable(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 = new android.widget.RelativeLayout.LayoutParams(
ViewUtil.dip2px(mContext, ), ViewUtil.dip2px(mContext, ));
leftPP.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
leftPP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
leftPP.setMargins(, , , );
mLeftView.setLayoutParams(leftPP);
mLeftView.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
viewFlipper.setInAnimation(slideRightIn);
viewFlipper.setOutAnimation(slideRightOut);
viewFlipper.showPrevious();
setPrevViewItem();
}
});
top.addView(mLeftView); // 右方按钮
ImageButton mRightView = new ImageButton(mContext);
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable rDrawableNor = new BitmapDrawable(mContext.getResources(),
BitmapFactory.decodeStream(CalendarView.class
.getResourceAsStream("image/right_arrow.png")));
Drawable rDrawablePre = new BitmapDrawable(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 = new android.widget.RelativeLayout.LayoutParams(
ViewUtil.dip2px(mContext, ), ViewUtil.dip2px(mContext, ));
rightPP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rightPP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
rightPP.setMargins(, , , );
mRightView.setLayoutParams(rightPP);
mRightView.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
viewFlipper.setInAnimation(slideLeftIn);
viewFlipper.setOutAnimation(slideLeftOut);
viewFlipper.showNext();
setNextViewItem();
}
});
top.addView(mRightView);
} /** 生成中间显示week */
private void generateWeekGirdView() {
GridView gridView = new GridView(mContext);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
gridView.setLayoutParams(params);
gridView.setNumColumns();// 设置每行列数
gridView.setGravity(Gravity.CENTER_VERTICAL);// 位置居中
gridView.setVerticalSpacing();// 垂直间隔
gridView.setHorizontalSpacing();// 水平间隔
gridView.setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4)); int i = screenWidth / ;
int j = screenWidth - (i * );
int x = j / ;
gridView.setPadding(x, , , );// 居中
WeekGridAdapter weekAdapter = new WeekGridAdapter(mContext);
gridView.setAdapter(weekAdapter);// 设置菜单Adapter
mMainLayout.addView(gridView);
} /** 生成底部日历 */
private void generateClaendarGirdView() {
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 = new CalendarGridView(mContext);
tempSelected1.add(Calendar.MONTH, -);
gAdapter1 = new CalendarGridViewAdapter(mContext, tempSelected1,
markDates);
gView1.setAdapter(gAdapter1);// 设置菜单Adapter
gView1.setId(calLayoutID); gView2 = new CalendarGridView(mContext);
gAdapter = new CalendarGridViewAdapter(mContext, tempSelected2,
markDates);
gView2.setAdapter(gAdapter);// 设置菜单Adapter
gView2.setId(calLayoutID); gView3 = new CalendarGridView(mContext);
tempSelected3.add(Calendar.MONTH, );
gAdapter3 = new CalendarGridViewAdapter(mContext, tempSelected3,
markDates);
gView3.setAdapter(gAdapter3);// 设置菜单Adapter
gView3.setId(calLayoutID); gView2.setOnTouchListener(this);
gView1.setOnTouchListener(this);
gView3.setOnTouchListener(this); if (viewFlipper.getChildCount() != ) {
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) + ) + "月";
mTitle.setText(title);
} // 上一个月
private void setPrevViewItem() {
iMonthViewCurrentMonth--;// 当前选择月--
// 如果当前月为负数的话显示上一年
if (iMonthViewCurrentMonth == -) {
iMonthViewCurrentMonth = ;
iMonthViewCurrentYear--;
}
calStartDate.set(Calendar.DAY_OF_MONTH, ); // 设置日为当月1日
calStartDate.set(Calendar.MONTH, iMonthViewCurrentMonth); // 设置月
calStartDate.set(Calendar.YEAR, iMonthViewCurrentYear); // 设置年
} // 下一个月
private void setNextViewItem() {
iMonthViewCurrentMonth++;
if (iMonthViewCurrentMonth == ) {
iMonthViewCurrentMonth = ;
iMonthViewCurrentYear++;
}
calStartDate.set(Calendar.DAY_OF_MONTH, );
calStartDate.set(Calendar.MONTH, iMonthViewCurrentMonth);
calStartDate.set(Calendar.YEAR, iMonthViewCurrentYear);
} // 根据改变的日期更新日历
// 填充日历控件用
private void UpdateStartDateForMonth() {
calStartDate.set(Calendar.DATE, ); // 设置成当月第一天
iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到当前日历显示的月
iMonthViewCurrentYear = calStartDate.get(Calendar.YEAR);// 得到当前日历显示的年 // 星期一是2 星期天是1 填充剩余天数
int iDay = ;
int iFirstDayOfWeek = Calendar.MONDAY;
int iStartDay = iFirstDayOfWeek;
if (iStartDay == Calendar.MONDAY) {
iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
if (iDay < )
iDay = ;
}
if (iStartDay == Calendar.SUNDAY) {
iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
if (iDay < )
iDay = ;
}
calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);
} /**
* 设置标注的日期
*
* @param markDates
*/
public void setMarkDates(List<Date> markDates) {
this.markDates.clear();
this.markDates.addAll(markDates);
gAdapter.notifyDataSetChanged();
gAdapter1.notifyDataSetChanged();
gAdapter3.notifyDataSetChanged();
} /**
* 设置点击日历监听
*
* @param listener
*/
public void setOnCalendarViewListener(OnCalendarViewListener listener) {
this.mListener = listener;
} @Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
} @SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGesture.onTouchEvent(event);
} @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// 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;
} @Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub } @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
} @Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub } @Override
public boolean 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;
} @Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
generateClaendarGirdView();
} @Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub } @Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub } } /**
* 显示week的布局adapter
*
*/
class WeekGridAdapter extends BaseAdapter { final String[] titles = new String[] { "日", "一", "二", "三", "四", "五", "六" };
private Context mContext; public WeekGridAdapter(Context context) {
this.mContext = context;
} @Override
public int getCount() {
return titles.length;
} @Override
public Object getItem(int position) {
return titles[position];
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView week = new TextView(mContext);
android.view.ViewGroup.LayoutParams week_params = new LayoutParams(
android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.MATCH_PARENT);
week.setLayoutParams(week_params);
week.setPadding(, , , );
week.setGravity(Gravity.CENTER);
week.setFocusable(false);
week.setBackgroundColor(Color.TRANSPARENT); if (position == ) { // 周六
week.setBackgroundColor(Color.argb(0xff, 0x52, 0x9b, 0xd0));
week.setTextColor(Color.WHITE);
} else if (position == ) { // 周日
week.setBackgroundColor(Color.argb(0xff, 0xbc, 0x44, 0x45));
week.setTextColor(Color.WHITE);
} else {
week.setTextColor(Color.BLACK);
}
week.setText(getItem(position) + "");
return week;
}
} /**
* 显示日期的adapter
*/
class CalendarGridViewAdapter extends BaseAdapter { /** 日历item中默认id从0xff0000开始 */
private final static int DEFAULT_ID = 0xff0000;
private Calendar calStartDate = Calendar.getInstance();// 当前显示的日历
private Calendar calSelected = Calendar.getInstance(); // 选择的日历 /** 标注的日期 */
private List<Date> markDates; private Context mContext; private Calendar calToday = Calendar.getInstance(); // 今日
private ArrayList<java.util.Date> titles; private ArrayList<java.util.Date> getDates() { UpdateStartDateForMonth(); ArrayList<java.util.Date> alArrayList = new ArrayList<java.util.Date>(); for (int i = ; i <= ; i++) {
alArrayList.add(calStartDate.getTime());
calStartDate.add(Calendar.DAY_OF_MONTH, );
} return alArrayList;
} // construct
public CalendarGridViewAdapter(Context context, Calendar cal, List<Date> dates) {
calStartDate = cal;
this.mContext = context;
titles = getDates();
this.markDates = dates;
} public CalendarGridViewAdapter(Context context) {
this.mContext = context;
} @Override
public int getCount() {
return titles.size();
} @Override
public Object getItem(int position) {
return titles.get(position);
} @Override
public long getItemId(int position) {
return position;
} @SuppressWarnings("deprecation")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 整个Item
LinearLayout itemLayout = new LinearLayout(mContext);
itemLayout.setId(position + DEFAULT_ID);
itemLayout.setGravity(Gravity.CENTER);
itemLayout.setOrientation();
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 = new LinearLayout.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 = new TextView(mContext);
LinearLayout.LayoutParams chinese_params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
chineseDay.setGravity(Gravity.CENTER_HORIZONTAL);
chineseDay.setTextSize();
CalendarUtil calendarUtil = new CalendarUtil(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;
}
}
}
return itemLayout;
} @Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
} @SuppressWarnings("deprecation")
private Boolean equalsDate(Date date1, Date date2) {
if (date1.getYear() == date2.getYear()
&& date1.getMonth() == date2.getMonth()
&& date1.getDate() == date2.getDate()) {
return true;
} else {
return false;
} } // 根据改变的日期更新日历
// 填充日历控件用
private void UpdateStartDateForMonth() {
calStartDate.set(Calendar.DATE, ); // 设置成当月第一天 // 星期一是2 星期天是1 填充剩余天数
int iDay = ;
int iFirstDayOfWeek = Calendar.MONDAY;
int iStartDay = iFirstDayOfWeek;
if (iStartDay == Calendar.MONDAY) {
iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
if (iDay < )
iDay = ;
}
if (iStartDay == Calendar.SUNDAY) {
iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
if (iDay < )
iDay = ;
}
calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);
calStartDate.add(Calendar.DAY_OF_MONTH, -);// 周日第一位
} public void setSelectedDate(Calendar cal) {
calSelected = cal;
} } /**
* 用于生成日历展示的GridView布局
*/
class CalendarGridView extends GridView { /**
* 当前操作的上下文对象
*/
private Context mContext; /**
* CalendarGridView 构造器
*
* @param context
* 当前操作的上下文对象
*/
public CalendarGridView(Context context) {
super(context);
mContext = context;
initGirdView();
} /**
* 初始化gridView 控件的布局
*/
private void initGirdView() {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
setLayoutParams(params);
setNumColumns();// 设置每行列数
setGravity(Gravity.CENTER_VERTICAL);// 位置居中
setVerticalSpacing();// 垂直间隔
setHorizontalSpacing();// 水平间隔
setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4)); int i = mContext.getResources().getDisplayMetrics().widthPixels / ;
int j = mContext.getResources().getDisplayMetrics().widthPixels
- (i * );
int x = j / ;
setPadding(x, , , );// 居中
}
} /**
* 把公历时间处理成农历时间
*
*/
class CalendarUtil {
/**
* 用于保存中文的月份
*/
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 = new SimpleDateFormat(
"yyyy年MM月dd日");
/**
* 转换为2012-11-22格式
*/
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd"); /**
* 计算得到农历的年份
*/
private int mLuchYear;
/**
* 计算得到农历的月份
*/
private int mLuchMonth; /**
* 计算得到农历的日期
*/
private int mLuchDay; /**
* 用于标识是事为闰年
*/
private boolean isLoap; /**
* 用于记录当前处理的时间
*/
private Calendar mCurrenCalendar; /**
* 传回农历 year年的总天数
*
* @param year
* 将要计算的年份
* @return 返回传入年份的总天数
*/
private static int yearDays(int year) {
int i, sum = ;
for (i = 0x8000; i > 0x8; i >>= ) {
if ((LUNAR_INFO[year - ] & i) != )
sum += ;
}
return (sum + leapDays(year));
} /**
* 传回农历 year年闰月的天数
*
* @param year
* 将要计算的年份
* @return 返回 农历 year年闰月的天数
*/
private static int leapDays(int year) {
if (leapMonth(year) != ) {
if ((LUNAR_INFO[year - ] & 0x10000) != )
return ;
else
return ;
} else
return ;
} /**
* 传回农历 year年闰哪个月 1-12 , 没闰传回 0
*
* @param year
* 将要计算的年份
* @return 传回农历 year年闰哪个月 1-12 , 没闰传回 0
*/
private static int leapMonth(int year) {
return (int) (LUNAR_INFO[year - ] & 0xf);
} /**
* 传回农历 year年month月的总天数
*
* @param year
* 将要计算的年份
* @param month
* 将要计算的月份
* @return 传回农历 year年month月的总天数
*/
private static int monthDays(int year, int month) {
if ((LUNAR_INFO[year - ] & (0x10000 >> month)) == )
return ;
else
return ;
} /**
* 传回农历 y年的生肖
*
* @return 传回农历 y年的生肖
*/
public String animalsYear() {
final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇",
"马", "羊", "猴", "鸡", "狗", "猪" };
return Animals[(mLuchYear - ) % ];
} // ====== 传入 月日的offset 传回干支, 0=甲子
private static String cyclicalm(int num) {
final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚",
"辛", "壬", "癸" };
final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午",
"未", "申", "酉", "戌", "亥" }; return (Gan[num % ] + Zhi[num % ]);
} // ====== 传入 offset 传回干支, 0=甲子
public String cyclical() {
int num = mLuchYear - + ;
return (cyclicalm(num));
} /**
* 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数
* dayCyl5:与1900年1月31日相差的天数,再加40 ?
*
* @param cal
* @return
*/
public CalendarUtil(Calendar cal) {
mCurrenCalendar = cal;
int leapMonth = ;
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 = ;
for (iYear = ; iYear < && offset > ; iYear++) {
daysOfYear = yearDays(iYear);
offset -= daysOfYear;
}
if (offset < ) {
offset += daysOfYear;
iYear--;
}
// 农历年份
mLuchYear = iYear; leapMonth = leapMonth(iYear); // 闰哪个月,1-12
isLoap = false; // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
int iMonth, daysOfMonth = ;
for (iMonth = ; iMonth < && offset > ; iMonth++) {
// 闰月
if (leapMonth > && iMonth == (leapMonth + ) && !isLoap) {
--iMonth;
isLoap = true;
daysOfMonth = leapDays(mLuchYear);
} else
daysOfMonth = monthDays(mLuchYear, iMonth); offset -= daysOfMonth;
// 解除闰月
if (isLoap && iMonth == (leapMonth + ))
isLoap = false;
if (!isLoap) {
}
}
// offset为0时,并且刚才计算的月份是闰月,要校正
if (offset == && leapMonth > && iMonth == leapMonth + ) {
if (isLoap) {
isLoap = false;
} else {
isLoap = true;
--iMonth;
}
}
// offset小于0时,也要校正
if (offset < ) {
offset += daysOfMonth;
--iMonth; }
mLuchMonth = iMonth;
mLuchDay = offset + ;
} /**
* 返化成中文格式
*
* @param day
* @return
*/
public static String getChinaDayString(int day) {
String chineseTen[] = { "初", "十", "廿", "卅" };
int n = day % == ? : day % - ;
if (day > )
return "";
if (day == )
return "初十";
else
return chineseTen[day / ] + CHINESE_NUMBER[n];
} /**
* 用于显示农历的初几这种格式
*
* @return 农历的日期
*/
public String toString() {
String message = "";
// int n = mLuchDay % 10 == 0 ? 9 : mLuchDay % 10 - 1;
message = getChinaCalendarMsg(mLuchYear, mLuchMonth, mLuchDay);
if (StringUtil.isNullOrEmpty(message)) {
String solarMsg = new SolarTermsUtil(mCurrenCalendar)
.getSolartermsMsg();
// 判断当前日期是否为节气
if (!StringUtil.isNullOrEmpty(solarMsg)) {
message = solarMsg;
} else {
/**
* 判断当前日期是否为公历节日
*/
String gremessage = new GregorianUtil(mCurrenCalendar)
.getGremessage();
if (!StringUtil.isNullOrEmpty(gremessage)) {
message = gremessage;
} else if (mLuchDay == ) {
message = CHINESE_NUMBER[mLuchMonth - ] + "月";
} else {
message = getChinaDayString(mLuchDay);
} }
}
return message;
} /**
* 返回农历的年月日
*
* @return 农历的年月日格式
*/
public String getDay() {
return (isLoap ? "闰" : "") + CHINESE_NUMBER[mLuchMonth - ] + "月"
+ getChinaDayString(mLuchDay);
} /**
* 把calendar转化为当前年月日
*
* @param calendar
* Calendar
* @return 返回成转换好的 年月日格式
*/
public static String getDay(Calendar calendar) {
return simpleDateFormat.format(calendar.getTime());
} /**
* 用于比对二个日期的大小
*
* @param compareDate
* 将要比对的时间
* @param currentDate
* 当前时间
* @return true 表示大于当前时间 false 表示小于当前时间
*/
public static boolean compare(Date compareDate, Date currentDate) {
return chineseDateFormat.format(compareDate).compareTo(
chineseDateFormat.format(currentDate)) >= ;
} /**
* 获取当前周几
*
* @param calendar
* @return
*/
public static String getWeek(Calendar calendar) {
return "周" + WEEK_NUMBER[calendar.get(Calendar.DAY_OF_WEEK) - ] + "";
} /**
* 将当前时间转换成要展示的形式
*
* @param calendar
* @return
*/
public static String getCurrentDay(Calendar calendar) {
return getDay(calendar) + " 农历" + new CalendarUtil(calendar).getDay()
+ " " + getWeek(calendar);
} /**
* 用于获取中国的传统节日
*
* @param month
* 农历的月
* @param day
* 农历日
* @return 中国传统节日
*/
private String getChinaCalendarMsg(int year, int month, int day) {
String message = "";
if (((month) == ) && day == ) {
message = "春节";
} else if (((month) == ) && day == ) {
message = "元宵";
} else if (((month) == ) && day == ) {
message = "端午";
} else if ((month == ) && day == ) {
message = "七夕";
} else if (((month) == ) && day == ) {
message = "中秋";
} else if ((month == ) && day == ) {
message = "重阳";
} else if ((month == ) && day == ) {
message = "腊八";
} else {
if (month == ) {
if ((((monthDays(year, month) == ) && day == ))
|| ((((monthDays(year, month) == ) && day == )))) {
message = "除夕";
}
}
}
return message;
}
} /**
* 字符串的处理类
*/
class StringUtil {
/**
* 判断是否为null或空值
*
* @param str
* String
* @return true or false
*/
public static boolean isNullOrEmpty(String str) {
return str == null || str.trim().length() == ;
} /**
* 判断str1和str2是否相同
*
* @param str1
* str1
* @param str2
* str2
* @return true or false
*/
public static boolean 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 static boolean equalsIgnoreCase(String str1, String str2) {
return str1 != null && str1.equalsIgnoreCase(str2);
} /**
* 判断字符串str1是否包含字符串str2
*
* @param str1
* 源字符串
* @param str2
* 指定字符串
* @return true源字符串包含指定字符串,false源字符串不包含指定字符串
*/
public static boolean contains(String str1, String str2) {
return str1 != null && str1.contains(str2);
} /**
* 判断字符串是否为空,为空则返回一个空值,不为空则返回原字符串
*
* @param str
* 待判断字符串
* @return 判断后的字符串
*/
public static String getString(String str) {
return str == null ? "" : str;
}
} /**
* 主要用于把公历日期处理成24节气
*/
class SolarTermsUtil { /**
* 计算得到公历的年份
*/
private int gregorianYear; /**
* 计算得到公历的月份
*/
private int gregorianMonth; /**
* 用于计算得到公历的日期
*/
private int gregorianDate; private int chineseYear;
private int chineseMonth;
private int chineseDate; // 初始日,公历农历对应日期:
// 公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日
private static int baseYear = ;
private static int baseMonth = ;
private static int baseDate = ;
private static int baseIndex = ;
private static int baseChineseYear = - ;
private static int baseChineseMonth = ;
private static int baseChineseDate = ;
private static char[] daysInGregorianMonth = { , , , , , , ,
, , , , }; private int sectionalTerm;
private int principleTerm; private static char[][] sectionalTermMap = {
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , },
{ , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , } };
private static char[][] sectionalTermYear = {
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , },
{ , , , , , , , , } };
private static char[][] principleTermMap = {
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , },
{ , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , } };
private static char[][] principleTermYear = {
{ , , , , , , },
{ , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , },
{ , , , , , , , } }; 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 = { "小寒", "立春", "惊蛰", "清明",
"立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪" }; public SolarTermsUtil(Calendar calendar) {
gregorianYear = calendar.get(Calendar.YEAR);
gregorianMonth = calendar.get(Calendar.MONTH) + ;
gregorianDate = calendar.get(Calendar.DATE);
computeChineseFields();
computeSolarTerms();
} public int computeChineseFields() {
if (gregorianYear < || gregorianYear > )
return ;
int startYear = baseYear;
int startMonth = baseMonth;
int startDate = baseDate;
chineseYear = baseChineseYear;
chineseMonth = baseChineseMonth;
chineseDate = baseChineseDate;
// 第二个对应日,用以提高计算效率
// 公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日
if (gregorianYear >= ) {
startYear = baseYear + ;
startMonth = ;
startDate = ;
chineseYear = baseChineseYear + ;
chineseMonth = ;
chineseDate = ;
}
int daysDiff = ;
for (int i = startYear; i < gregorianYear; i++) {
daysDiff += ;
if (isGregorianLeapYear(i))
daysDiff += ; // 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) < Math.abs(chineseMonth))
chineseYear++;
chineseMonth = nextMonth;
chineseDate -= lastDate;
lastDate = daysInChineseMonth(chineseYear, chineseMonth);
nextMonth = nextChineseMonth(chineseYear, chineseMonth);
}
return ;
} public int computeSolarTerms() {
if (gregorianYear < || gregorianYear > )
return ;
sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth);
principleTerm = principleTerm(gregorianYear, gregorianMonth);
return ;
} public static int sectionalTerm(int y, int m) {
if (y < || y > )
return ;
int index = ;
int ry = y - baseYear + ;
while (ry >= sectionalTermYear[m - ][index])
index++;
int term = sectionalTermMap[m - ][ * index + ry % ];
if ((ry == ) && (m == ))
term = ;
if ((ry == ) && (m == ))
term = ;
if ((ry == ) && (m == ))
term = ;
return term;
} public static int principleTerm(int y, int m) {
if (y < || y > )
return ;
int index = ;
int ry = y - baseYear + ;
while (ry >= principleTermYear[m - ][index])
index++;
int term = principleTermMap[m - ][ * index + ry % ];
if ((ry == ) && (m == ))
term = ;
if ((ry == ) && (m == ))
term = ;
return term;
} /**
* 用于判断输入的年份是否为闰年
*
* @param year
* 输入的年份
* @return true 表示闰年
*/
public static boolean isGregorianLeapYear(int year) {
boolean isLeap = false;
if (year % == )
isLeap = true;
if (year % == )
isLeap = false;
if (year % == )
isLeap = true;
return isLeap;
} public static int daysInGregorianMonth(int y, int m) {
int d = daysInGregorianMonth[m - ];
if (m == && isGregorianLeapYear(y))
d++; // 公历闰年二月多一天
return d;
} public static int daysInChineseMonth(int y, int m) {
// 注意:闰月 m < 0
int index = y - baseChineseYear + baseIndex;
int v = ;
int l = ;
int d = ;
if ( <= m && m <= ) {
v = chineseMonths[ * index];
l = m - ;
if (((v >> l) & 0x01) == )
d = ;
} else if ( <= m && m <= ) {
v = chineseMonths[ * index + ];
l = m - ;
if (((v >> l) & 0x01) == )
d = ;
} else {
v = chineseMonths[ * index + ];
v = (v >> ) & 0x0F;
if (v != Math.abs(m)) {
d = ;
} else {
d = ;
for (int i = ; i < bigLeapMonthYears.length; i++) {
if (bigLeapMonthYears[i] == index) {
d = ;
break;
}
}
}
}
return d;
} public static int nextChineseMonth(int y, int m) {
int n = Math.abs(m) + ;
if (m > ) {
int index = y - baseChineseYear + baseIndex;
int v = chineseMonths[ * index + ];
v = (v >> ) & 0x0F;
if (v == m)
n = -m;
}
if (n == )
n = ;
return n;
} // 大闰月的闰年年份
private static int[] bigLeapMonthYears = { , , , , , , , ,
, , , , , , , , , , , }; /**
* 用于获取24节气的值
*
* @return 24节气的值
*/
public String getSolartermsMsg() {
String str = "";
String gm = String.valueOf(gregorianMonth);
if (gm.length() == )
gm = ' ' + gm;
String cm = String.valueOf(Math.abs(chineseMonth));
if (cm.length() == )
cm = ' ' + cm;
String gd = String.valueOf(gregorianDate);
if (gd.length() == )
gd = ' ' + gd;
String cd = String.valueOf(chineseDate);
if (cd.length() == )
cd = ' ' + cd;
if (gregorianDate == sectionalTerm) {
str = " " + sectionalTermNames[gregorianMonth - ];
} else if (gregorianDate == principleTerm) {
str = " " + principleTermNames[gregorianMonth - ];
}
return str;
}
} /**
* 对公历日期的处理类
*/
class GregorianUtil {
private final static String[][] GRE_FESTVIAL = {
// 一月
{ "元旦", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 二月
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "情人", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 三月
{ "", "", "", "", "", "", "", "妇女", "", "", "", "植树", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"" },
// 四月
{ "愚人", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 五月
{ "劳动", "", "", "青年", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"" },
// 六月
{ "儿童", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 七月
{ "建党", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 八月
{ "建军", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 九月
{ "", "", "", "", "", "", "", "", "", "教师", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 十月
{ "国庆", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 十一月
{ "", "", "", "", "", "", "", "", "", "", "光棍", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
// 十二月
{ "艾滋病", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "圣诞", "", "", "", "",
"", "" }, };
private int mMonth;
private int mDay; public GregorianUtil(Calendar calendar) {
mMonth = calendar.get(Calendar.MONTH);
mDay = calendar.get(Calendar.DATE);
} public String getGremessage() {
return GRE_FESTVIAL[mMonth][mDay - ];
}
} class NumberHelper {
public static String LeftPad_Tow_Zero(int str) {
java.text.DecimalFormat format = new java.text.DecimalFormat("");
return format.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 class ViewUtil { /**
* 获取屏幕的宽度
* @param context
* @return
*/
public int getScreenWidth(Context context) {
Resources res = context.getResources();
return res.getDisplayMetrics().widthPixels;
} /**
* 获取屏幕高度
* @param context
* @return
*/
public int getScreenHeight(Context context) {
Resources res = context.getResources();
return res.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,int textSize){
float ratio = ;
try {
float ratioWidth = (float)screenWidth / ;
float ratioHeight = (float)screenHeight / ;
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, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return Math.round(dipValue * scale);
} /**
*
* 描述:px转换为dip
* @param context
* @param pxValue
* @return
* @throws
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return Math.round(pxValue / scale);
} /**
*
* 描述:px转换为sp
* @param context
* @param pxValue
* @return
* @throws
*/
public static int px2sp(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().scaledDensity;
return Math.round(pxValue / scale);
} /**
*
* 描述:sp转换为px
* @param context
* @param spValue
* @return
* @throws
*/
public static int sp2px(Context context, float spValue) {
final float scale = context.getResources().getDisplayMetrics().scaledDensity;
return Math.round(spValue * scale);
}
} //使用方法
//在xml中添加控件
<cc.util.android.view.CalendarView
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<Date> markDates = new ArrayList<Date>();
markDates.add(new Date());
calendarView.setMarkDates(markDates); //设置点击操作
calendarView.setOnCalendarViewListener(new OnCalendarViewListener() { @Override
public void onCalendarItemClick(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自定义日历,可以点击、标注日期、节气、旧历等的更多相关文章

  1. Android自定义日历控件(继承系统控件实现)

    Android自定义日历控件(继承系统控件实现) 主要步骤 编写布局 继承LinearLayout设置子控件 设置数据 继承TextView实现有圆圈背景的TextView 添加Attribute 添 ...

  2. android 自定义日历控件

    日历控件View: /** * 日历控件 功能:获得点选的日期区间 * */ public class CalendarView extends View implements View.OnTouc ...

  3. Android 自定义日历

    好久没来写博客了,这半年多发生了好多的事情,废话不多说,今天在公司里比较闲在,写一篇最近写的公司用到的控件——日历控件. 控件的功能比较少,根据需求只有选择开始时间和结束时间并返回时间段. 效果图如下 ...

  4. Android 一个日历控件的实现代码

    转载  2017-05-19   作者:Othershe   我要评论 本篇文章主要介绍了Android 一个日历控件的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看 ...

  5. Android自定义View(CustomCalendar-定制日历控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeas ...

  6. Android自定义View(RollWeekView-炫酷的星期日期选择控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义Cus ...

  7. android高德地图网络路径实现自定义marker并点击弹出自定义窗口

    android中使用地图的地方随处可见,今天记录一下网络路径生成自定义marker,点击标记弹出自定义的窗口(在这里使用的是高德地图) 在这里我们使用Grilde去加载网络图片,因为这个简直太方便了! ...

  8. Android 自定义View——自定义点击事件

    每个人手机上都有通讯录,这是毫无疑问的,我们通讯录上有一个控件,在通讯录的最左边有一列从”#”到”Z”的字母,我们通过滑动或点击指定的字母来确定联系人的位置,进而找到联系人.我们这一节就通过开发这个控 ...

  9. javascript实例学习之六—自定义日历控件

    基于之前上篇博客轻量级jquery,tool.js和base.js.自定义开发的base_datePicker插件,效果类似于jquery_ui的datePicker插件 //基于Base.js以及t ...

随机推荐

  1. 【转】FAE及其发展前景

    原文网址:http://blog.sina.com.cn/s/blog_6e80c27b0100okd9.html FAE Field Application Engineer(现场应用工程师) ,其 ...

  2. 模仿TMALL搜索,下拉提示 优化 用户keypress停顿200毫秒间隔时,在执行异步取数据操作 通过underscore的函数debounce来实现

  3. 理解Spring MVC Model Attribute和Session Attribute

    作为一名 Java Web 应用开发者,你已经快速学习了 request(HttpServletRequest)和 session(HttpSession)作用域.在设计和构建 Java Web 应用 ...

  4. poj 1236 Network of Schools(tarjan+缩点)

    Network of Schools Description A number of schools are connected to a computer network. Agreements h ...

  5. C++中的重载、覆盖、隐藏

    前几天面试时被问及C++中的覆盖.隐藏,概念基本答不上来,只答了怎么用指针实现多态,也还有遗漏.最终不欢而散.回来后在网上查找学习了一番,做了这个总结.其中部分文字借用了别人的博客,望不要见怪.引用的 ...

  6. 使用sublime text2怎样新建文件高速生成HTML头部信息?

    前提须要安装Emmet插件.安装完毕后重新启动sublime. 输入下面简写,按Tab. html:4t <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  7. 可失败构造器(Failable Initializers)

    Xcode6.1中Swift的最新版本是1.1,在该版本中引入了一个新的特性:可失败构造器.通过构造器初始化实际上是给class或struct的每一个存储属性(参数)提供初始值,进行对象实例化的过程. ...

  8. Android Action Bar 详解篇 .

    作者原创,转载请标明出处:http://blog.csdn.net/yuxlong2010 作为Android 3.0之后引入的新的对象,ActionBar可以说是一个方便快捷的导航神器.它可以作为活 ...

  9. Qt 界面使用自己定义控件 &quot;提升为&quot;

    1.效果图 我做了一个很easy的样例,一个能够显示颜色的QLabel,边上有个button,点击,跳出颜色选取的Dialog,然后选择一个颜色.这个QLabel会变成什么颜色. 2.ColorLab ...

  10. Javascript基础form表单

    <!DOCTYPE HTML> <html> <head> <script type="text/javascript" charset= ...