-
安卓开发日历控件遇到的问题
2019-06-05 10:53:45现在想做一个日历控件,但是给的图是这样,选择是在最上面点击选择的如图所示 但是平常我所做的都是![图片说明]... -
基于安卓开发的日历功能完善附带分享按扭.rar
2020-05-06 20:36:03本科毕业设计安卓开发功能完善并添加分享功能,可运行 -
安卓日历日程事件获取和监听汇总
2017-02-17 15:52:16在我们的APP开发过程中,很多时候我们需要获取用户的日历日程事件,便于我们APP更好的了解用户,同时给予用户提醒。 要想获得日历日程的相关内容,首先我们需要拥有日历日程的读写权限。主要包括下面两个权限 ...在我们的APP开发过程中,很多时候我们需要获取用户的日历日程事件,便于我们APP更好的了解用户,同时给予用户提醒。
要想获得日历日程的相关内容,首先我们需要拥有日历日程的读写权限。主要包括下面两个权限
获得对安卓系统日历事件操作的权限,也就是在AndroidManifest.xml文件中加入如下两行
· <uses-permission Android:name="android.permission.READ_CALENDAR"/>
· <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
字面意思很明确就是分别的读写权限,类同于对短信的权限获取
安卓中日历用到三个URL,分别是日历用户的URL,事件的URL,以及事件提醒的URL,三个URL在安卓版本2.2前后分别是:
if(Integer.parseInt(Build.VERSION.SDK)>=8){
uri = "content://com.android.calendar/calendars";
eventUri = "content://com.android.calendar/events";
reminderUri = "content://com.android.calendar/reminders";
}
else{ //在安卓2.2版本以后的地址
calanderURL= "content://calendar/calendars";
calanderEventURL= "content://calendar/events";
reminderUri = "content://calendar/reminders";
}
之后我们通过内容解析者分别对这三个url内容进行查询
- Cursor userCursor = getContentResolver().query(Uri.parse(calanderURL), null,
- null, null, null);
- if(userCursor.getCount() > 0){
- userCursor.moveToFirst(); // 将游标移动到首位
- String userName = userCursor.getString(userCursor.getColumnIndex("name")); //拿到当前日历用户
- }
- Cursor eventCursor = getContentResolver().query(Uri.parse(calanderEventURL), null,
- null, null, null);
- if(eventCursor.getCount() > 0){
- eventCursor.moveToLast();
- String eventTitle = eventCursor.getString(eventCursor.getColumnIndex("title"));
- }
- //获取要出入的gmail账户的id
- String calId = "";
- Cursor userCursor = getContentResolver().query(Uri.parse(calanderURL), null,
- null, null, null);
- if(userCursor.getCount() > 0){
- userCursor.moveToFirst();
- calId = userCursor.getString(userCursor.getColumnIndex("_id"));
- }
- ContentValues event = new ContentValues(); // 新建日历事件
- event.put("title", "明天上午八点考试");
- event.put("description", "明天上午在第二教学楼有英语专业的考试");
- //插入插入用户
- event.put("calendar_id",calId);
- Calendar mCalendar = Calendar.getInstance();
- mCalendar.set(Calendar.HOUR_OF_DAY,10);
- long start = mCalendar.getTime().getTime();
- mCalendar.set(Calendar.HOUR_OF_DAY,11);
- long end = mCalendar.getTime().getTime();
- // 分别设置开始时间和结束时间
- event.put("dtstart", start);
- event.put("dtend", end);
- event.put("hasAlarm",1);
//将事件插入到日历中- Uri newEvent = getContentResolver().insert(Uri.parse(calanderEventURL), event);
- long id = Long.parseLong( newEvent.getLastPathSegment() );
- ContentValues values = new ContentValues();
- values.put( "event_id", id );
- //提前10分钟有提醒
- values.put( "minutes", 10 );
- getContentResolver().insert(Uri.parse(calanderRemiderURL), values);
- }
- }
private Context context;
private Handler handler;
public CalendarObserver(Context context,Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
this.context=context;
this.handler=handler;
}
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
super.onChange(selfChange);
handler.obtainMessage(3,"events have chage").sendToTarget();
}
在主类中,实例化并实施监听
calObserver=new CalendarObserver(this,new Handler(){
@Override
public void handleMessage(Message msg) {
/**当监听到改变时,做业务操作*/
Log.i("tag", "now ");
String msgStr=(String)msg.obj;
System.out.println(msgStr+"----------------日程日程");
Toast.makeText(CalendarActivity.this, "日程事件修改被触发", Toast.LENGTH_SHORT).show();
}
};
//注册日程事件监听
getContentResolver().registerContentObserver(Events.CONTENT_URI, true, calObserver);
}
以下是日历事件的增删该差的具体demohttp://blog.csdn.net/justforhappness/article/details/40432663
-
安卓日历、时间弹出框
2016-08-11 11:57:35安卓项目开发中,会遇到选择日期和时间的需求,安卓本身自带了两个类,DataPickerDialog和TimePickerDialog(弹出框),可以完成需求。 1、DataPickerDialog用法: new DatePickerDialog(getContext(), new ...安卓项目开发中,会遇到选择日期和时间的需求,安卓本身自带了两个类,DataPickerDialog和TimePickerDialog(弹出框),可以完成需求。
1、DataPickerDialog用法:
new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { date = year+"/"+(monthOfYear+1)+"/"+dayOfMonth; tv_calender.setText(date); } },Integer.parseInt(date.split("/")[0]),(Integer.parseInt(date.split("/")[1])-1),Integer.parseInt(date.split("/")[2])).show();
其中data需要选给他设置当前日期用“/”隔开(用其他符号隔开也行),因为DataPickerDialog打开的时候需要给他设置一个日期。
2、TimePickerDialog的用法:
new TimePickerDialog(getContext(),new TimePickerDialog.OnTimeSetListener() {
@Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { time =hourOfDay+":"+minute; tv_time.setText(time); } },Integer.parseInt(now_time.split(",")[0]),Integer.parseInt(now_time.split(",")[1]),true).show();用法和DataPickerDialog一样
-
安卓系统的日历开发(项目报告1)【项目开发需求及功能介绍】
2016-12-22 12:54:54本文档的编写主要为了介绍本项目的开发目的,项目需求,以及开发的情况,将本系统的结构进行大概的介绍,以便用户更熟悉的了解本软件,让用户在使用该软件前,对本软件的使用有一定的了解。 1.2项目介绍 随着智能...一.项目概述
1.1编写目的
本文档的编写主要为了介绍本项目的开发目的,项目需求,以及开发的情况,将本系统的结构进行大概的介绍,以便用户更熟悉的了解本软件,让用户在使用该软件前,对本软件的使用有一定的了解。
1.2项目介绍
随着智能手机的逐渐普及及其功能的多样化、实用化,移动设备逐渐成为人们生活中不可或缺的一部分。目前,市场占有率最高的两个移动平台系统分别为苹果公司的ios,及Google作为代表的Android系统,移动端也逐渐成为各行业商家的争夺之地,程序开发人员也将战场向移动端扩散。本项目为Android移动端的日历软件,用于显示日历,本软件可以浏览公历日期,也可以显示农历日期及公历和农历假期信息,本项目的开发是为方便Android移动端用户提供日历的服务。
1.3软件相关信息
软件名称:生活日历
软件版本:1.0
适用平台:Android4.0及以上
二.项目需求
2.1概述
2.1.1编写目的
本文档的编写主要是描述本软件需要实现的功能,列出本软件的需求点,作为开发人员开发目标系统及编程所需的基础,也作为项目完成验收时作为产品是否符合要求的一个参考。本文档的预期读者为开发人员,用户。
2.1.2项目概述
本项目的目标受众为所有Android用户,Android系统现在已经成为相当主流的移动端系统,本系统作为Android端的应用软件,有很广泛的受众群。本软件主要为用户提供日常生活的日历浏览,待开发软件名称:生活日历
2.1.3运行环境
2.2项目需求分析
2.2.1项目需求介绍
(1)日历浏览:显示日历信息,包括公历,农历,假日信息。日程添加: 在点击某一日期时跳转至日程添加界面,进行日程信息的添加。
(2)日期跳转:选择要查看的日期进行跳转。
2.2.2 模块、流程描述
(1)主界面:用于显示日期信息,信息包括农历日期,公历日期,节日信息.
(2)日期跳转:用于用户想要查看的日期后跳转到指定的日期。
(3)日期转换:用户在点击某一个日期后,输出改日期的农历日期。
二 功能需求
2.3.1功能需求点列表
功能名称
功能描述
输入
预期输出
日历显示
用于显示日期信息,包括公立及农历你年月日,星期,节假日信息,头部应包含当前年月。
点击软件图标进入软件
显示功能描述的所有日期信息
日程跳转
用户点击某一日期,点击按钮后跳转到指定日期
在指定方位内的某一日期
跳转至指定日期
2.3.2其他功能需求
A.在日历显示界面,用户在屏幕进行左右滑动时,显示的日历的月份相应的进入下一个月或者上一个月的日历。
B.点击左上角【今天】就会显示今天的日历
3.1 概述
3.1.1 编写目的
本部分文档的编写是让读者尽快的了解本软件的概要设计,对软件的运行流 程有一个大概的了解。
3.1.2 预期读者
3.2系统概要设计说明
3.2.1系统功能模块说明
(1)日历查看模块:拥有一个完整的日历界面,包括头部的年月日、生肖、闰年的显示,还有每个日期上都分别有阳历和阴历的日期显示,并且日历中 包含了各个重要的节日或纪念日等。在日历界面上每个日期都会跳到当前日 期的日程添加界面或者是日程显示界面。日历界面上还有对存在日程的标 记,有利于人们更好的管理日程。
(2)日程管理模块:在本模块中包括总的日程显示页面和日历页面所跳转到的日程显示界面或者是日程添加界面。总日程显示界面每一个日程都会有它 所包含的日期、时间、日程类型、重复类型和日程内容。日历日期所对应的 日程显示界面也是相应的显示。而在日程添加界面中包含了显示界面所对应 的各项数据、添加日程成功后会有对应日历日期的标记。另外也有对日程的 一系列管理操作的功能。
(3)天气查询模块:在本模块中包括对指定城市天气的查询和显示。
3.2.2系统功能模块结构图
(1)在程序设计分析的基础上,结合实际情况,得出本程序的功能模块结构图。在结构图中包括了功能模块的表示及其中部分功能的实现原理。首先是 一个总的功能模块的结构图,其中包括了系统设计时的总体功能概括,如图3-1:
模块描述:
a.日程模块:主要是添加日程,显示日程概况,点击日程显示日程详细信息。
b.主界面:主界面即为日历显示界面,用于显示日历及有日程信息的日程的标记。
c.天气模块:用于查询指定城市的天气信息。
d.总日程显示:即显示所有添加的日程列表。
e.单一日程显示:显示某一日程的详细信息。
-
安卓系统的日历开发(项目报告2)【程序详解及效果图 开发总结】
2016-12-22 13:03:22* TODO<用于生成日历展示的GridView布局> * */ public class CalendarGridView extends GridView { /** * 当前操作的上下文对象 */ private Context mContext; /** * CalendarGridView 构造器 * ...package com.easier.adapter; import android.app.Activity; import android.content.Context; import android.view.Display; import android.view.Gravity; import android.view.WindowManager; import android.widget.GridView; import android.widget.LinearLayout; import com.easier.ui.R; /** * * TODO<用于生成日历展示的GridView布局> * */ public class CalendarGridView extends GridView { /** * 当前操作的上下文对象 */ private Context mContext; /** * CalendarGridView 构造器 * * @param context * 当前操作的上下文对象 */ public CalendarGridView(Context context) { super(context); mContext = context; setGirdView(); } /** * 初始化gridView 控件的布局 */ private void setGirdView() { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); setLayoutParams(params); setNumColumns(7);// 设置每行列数 setGravity(Gravity.CENTER_VERTICAL);// 位置居中 setVerticalSpacing(1);// 垂直间隔 setHorizontalSpacing(1);// 水平间隔 setBackgroundColor(getResources().getColor(R.color.calendar_background)); WindowManager windowManager = ((Activity) mContext).getWindowManager(); Display display = windowManager.getDefaultDisplay(); int i = display.getWidth() / 7; int j = display.getWidth() - (i * 7); int x = j / 2; setPadding(x, 0, 0, 0);// 居中 } } 二: package com.easier.adapter; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import android.app.Activity; import android.content.res.Resources; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.LinearLayout.LayoutParams; import com.easier.ui.R; import com.easier.util.CalendarUtil; /** * * TODO<GridViewAdapter> * */ public class CalendarGridViewAdapter extends BaseAdapter { private Calendar calStartDate = Calendar.getInstance();// 当前显示的日历 private Calendar calSelected = Calendar.getInstance(); // 选择的日历 public void setSelectedDate(Calendar cal) { calSelected = cal; } private Calendar calToday = Calendar.getInstance(); // 今日 private int iMonthViewCurrentMonth = 0; // 当前视图月 // 根据改变的日期更新日历 // 填充日历控件用 private void UpdateStartDateForMonth() { calStartDate.set(Calendar.DATE, 1); // 设置成当月第一天 iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到当前日历显示的月 // 星期一是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);// 周日第一位 } 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 = 1; i <= 42; i++) { alArrayList.add(calStartDate.getTime()); calStartDate.add(Calendar.DAY_OF_MONTH, 1); } return alArrayList; } private Activity activity; Resources resources; // construct public CalendarGridViewAdapter(Activity a, Calendar cal) { calStartDate = cal; activity = a; resources = activity.getResources(); titles = getDates(); } public CalendarGridViewAdapter(Activity a) { activity = a; resources = activity.getResources(); } @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; } @Override public View getView(int position, View convertView, ViewGroup parent) { LinearLayout iv = new LinearLayout(activity); iv.setId(position + 5000); LinearLayout imageLayout = new LinearLayout(activity); imageLayout.setOrientation(0); iv.setGravity(Gravity.CENTER); iv.setOrientation(1); iv.setBackgroundColor(resources.getColor(R.color.white)); Date myDate = (Date) getItem(position); Calendar calCalendar = Calendar.getInstance(); calCalendar.setTime(myDate); final int iMonth = calCalendar.get(Calendar.MONTH); final int iDay = calCalendar.get(Calendar.DAY_OF_WEEK); // 判断周六周日 iv.setBackgroundColor(resources.getColor(R.color.white)); if (iDay == 7) { // 周六 iv.setBackgroundColor(resources.getColor(R.color.text_6)); } else if (iDay == 1) { // 周日 iv.setBackgroundColor(resources.getColor(R.color.text_7)); } // 判断周六周日结束 TextView txtToDay = new TextView(activity);// 日本老黄历 txtToDay.setGravity(Gravity.CENTER_HORIZONTAL); txtToDay.setTextSize(9); CalendarUtil calendarUtil = new CalendarUtil(calCalendar); if (equalsDate(calToday.getTime(), myDate)) { // 当前日期 iv.setBackgroundColor(resources.getColor(R.color.event_center)); txtToDay.setText(calendarUtil.toString()); } else { txtToDay.setText(calendarUtil.toString()); } // 这里用于比对是不是比当前日期小,如果比当前日期小就高亮 if (!CalendarUtil.compare(myDate, calToday.getTime())) { iv.setBackgroundColor(resources.getColor(R.color.frame)); } else { // 设置背景颜色 if (equalsDate(calSelected.getTime(), myDate)) { // 选择的 iv.setBackgroundColor(resources.getColor(R.color.selection)); } else { if (equalsDate(calToday.getTime(), myDate)) { // 当前日期 iv.setBackgroundColor(resources .getColor(R.color.calendar_zhe_day)); } } } // 设置背景颜色结束 // 日期开始 TextView txtDay = new TextView(activity);// 日期 txtDay.setGravity(Gravity.CENTER_HORIZONTAL); // 判断是否是当前月 if (iMonth == iMonthViewCurrentMonth) { txtToDay.setTextColor(resources.getColor(R.color.ToDayText)); txtDay.setTextColor(resources.getColor(R.color.Text)); } else { txtDay.setTextColor(resources.getColor(R.color.noMonth)); txtToDay.setTextColor(resources.getColor(R.color.noMonth)); } int day = myDate.getDate(); // 日期 txtDay.setText(String.valueOf(day)); txtDay.setId(position + 500); iv.setTag(myDate); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); iv.addView(txtDay, lp); LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); iv.addView(txtToDay, lp1); return iv; } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); } 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; } } } 三 package com.easier.ui; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.Window; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.*; import android.widget.LinearLayout.LayoutParams; import com.easier.adapter.CalendarGridView; import com.easier.adapter.CalendarGridViewAdapter; import com.easier.util.CalendarUtil; import com.easier.util.NumberHelper; import java.util.Calendar; import java.util.Date; /** * * TODO<布局> * */ public class CalendarView extends Activity implements OnTouchListener { /** * 日历布局ID */ private static final int CAL_LAYOUT_ID = 55; // 判断手势用 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 static final String MESSAGE = "msg"; // 动画 private Animation slideLeftIn; private Animation slideLeftOut; private Animation slideRightIn; private Animation slideRightOut; private ViewFlipper viewFlipper; GestureDetector mGesture = null; /** * 今天按钮 */ private Button mTodayBtn; /** * 上一个月按钮 */ private ImageView mPreMonthImg; /** * 下一个月按钮 */ private ImageView mNextMonthImg; /** * 用于显示今天的日期 */ private TextView mDayMessage; /** * 用于装截日历的View */ private RelativeLayout mCalendarMainLayout; // 基本变量 private Context mContext = CalendarView.this; /** * 上一个月View */ private GridView firstGridView; /** * 当前月View */ private GridView currentGridView; /** * 下一个月View */ private GridView lastGridView; /** * 当前显示的日历 */ private Calendar calStartDate = Calendar.getInstance(); /** * 选择的日历 */ private Calendar calSelected = Calendar.getInstance(); /** * 今日 */ private Calendar calToday = Calendar.getInstance(); /** * 当前界面展示的数据源 */ private CalendarGridViewAdapter currentGridAdapter; /** * 预装载上一个月展示的数据源 */ private CalendarGridViewAdapter firstGridAdapter; /** * 预装截下一个月展示的数据源 */ private CalendarGridViewAdapter lastGridAdapter; // /** * 当前视图月 */ private int mMonthViewCurrentMonth = 0; /** * 当前视图年 */ private int mMonthViewCurrentYear = 0; /** * 起始周 */ private int iFirstDayOfWeek = Calendar.MONDAY; @Override public boolean onTouch(View v, MotionEvent event) { return mGesture.onTouchEvent(event); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.calendar_main); initView(); updateStartDateForMonth(); generateContetView(mCalendarMainLayout); slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in); slideLeftOut = AnimationUtils .loadAnimation(this, R.anim.slide_left_out); slideRightIn = AnimationUtils .loadAnimation(this, R.anim.slide_right_in); slideRightOut = AnimationUtils.loadAnimation(this, R.anim.slide_right_out); slideLeftIn.setAnimationListener(animationListener); slideLeftOut.setAnimationListener(animationListener); slideRightIn.setAnimationListener(animationListener); slideRightOut.setAnimationListener(animationListener); mGesture = new GestureDetector(this, new GestureListener()); } /** * 用于初始化控件 */ private void initView() { mTodayBtn = (Button) findViewById(R.id.today_btn); mDayMessage = (TextView) findViewById(R.id.day_message); mCalendarMainLayout = (RelativeLayout) findViewById(R.id.calendar_main); mPreMonthImg = (ImageView) findViewById(R.id.left_img); mNextMonthImg = (ImageView) findViewById(R.id.right_img); mTodayBtn.setOnClickListener(onTodayClickListener); mPreMonthImg.setOnClickListener(onPreMonthClickListener); mNextMonthImg.setOnClickListener(onNextMonthClickListener); } /** * 用于加载到当前的日期的事件 */ private View.OnClickListener onTodayClickListener = new View.OnClickListener() { @Override public void onClick(View view) { calStartDate = Calendar.getInstance(); calSelected = Calendar.getInstance(); updateStartDateForMonth(); generateContetView(mCalendarMainLayout); } }; /** * 用于加载上一个月日期的事件 */ private View.OnClickListener onPreMonthClickListener = new View.OnClickListener() { @Override public void onClick(View view) { viewFlipper.setInAnimation(slideRightIn); viewFlipper.setOutAnimation(slideRightOut); viewFlipper.showPrevious(); setPrevViewItem(); } }; /** * 用于加载下一个月日期的事件 */ private View.OnClickListener onNextMonthClickListener = new View.OnClickListener() { @Override public void onClick(View view) { viewFlipper.setInAnimation(slideLeftIn); viewFlipper.setOutAnimation(slideLeftOut); viewFlipper.showNext(); setNextViewItem(); } }; /** * 主要用于生成发前展示的日历View * * @param layout * 将要用于去加载的布局 */ private void generateContetView(RelativeLayout layout) { // 创建一个垂直的线性布局(整体内容) viewFlipper = new ViewFlipper(this); viewFlipper.setId(CAL_LAYOUT_ID); calStartDate = getCalendarStartDate(); CreateGirdView(); RelativeLayout.LayoutParams params_cal = new RelativeLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); layout.addView(viewFlipper, params_cal); LinearLayout br = new LinearLayout(this); RelativeLayout.LayoutParams params_br = new RelativeLayout.LayoutParams( LayoutParams.FILL_PARENT, 1); params_br.addRule(RelativeLayout.BELOW, CAL_LAYOUT_ID); br.setBackgroundColor(getResources().getColor( R.color.calendar_background)); layout.addView(br, params_br); } /** * 用于创建当前将要用于展示的View */ private void CreateGirdView() { Calendar firstCalendar = Calendar.getInstance(); // 临时 Calendar currentCalendar = Calendar.getInstance(); // 临时 Calendar lastCalendar = Calendar.getInstance(); // 临时 firstCalendar.setTime(calStartDate.getTime()); currentCalendar.setTime(calStartDate.getTime()); lastCalendar.setTime(calStartDate.getTime()); firstGridView = new CalendarGridView(mContext); firstCalendar.add(Calendar.MONTH, -1); firstGridAdapter = new CalendarGridViewAdapter(this, firstCalendar); firstGridView.setAdapter(firstGridAdapter);// 设置菜单Adapter firstGridView.setId(CAL_LAYOUT_ID); currentGridView = new CalendarGridView(mContext); currentGridAdapter = new CalendarGridViewAdapter(this, currentCalendar); currentGridView.setAdapter(currentGridAdapter);// 设置菜单Adapter currentGridView.setId(CAL_LAYOUT_ID); lastGridView = new CalendarGridView(mContext); lastCalendar.add(Calendar.MONTH, 1); lastGridAdapter = new CalendarGridViewAdapter(this, lastCalendar); lastGridView.setAdapter(lastGridAdapter);// 设置菜单Adapter lastGridView.setId(CAL_LAYOUT_ID); currentGridView.setOnTouchListener(this); firstGridView.setOnTouchListener(this); lastGridView.setOnTouchListener(this); if (viewFlipper.getChildCount() != 0) { viewFlipper.removeAllViews(); } viewFlipper.addView(currentGridView); viewFlipper.addView(lastGridView); viewFlipper.addView(firstGridView); String s = calStartDate.get(Calendar.YEAR) + "-" + NumberHelper.LeftPad_Tow_Zero(calStartDate .get(Calendar.MONTH) + 1); mDayMessage.setText(s); } /** * 上一个月 */ private void setPrevViewItem() { mMonthViewCurrentMonth--;// 当前选择月-- // 如果当前月为负数的话显示上一年 if (mMonthViewCurrentMonth == -1) { mMonthViewCurrentMonth = 11; mMonthViewCurrentYear--; } calStartDate.set(Calendar.DAY_OF_MONTH, 1); // 设置日为当月1日 calStartDate.set(Calendar.MONTH, mMonthViewCurrentMonth); // 设置月 calStartDate.set(Calendar.YEAR, mMonthViewCurrentYear); // 设置年 } /** * 下一个月 */ private void setNextViewItem() { mMonthViewCurrentMonth++; if (mMonthViewCurrentMonth == 12) { mMonthViewCurrentMonth = 0; mMonthViewCurrentYear++; } calStartDate.set(Calendar.DAY_OF_MONTH, 1); calStartDate.set(Calendar.MONTH, mMonthViewCurrentMonth); calStartDate.set(Calendar.YEAR, mMonthViewCurrentYear); } /** * 根据改变的日期更新日历 填充日历控件用 */ private void updateStartDateForMonth() { calStartDate.set(Calendar.DATE, 1); // 设置成当月第一天 mMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到当前日历显示的月 mMonthViewCurrentYear = calStartDate.get(Calendar.YEAR);// 得到当前日历显示的年 String s = calStartDate.get(Calendar.YEAR) + "-" + NumberHelper.LeftPad_Tow_Zero(calStartDate .get(Calendar.MONTH) + 1); mDayMessage.setText(s); // 星期一是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); } /** * 用于获取当前显示月份的时间 * * @return 当前显示月份的时间 */ private Calendar getCalendarStartDate() { calToday.setTimeInMillis(System.currentTimeMillis()); calToday.setFirstDayOfWeek(iFirstDayOfWeek); if (calSelected.getTimeInMillis() == 0) { calStartDate.setTimeInMillis(System.currentTimeMillis()); calStartDate.setFirstDayOfWeek(iFirstDayOfWeek); } else { calStartDate.setTimeInMillis(calSelected.getTimeInMillis()); calStartDate.setFirstDayOfWeek(iFirstDayOfWeek); } return calStartDate; } AnimationListener animationListener = new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 当动画完成后调用 CreateGirdView(); } }; class GestureListener extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 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 boolean onSingleTapUp(MotionEvent e) { // 得到当前选中的是第几个单元格 int pos = currentGridView.pointToPosition((int) e.getX(), (int) e.getY()); LinearLayout txtDay = (LinearLayout) currentGridView .findViewById(pos + 5000); if (txtDay != null) { if (txtDay.getTag() != null) { Date date = (Date) txtDay.getTag(); if (CalendarUtil.compare(date, Calendar.getInstance() .getTime())) { calSelected.setTime(date); currentGridAdapter.setSelectedDate(calSelected); currentGridAdapter.notifyDataSetChanged(); firstGridAdapter.setSelectedDate(calSelected); firstGridAdapter.notifyDataSetChanged(); lastGridAdapter.setSelectedDate(calSelected); lastGridAdapter.notifyDataSetChanged(); String week = CalendarUtil.getWeek(calSelected); String message = CalendarUtil.getDay(calSelected) + " 农历" + new CalendarUtil(calSelected).getDay() + " " + week; Toast.makeText(getApplicationContext(), "您选择的日期为:" + message, Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(getApplicationContext(), "选择的日期不能小于今天的日期", Toast.LENGTH_SHORT).show(); } } } Log.i("TEST", "onSingleTapUp - pos=" + pos); return false; } } } 四 package com.easier.ui; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.Window; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.*; import android.widget.LinearLayout.LayoutParams; import com.easier.adapter.CalendarGridView; import com.easier.adapter.CalendarGridViewAdapter; import com.easier.util.CalendarUtil; import com.easier.util.NumberHelper; import java.util.Calendar; import java.util.Date; /** * * TODO<布局> * */ public class CalendarView extends Activity implements OnTouchListener { /** * 日历布局ID */ private static final int CAL_LAYOUT_ID = 55; // 判断手势用 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 static final String MESSAGE = "msg"; // 动画 private Animation slideLeftIn; private Animation slideLeftOut; private Animation slideRightIn; private Animation slideRightOut; private ViewFlipper viewFlipper; GestureDetector mGesture = null; /** * 今天按钮 */ private Button mTodayBtn; /** * 上一个月按钮 */ private ImageView mPreMonthImg; /** * 下一个月按钮 */ private ImageView mNextMonthImg; /** * 用于显示今天的日期 */ private TextView mDayMessage; /** * 用于装截日历的View */ private RelativeLayout mCalendarMainLayout; // 基本变量 private Context mContext = CalendarView.this; /** * 上一个月View */ private GridView firstGridView; /** * 当前月View */ private GridView currentGridView; /** * 下一个月View */ private GridView lastGridView; /** * 当前显示的日历 */ private Calendar calStartDate = Calendar.getInstance(); /** * 选择的日历 */ private Calendar calSelected = Calendar.getInstance(); /** * 今日 */ private Calendar calToday = Calendar.getInstance(); /** * 当前界面展示的数据源 */ private CalendarGridViewAdapter currentGridAdapter; /** * 预装载上一个月展示的数据源 */ private CalendarGridViewAdapter firstGridAdapter; /** * 预装截下一个月展示的数据源 */ private CalendarGridViewAdapter lastGridAdapter; // /** * 当前视图月 */ private int mMonthViewCurrentMonth = 0; /** * 当前视图年 */ private int mMonthViewCurrentYear = 0; /** * 起始周 */ private int iFirstDayOfWeek = Calendar.MONDAY; @Override public boolean onTouch(View v, MotionEvent event) { return mGesture.onTouchEvent(event); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.calendar_main); initView(); updateStartDateForMonth(); generateContetView(mCalendarMainLayout); slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in); slideLeftOut = AnimationUtils .loadAnimation(this, R.anim.slide_left_out); slideRightIn = AnimationUtils .loadAnimation(this, R.anim.slide_right_in); slideRightOut = AnimationUtils.loadAnimation(this, R.anim.slide_right_out); slideLeftIn.setAnimationListener(animationListener); slideLeftOut.setAnimationListener(animationListener); slideRightIn.setAnimationListener(animationListener); slideRightOut.setAnimationListener(animationListener); mGesture = new GestureDetector(this, new GestureListener()); } /** * 用于初始化控件 */ private void initView() { mTodayBtn = (Button) findViewById(R.id.today_btn); mDayMessage = (TextView) findViewById(R.id.day_message); mCalendarMainLayout = (RelativeLayout) findViewById(R.id.calendar_main); mPreMonthImg = (ImageView) findViewById(R.id.left_img); mNextMonthImg = (ImageView) findViewById(R.id.right_img); mTodayBtn.setOnClickListener(onTodayClickListener); mPreMonthImg.setOnClickListener(onPreMonthClickListener); mNextMonthImg.setOnClickListener(onNextMonthClickListener); } /** * 用于加载到当前的日期的事件 */ private View.OnClickListener onTodayClickListener = new View.OnClickListener() { @Override public void onClick(View view) { calStartDate = Calendar.getInstance(); calSelected = Calendar.getInstance(); updateStartDateForMonth(); generateContetView(mCalendarMainLayout); } }; /** * 用于加载上一个月日期的事件 */ private View.OnClickListener onPreMonthClickListener = new View.OnClickListener() { @Override public void onClick(View view) { viewFlipper.setInAnimation(slideRightIn); viewFlipper.setOutAnimation(slideRightOut); viewFlipper.showPrevious(); setPrevViewItem(); } }; /** * 用于加载下一个月日期的事件 */ private View.OnClickListener onNextMonthClickListener = new View.OnClickListener() { @Override public void onClick(View view) { viewFlipper.setInAnimation(slideLeftIn); viewFlipper.setOutAnimation(slideLeftOut); viewFlipper.showNext(); setNextViewItem(); } }; /** * 主要用于生成发前展示的日历View * * @param layout * 将要用于去加载的布局 */ private void generateContetView(RelativeLayout layout) { // 创建一个垂直的线性布局(整体内容) viewFlipper = new ViewFlipper(this); viewFlipper.setId(CAL_LAYOUT_ID); calStartDate = getCalendarStartDate(); CreateGirdView(); RelativeLayout.LayoutParams params_cal = new RelativeLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); layout.addView(viewFlipper, params_cal); LinearLayout br = new LinearLayout(this); RelativeLayout.LayoutParams params_br = new RelativeLayout.LayoutParams( LayoutParams.FILL_PARENT, 1); params_br.addRule(RelativeLayout.BELOW, CAL_LAYOUT_ID); br.setBackgroundColor(getResources().getColor( R.color.calendar_background)); layout.addView(br, params_br); } /** * 用于创建当前将要用于展示的View */ private void CreateGirdView() { Calendar firstCalendar = Calendar.getInstance(); // 临时 Calendar currentCalendar = Calendar.getInstance(); // 临时 Calendar lastCalendar = Calendar.getInstance(); // 临时 firstCalendar.setTime(calStartDate.getTime()); currentCalendar.setTime(calStartDate.getTime()); lastCalendar.setTime(calStartDate.getTime()); firstGridView = new CalendarGridView(mContext); firstCalendar.add(Calendar.MONTH, -1); firstGridAdapter = new CalendarGridViewAdapter(this, firstCalendar); firstGridView.setAdapter(firstGridAdapter);// 设置菜单Adapter firstGridView.setId(CAL_LAYOUT_ID); currentGridView = new CalendarGridView(mContext); currentGridAdapter = new CalendarGridViewAdapter(this, currentCalendar); currentGridView.setAdapter(currentGridAdapter);// 设置菜单Adapter currentGridView.setId(CAL_LAYOUT_ID); lastGridView = new CalendarGridView(mContext); lastCalendar.add(Calendar.MONTH, 1); lastGridAdapter = new CalendarGridViewAdapter(this, lastCalendar); lastGridView.setAdapter(lastGridAdapter);// 设置菜单Adapter lastGridView.setId(CAL_LAYOUT_ID); currentGridView.setOnTouchListener(this); firstGridView.setOnTouchListener(this); lastGridView.setOnTouchListener(this); if (viewFlipper.getChildCount() != 0) { viewFlipper.removeAllViews(); } viewFlipper.addView(currentGridView); viewFlipper.addView(lastGridView); viewFlipper.addView(firstGridView); String s = calStartDate.get(Calendar.YEAR) + "-" + NumberHelper.LeftPad_Tow_Zero(calStartDate .get(Calendar.MONTH) + 1); mDayMessage.setText(s); } /** * 上一个月 */ private void setPrevViewItem() { mMonthViewCurrentMonth--;// 当前选择月-- // 如果当前月为负数的话显示上一年 if (mMonthViewCurrentMonth == -1) { mMonthViewCurrentMonth = 11; mMonthViewCurrentYear--; } calStartDate.set(Calendar.DAY_OF_MONTH, 1); // 设置日为当月1日 calStartDate.set(Calendar.MONTH, mMonthViewCurrentMonth); // 设置月 calStartDate.set(Calendar.YEAR, mMonthViewCurrentYear); // 设置年 } /** * 下一个月 */ private void setNextViewItem() { mMonthViewCurrentMonth++; if (mMonthViewCurrentMonth == 12) { mMonthViewCurrentMonth = 0; mMonthViewCurrentYear++; } calStartDate.set(Calendar.DAY_OF_MONTH, 1); calStartDate.set(Calendar.MONTH, mMonthViewCurrentMonth); calStartDate.set(Calendar.YEAR, mMonthViewCurrentYear); } /** * 根据改变的日期更新日历 填充日历控件用 */ private void updateStartDateForMonth() { calStartDate.set(Calendar.DATE, 1); // 设置成当月第一天 mMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到当前日历显示的月 mMonthViewCurrentYear = calStartDate.get(Calendar.YEAR);// 得到当前日历显示的年 String s = calStartDate.get(Calendar.YEAR) + "-" + NumberHelper.LeftPad_Tow_Zero(calStartDate .get(Calendar.MONTH) + 1); mDayMessage.setText(s); // 星期一是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); } /** * 用于获取当前显示月份的时间 * * @return 当前显示月份的时间 */ private Calendar getCalendarStartDate() { calToday.setTimeInMillis(System.currentTimeMillis()); calToday.setFirstDayOfWeek(iFirstDayOfWeek); if (calSelected.getTimeInMillis() == 0) { calStartDate.setTimeInMillis(System.currentTimeMillis()); calStartDate.setFirstDayOfWeek(iFirstDayOfWeek); } else { calStartDate.setTimeInMillis(calSelected.getTimeInMillis()); calStartDate.setFirstDayOfWeek(iFirstDayOfWeek); } return calStartDate; } AnimationListener animationListener = new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 当动画完成后调用 CreateGirdView(); } }; class GestureListener extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 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 boolean onSingleTapUp(MotionEvent e) { // 得到当前选中的是第几个单元格 int pos = currentGridView.pointToPosition((int) e.getX(), (int) e.getY()); LinearLayout txtDay = (LinearLayout) currentGridView .findViewById(pos + 5000); if (txtDay != null) { if (txtDay.getTag() != null) { Date date = (Date) txtDay.getTag(); if (CalendarUtil.compare(date, Calendar.getInstance() .getTime())) { calSelected.setTime(date); currentGridAdapter.setSelectedDate(calSelected); currentGridAdapter.notifyDataSetChanged(); firstGridAdapter.setSelectedDate(calSelected); firstGridAdapter.notifyDataSetChanged(); lastGridAdapter.setSelectedDate(calSelected); lastGridAdapter.notifyDataSetChanged(); String week = CalendarUtil.getWeek(calSelected); String message = CalendarUtil.getDay(calSelected) + " 农历" + new CalendarUtil(calSelected).getDay() + " " + week; Toast.makeText(getApplicationContext(), "您选择的日期为:" + message, Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(getApplicationContext(), "选择的日期不能小于今天的日期", Toast.LENGTH_SHORT).show(); } } } Log.i("TEST", "onSingleTapUp - pos=" + pos); return false; } } } 五 package com.easier.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * Created by IntelliJ IDEA. * 把公历时间处理成农历时间 * */ public 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 = 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(int year) { 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(int year) { return (int) (LUNAR_INFO[year - 1900] & 0xf); } /** * 传回农历 year年month月的总天数 * * @param year 将要计算的年份 * @param month 将要计算的月份 * @return 传回农历 year年month月的总天数 */ private static int monthDays(int year, int month) { if ((LUNAR_INFO[year - 1900] & (0x10000 >> month)) == 0) return 29; else return 30; } /** * 传回农历 y年的生肖 * * @return 传回农历 y年的生肖 */ public String animalsYear() { final String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"}; return Animals[(mLuchYear - 4) % 12]; } // ====== 传入 月日的offset 传回干支, 0=甲子 private static String cyclicalm(int num) { final String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; final String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; return (Gan[num % 10] + Zhi[num % 12]); } // ====== 传入 offset 传回干支, 0=甲子 public String 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 */ public CalendarUtil(Calendar cal) { int yearCyl, monCyl, dayCyl; 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); dayCyl = offset + 40; monCyl = 14; // 用offset减去每农历年的天数 // 计算当天是农历第几天 // i最终结果是农历的年份 // offset是当年的第几天 int iYear, daysOfYear = 0; for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) { daysOfYear = yearDays(iYear); offset -= daysOfYear; monCyl += 12; } if (offset < 0) { offset += daysOfYear; iYear--; monCyl -= 12; } // 农历年份 mLuchYear = iYear; yearCyl = iYear - 1864; 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); } else daysOfMonth = monthDays(mLuchYear, iMonth); offset -= daysOfMonth; // 解除闰月 if (isLoap && iMonth == (leapMonth + 1)) isLoap = false; if (!isLoap) monCyl++; } // offset为0时,并且刚才计算的月份是闰月,要校正 if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { if (isLoap) { isLoap = false; } else { isLoap = true; --iMonth; --monCyl; } } // offset小于0时,也要校正 if (offset < 0) { offset += daysOfMonth; --iMonth; --monCyl; } mLuchMonth = iMonth; mLuchDay = offset + 1; } /** * 返化成中文格式 * * @param day * @return */ public static String getChinaDayString(int day) { 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 农历的日期 */ 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 == 1) { message = CHINESE_NUMBER[mLuchMonth - 1] + "月"; } else { message = getChinaDayString(mLuchDay); } } } return message; } /** * 返回农历的年月日 * * @return 农历的年月日格式 */ public String getDay() { return (isLoap ? "闰" : "") + CHINESE_NUMBER[mLuchMonth - 1] + "月" + 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)) >= 0; } /** * 获取当前周几 * * @param calendar * @return */ public static String getWeek(Calendar calendar) { return "周" + WEEK_NUMBER[calendar.get(Calendar.DAY_OF_WEEK) - 1] + ""; } /** * 将当前时间转换成要展示的形式 * * @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) == 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 = "除夕"; } } } return message; } } 六. package com.easier.util; import java.util.Calendar; /** * Created by IntelliJ IDEA. * 对公历日期的处理类 */ public 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 - 1]; } } 七 package com.easier.util; import java.util.Calendar; /** * Created by IntelliJ IDEA. * 对公历日期的处理类 */ public 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 - 1]; } } 八 package com.easier.util; import java.util.Calendar; /** * Created by IntelliJ IDEA. * 主要用于把公历日期处理成24节气 */ public 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 = 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 int sectionalTerm; private int principleTerm; 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 = {"小寒", "立春", "惊蛰", "清明", "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪"}; public SolarTermsUtil(Calendar calendar) { gregorianYear = calendar.get(Calendar.YEAR); gregorianMonth = calendar.get(Calendar.MONTH) + 1; gregorianDate = calendar.get(Calendar.DATE); computeChineseFields(); computeSolarTerms(); } public int computeChineseFields() { 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) < Math.abs(chineseMonth)) chineseYear++; chineseMonth = nextMonth; chineseDate -= lastDate; lastDate = daysInChineseMonth(chineseYear, chineseMonth); nextMonth = nextChineseMonth(chineseYear, chineseMonth); } return 0; } public int computeSolarTerms() { if (gregorianYear < 1901 || gregorianYear > 2100) return 1; sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth); principleTerm = principleTerm(gregorianYear, gregorianMonth); return 0; } public static int sectionalTerm(int y, int m) { 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; return term; } public static int principleTerm(int y, int m) { 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; return term; } /** * 用于判断输入的年份是否为闰年 * * @param year 输入的年份 * @return true 表示闰年 */ public static boolean isGregorianLeapYear(int year) { boolean isLeap = false; if (year % 4 == 0) isLeap = true; if (year % 100 == 0) isLeap = false; if (year % 400 == 0) isLeap = true; return isLeap; } public static int daysInGregorianMonth(int y, int m) { int d = daysInGregorianMonth[m - 1]; if (m == 2 && isGregorianLeapYear(y)) d++; // 公历闰年二月多一天 return d; } public static int daysInChineseMonth(int y, int m) { // 注意:闰月 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; } } } } return d; } public static int nextChineseMonth(int y, int m) { 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; return n; } 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节气的值 */ public String 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]; } return str; } } 九 package com.easier.util; /** * Created by IntelliJ IDEA. * 字符串的处理类 */ public class StringUtil { /** * 判断是否为null或空值 * * @param str String * @return true or false */ public static boolean isNullOrEmpty(String str) { return str == null || str.trim().length() == 0; } /** * 判断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; } }
五.实验效果图
【最终实验效果图】
六.总结
6.1参考资料
(1)《Android实例开发完全手册》
(2) 《疯狂Android讲义》
(3)《Android高级编程》
(4)《第一行代码》
6.2总结语
经过艰苦的奋斗,我的生产实习设计系统——基于安卓的日历系统终于完成了,系统成功通过测试,基本上实现模拟器的实现和手机操作的实现。一切准备就绪后开始进行项目设计的启动,一开始还是遇到了各种各样的问题,通过自己的不断尝试,不断的学习,终于解决了项目中的一些难点,在这过程中我感觉到经历很多,收益很多。其中我了解了很多以前在书本中无法学习到的知识,我发现只有自己实践才能更好地提升自己的能力,我发现光有知识是不够的,还需要与实践相结合,这样才能提高自己的专业知识和操作能力。 -
安卓开发学习-Android Studio-13-表格视图、日历
2021-02-17 08:52:53目录 GridView calendarView DatePicker GridView 表格视图。... import androidx.appcompat.app.AppCompatActivity; import android.os.... 与calendar的区别是在日历表上方增加了一个显示日期的视图。这里就不演示了。 -
手机开发日历农历_求安卓手机软件功能强大的日历提醒便签备忘录软件
2021-01-11 19:29:11有没有一款功能强大的带有日历提醒的手机便签备忘录软件?1、下载个手机版敬业签APP,你可以从手机应用市场搜索“敬业签”手机版下载;下载完打开注册登录账号,点击底部“+”符号;2、输入斋日提醒便签内容,点击... -
安卓源码如何实现日历?
2019-03-15 11:37:23本程序是一个桌面日历为用户提供公历显示。左箭头是调节当日之前的日期,按中间那个年月按钮就可调节到当天所在的日期,右箭头是调节当日之后的日期。 2、 软件开发环境 1.下载eclipse 2.安装eclipse的ADT插件 3.... -
推荐一款Android安卓app开发框架_有超多的控件特效.zip
2021-01-10 22:45:02推荐一款Android安卓app开发框架_有超多的控件特效.zip list分页,grid分页,下拉刷新,进度框,图片轮播,表格,多线程下载器,侧边栏,图片上传,轮子选择,图表,Tab滑动,日历选择器 网络下载,多线程与线程池的... -
安卓开发—04 Android其他控件
2021-01-03 17:32:53CalendarView日历 VideoView视频播放 WebView网页镶嵌 ScrollView滑动控件 1.Switch开关 android:switchMinWidth:设置开关的最小宽度 android:switchPadding:设置滑块内文字的间隔 android:textOff:按钮没有被... -
安卓开发中的日期和时间控件
2012-09-17 23:03:07在web开发中有第三方日历控件,我们可以直接拿过来使用,在安卓开发中我们安卓系统自带了一个选择日期和时间的控件,我们也可以直接使用,怎么使用呢?且看下文。 这篇文章本人收藏了,嘿嘿嘿 原文:安卓开发中的... -
android开发日历控件 可滑动?
2014-10-22 02:34:59谁有做过安卓 日历控件可滑动,点击又可以编程单行日历的,也可以滑动 -
联想日历最新版下载-联想日历精简手机版下载5.60.896.190906.7f09adf 安卓版...
2020-12-29 15:54:29联想日历软件由联想公司进行开发,作为一款日历app,它有着非常全面的功能,支持日常生日,重要节日的提醒,还要相关的节日贺卡,界面非常简洁,还有天气预报的功能,感兴趣的话可以下载体验。联想日历安卓版功能1.... -
Android开发之日历CalendarView用法示例
2021-01-04 23:11:37本文实例讲述了Android开发之日历CalendarView用法。分享给大家供大家参考,具体如下: 简介: 1.CalendarView是安卓自带的一个日历控件 2.在主活动中 通过设置setOnDataChangeListener() 来为其添加监听事件 可在... -
安卓手机上应用开发管理日常
2019-04-21 21:40:04日历式的员工考勤管理,后台基于Bmob。功能包括显示登录(包括账号密码登录,手机验证码登录两种方式)、注册、忘记密码、修改密码等用户管理功能;普通员工注册手机号 -
安卓开发---04 Android其他控件
2020-04-10 09:50:36Switch开关 ...CalendarView日历 VideoView视频播放 WebView网页镶嵌 ScrollView滑动控件 1.Switch开关 android:switchMinWidth:设置开关的最小宽度 android:switchPadding:设置滑块内文字的间隔 and... -
安卓移动应用开发考题_Android移动应用试题
2020-12-20 10:35:32日历C.SQLiteD.SMS程序2.下面哪种说法不正确A.Android应用的gen目录下的R.java被删除后还能自动生成;B.res目录是一个特殊目录,包含了应用程序的全部资源,命名规则可以支持数字(0-9)下横线(_),大小写字母(a-z,A-Z);... -
网络代理工具安卓版_不仅仅是一个日历,更是一款优秀的时间管理工具。
2020-11-15 03:03:42想追求一款电脑版的日历,不仅可以看到农历,还可以看到天气预报的软件,所有小编搜呀搜,突然发现新大陆,这款软件太神奇了,小编不得不佩服开发这款软件的程序猿,真的是太赞了,废话少说,先来看看优效日历的来历... -
手机开发日历农历_手把手教你3??如何让你的「苹果」日历更加好用
2021-01-12 23:15:37相信大家经常看到使用安卓手机的小伙伴,可以很方便的知道一些节假日的假期时间,而自己的iPhone日历却只有一些节假日的时间点,根本不知道自己的假期具体有多久。关于农历设置生日提醒 可以查看《手把手教你6⃣️》... -
安卓开发一些界面控件的小例子(部分内容转载,持续更新ING)
2012-03-19 16:31:23最近开始学习ANDROID开发,从简单的界面控制开始,希望在这里可以得到大家的回应,大家一起指正不足,我把我遇到的问题先来个抛砖引玉 1、我第一个要做的东西是一个定时闹钟的小东西,再加上文本记录,总结了... -
安卓项目结构与安卓体系架构
2018-09-12 10:03:34一、安卓四层体系架构 ...该层提供一些核心应用程序包,例如电子邮件、短信、日历、地图、浏览器和联系人...该层是Android应用开发的基础,开发人员大部分情况是在和它打交道。应用程序框架层包括活动管理... -
开发的应用在安卓10会闪退_冤枉三星了,除华为外很多安卓10手机碰到它都会系统崩溃...
2020-12-04 17:34:48前段时间,由于很多三星老用户没有及时更新系统,导致自己手机出现「闰四月」日历Bug进而出现手机崩溃情况,此事甚至还上了微博热搜。万万没想到的是,就在日历Bug事件还未彻底停息时,又有大量网友发现了三星手机新... -
安卓桌面小组件
2016-04-05 12:52:33今天开发中用到了桌面小组件,可以说安卓中的小组件用起来是非常的方便和实用的,比如显示日期时间,手电筒,日历,天气预报这些小组件。 下面就告诉大家如何创建你的小组件!1.首先你要创建一个类似广播一样的东西... -
vue移动端日历组件封装
2019-05-21 16:35:45最近项目需求,需要做一个移动端的日历,类似于安卓原生日历。晚上找了很多成熟的插件都不是想要。偶然的机会发现某篇博客上有人写的有类似的,于是拿过来稍加改造,终于可以用了。在这里非常感谢这位博主,省去我很... -
安卓图标_不开玩笑,安卓可以体验 "Windows 10" 了
2020-12-15 15:57:14不知道当年有多少人因为微软...由于 Windows Phone 上的应用实在太少,有些厂商根本不愿意为它开发应用,所以一些用户不得不投向其它平台的手机,如安卓、iOS。后来微软也宣布砍掉了 Windows Phone 系统。但是 Wind... -
安卓平台架构及特性
2016-04-08 19:11:11开发者开发的程序和系统程序都是平等的,都是通过访问安卓提供的API框架; 大量的API供开发者使用。除了作为应用程序开发的基础,也可以成为软件复用的手段。 3、函数库 系统C库:为嵌入式Linux -
调用Android自带日历功能
2011-01-22 16:10:27推荐安卓开发神器(里面有各种UI特效和android代码库实例) Android手机配备有一个内置的日历应用程序。第三方应用程序可以利用日历内容提供商接口读取用户的日历信息和安排在日历新的事件。这个日历可以直接同步... -
android日历提醒之简单实用
2018-07-12 17:37:29前言:我们在自己的项目开发中,经常会有预约提醒、定时提醒等方面的需求,这时我们可以使用安卓自己的系统日历来实现。 通过代码向系统日历中写入日历事件、设置提醒,就可以实现到特定时间时提醒用户的功能。当然...