很久没有写博客了,深知这样是不对的,今日多次反省之后,跟大家分享一个关于日历的功能
简单的描述一下日历的功能:
- 左右滑动可以切换日期
- 日期中有阴历和阳历两个日期
- 选中日期时,会有一个圆形背景效果,如果当日有添加的事务或提醒,在日期下方会有一个白色的小点
- 有事务或提醒的日期没有被选中时,下方会有一个橙色的小点
效果图如下:
如果希望日历能够支持节日、生肖等功能可以自行修改代码来支持想要的功能。欢迎建议和拍砖!
别的不多说,上代码!
alert_calendar_layout.xml
AlertCalendarActivity.java<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/common_body_style" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <include android:layout_width="match_parent" android:layout_height="wrap_content" layout="@layout/public_header_layout" /> <LinearLayout android:id="@+id/root_calendar_layout_id" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="6" android:background="#F5F5F5" android:orientation="vertical" android:paddingLeft="18dp" android:paddingRight="18dp" > <LinearLayout android:id="@+id/root_week_layout_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="5dp" android:paddingTop="5dp" > <TextView style="@style/weekName" android:text="周日" android:textColor="#b1b1b1" /> <TextView style="@style/weekName" android:text="周一" /> <TextView style="@style/weekName" android:text="周二" /> <TextView style="@style/weekName" android:text="周三" /> <TextView style="@style/weekName" android:text="周四" /> <TextView style="@style/weekName" android:text="周五" /> <TextView style="@style/weekName" android:text="周六" android:textColor="#b1b1b1" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:background="#b1b1b1"/> <ViewFlipper android:paddingTop="5dp" android:id="@+id/flipper" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> <ListView android:id="@+id/service_message_scroll_view_id" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="4" > </ListView> </LinearLayout>
CalendarItemOnclickListener.javapackage com.xxx.xxx.Activity.Alert; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.animation.AnimationUtils; import android.widget.GridView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.ListView; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.ViewFlipper; import com.xxx.xxx.R; import com.xxx.xxx.Activity.CommonActivity; import com.xxx.xxx.Listener.View.CalendarItemOnclickListener; import com.xxx.xxx.adapter.CalendarAdapter; public class AlertCalendarActivity extends CommonActivity implements View.OnClickListener { private GestureDetector gestureDetector = null; public static CalendarAdapter calV = null; private ViewFlipper flipper = null; private GridView gridView = null; private static int jumpMonth = 0; // 每次滑动,增加或减去一个月,默认为0(即显示当前月) private static int jumpYear = 0; // 滑动跨越一年,则增加或者减去一年,默认为0(即当前年) private int year_c = 0; private int month_c = 0; private int day_c = 0; private String currentDate = ""; /** 每次添加gridview到viewflipper中时给的标记 */ private int gvFlag = 0; /** 当前的年月,现在日历顶端 */ private TextView currentMonth; // /** 上个月 */ // private ImageView prevMonth; // /** 下个月 */ // private ImageView nextMonth; // 修改后的上一个点击的日期 public static View previousOnclickDateView; // 修改前的上一个点击的日期位置 public static int[] previousOnclickDateViewPosition = new int[3]; // 日历根布局 private LinearLayout rootCalenderLinearLayout; public static Activity INSTANCE; public AlertCalendarActivity() { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); currentDate = sdf.format(date); // 当期日期 year_c = Integer.parseInt(currentDate.split("-")[0]); month_c = Integer.parseInt(currentDate.split("-")[1]); day_c = Integer.parseInt(currentDate.split("-")[2]); } public void onCreate(Bundle savedInstanceState) { INSTANCE = this; super.TAG = AlertCalendarActivity.class.getCanonicalName(); super.context = AlertCalendarActivity.this; super.onCreate(savedInstanceState, R.layout.alert_calendar_layout); // commonHeaderTitleTextView = // (TextView)findViewById(R.id.common_header_title); // 移除头部标题组件 TableLayout commonHeaderTitleTableLayout = (TableLayout) View.inflate( this.context, R.layout.public_header_layout, null); /* * TableRow commonHeaderTitleTableRow = (TableRow) * commonHeaderTitleTableLayout.getChildAt(0); */ TableRow commonHeaderTitleTableRow = (TableRow) findViewById(R.id.common_header_title_row_id); commonHeaderTitleTableRow.removeViewAt(1); // 添加日期选择组件 LinearLayout linearLayout = (LinearLayout) View.inflate(this.context, R.layout.alert_calendar_date_change_layout, null); // 设置日期 TextView dateTextView = (TextView) linearLayout .findViewById(R.id.alert_calendar_date_text_id); dateTextView.setText("2014-11-29"); commonHeaderTitleTableRow.addView(linearLayout, 1); LayoutParams layoutParams = (LayoutParams) commonHeaderTitleTableRow .getChildAt(1).getLayoutParams(); layoutParams.gravity = Gravity.CENTER; linearLayout.setLayoutParams(layoutParams); commonHeaderTitleTableLayout.setColumnShrinkable(1, true); commonHeaderTitleTableLayout.setColumnStretchable(1, true); // 设置头部右侧图标 commonHeaderTitleRightButton .setBackgroundResource(R.drawable.calendar_today_button_background); commonHeaderTitleRightButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { int jumpMonthTemp = jumpMonth < 0 ? 0 - jumpMonth : jumpMonth; for (int i = 0; i < jumpMonthTemp; i++) { if (jumpMonth < 0) { enterNextMonth(gvFlag); } else { enterPrevMonth(gvFlag); } } initCalendar(); } }); initCalendar(); } /** * 初始化日历 * * */ private void initCalendar() { // setContentView(R.layout.calendar); rootCalenderLinearLayout = (LinearLayout) findViewById(R.id.root_calendar_layout_id); currentMonth = (TextView) findViewById(R.id.alert_calendar_date_text_id); // prevMonth = (ImageView) findViewById(R.id.prevMonth); // nextMonth = (ImageView) findViewById(R.id.nextMonth); // setListener(); gestureDetector = new GestureDetector(this, new MyGestureListener()); flipper = (ViewFlipper) findViewById(R.id.flipper); flipper.removeAllViews(); calV = new CalendarAdapter(this, this, getResources(), jumpMonth, jumpYear, year_c, month_c, day_c); addGridView(); gridView.setAdapter(calV); flipper.addView(gridView, 0); addTextToTopTextView(currentMonth); } private class MyGestureListener extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { int gvFlag = 0; // 每次添加gridview到viewflipper中时给的标记 if (e1.getX() - e2.getX() > 120) { // 像左滑动 enterNextMonth(gvFlag); return true; } else if (e1.getX() - e2.getX() < -120) { // 向右滑动 enterPrevMonth(gvFlag); return true; } return false; } } /** * 移动到下一个月 * * @param gvFlag */ private void enterNextMonth(int gvFlag) { addGridView(); // 添加一个gridView jumpMonth++; // 下一个月 calV = new CalendarAdapter(context, this, this.getResources(), jumpMonth, jumpYear, year_c, month_c, day_c); gridView.setAdapter(calV); addTextToTopTextView(currentMonth); // 移动到下一月后,将当月显示在头标题中 gvFlag++; flipper.addView(gridView, gvFlag); flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out)); flipper.showNext(); flipper.removeViewAt(0); cleanShowAlertList(); } /** * 移动到上一个月 * * @param gvFlag */ private void enterPrevMonth(int gvFlag) { addGridView(); // 添加一个gridView jumpMonth--; // 上一个月 calV = new CalendarAdapter(context, this, this.getResources(), jumpMonth, jumpYear, year_c, month_c, day_c); gridView.setAdapter(calV); gvFlag++; addTextToTopTextView(currentMonth); // 移动到上一月后,将当月显示在头标题中 flipper.addView(gridView, gvFlag); flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in)); flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out)); flipper.showPrevious(); flipper.removeViewAt(0); cleanShowAlertList(); } /** * 添加头部的年份 闰哪月等信息 * * @param view */ public void addTextToTopTextView(TextView view) { StringBuffer textDate = new StringBuffer(); // draw = getResources().getDrawable(R.drawable.top_day); // view.setBackgroundDrawable(draw); textDate.append(calV.getShowYear()).append("年") .append(calV.getShowMonth()).append("月").append("\t"); view.setText(textDate); } private void addGridView() { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); // 取得屏幕的宽度和高度 /* * WindowManager windowManager = getWindowManager(); Display display = * windowManager.getDefaultDisplay(); int Width = display.getWidth(); * int Height = display.getHeight(); */ // 获取日历控件所在布局宽高 int Height = rootCalenderLinearLayout.getMeasuredHeight(); int Width = rootCalenderLinearLayout.getMeasuredWidth(); int numberColumns = 7; gridView = new GridView(this); gridView.setNumColumns(numberColumns); gridView.setColumnWidth(Width / numberColumns); // gridView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); /* * if (Width == 720 && Height == 1280) { gridView.setColumnWidth(40); } */ gridView.setGravity(Gravity.CENTER_VERTICAL); gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); // 去除gridView边框 gridView.setVerticalSpacing(1); gridView.setHorizontalSpacing(1); gridView.setOnTouchListener(new OnTouchListener() { // 将gridview中的触摸事件回传给gestureDetector public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return AlertCalendarActivity.this.gestureDetector .onTouchEvent(event); } }); gridView.setOnItemClickListener(new CalendarItemOnclickListener( context, this)); gridView.setLayoutParams(params); } // private void setListener() { // prevMonth.setOnClickListener(this); // nextMonth.setOnClickListener(this); // } // @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.nextMonth: // 下一个月 enterNextMonth(gvFlag); break; case R.id.prevMonth: // 上一个月 enterPrevMonth(gvFlag); break; default: break; } } /** * 清除查询的提醒列表 * * */ public void cleanShowAlertList() { ListView listView = (ListView) findViewById(R.id.service_message_scroll_view_id); listView.setAdapter(null); } }
SpecialCalendar.javapackage com.xxx.xxx.Listener.View; import java.util.List; import android.app.Activity; import android.content.Context; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import com.xxx.xxx.R; import com.xxx.xxx.Activity.Alert.AlertCalendarActivity; import com.xxx.xxx.Dao.impl.AlertSettingDao; import com.xxx.xxx.Domain.Object.AlertSetting; import com.xxx.xxx.Utils.Calendar.SpecialCalendar; import com.xxx.xxx.adapter.CalendarAdapter.CalendarItemViewHolder; import com.xxx.xxx.adapter.CalendarSearchAlertAdapter; import com.xxx.xxx.provider.AlertContentProvider; public class CalendarItemOnclickListener implements OnItemClickListener { private final static String TAG = CalendarItemOnclickListener.class .getCanonicalName(); private Context context; private Activity activity; public CalendarItemOnclickListener(Context context, Activity activity) { this.context = context; this.activity = activity; } public void onItemClick(AdapterView<?> parent, View view, int position, long id) { CalendarItemViewHolder viewHolder = (CalendarItemViewHolder) view .getTag(); // TODO Auto-generated method stub // 点击任何一个item,得到这个item的日期(排除点击的是周日到周六(点击不响应)) int startPosition = AlertCalendarActivity.calV.getStartPositon(); int endPosition = AlertCalendarActivity.calV.getEndPosition(); // View defaultView = view; // 设置当前点击日期背景颜色 AlertCalendarActivity.calV.setCheckedBackground(view); // 其他日期去除添加的背景色 if (null != AlertCalendarActivity.previousOnclickDateView && AlertCalendarActivity.previousOnclickDateView != view) { AlertCalendarActivity.calV.recoverStyle( AlertCalendarActivity.previousOnclickDateView, AlertCalendarActivity.previousOnclickDateViewPosition); } AlertCalendarActivity.previousOnclickDateView = view; int scheduleDay = AlertCalendarActivity.calV.getDateByClickItem( position).getDay(); // 这一天的阳历 // String scheduleLunarDay = // calV.getDateByClickItem(position).split("\\.")[1]; // //这一天的阴历 int scheduleYear = AlertCalendarActivity.calV.getShowYear(); int scheduleMonth = AlertCalendarActivity.calV.getShowMonth(); AlertCalendarActivity.previousOnclickDateViewPosition[0] = position; AlertCalendarActivity.previousOnclickDateViewPosition[1] = Integer .valueOf(scheduleDay); AlertCalendarActivity.previousOnclickDateViewPosition[2] = new SpecialCalendar() .getWeekdayOfMonth(scheduleYear, scheduleMonth); /* * if (startPosition <= position + 7 && position <= endPosition - 7) { * * // Toast.makeText(CalendarActivity.this, "点击了该条目", // * Toast.LENGTH_SHORT).show(); } */ Log.d(TAG, scheduleYear + "-" + scheduleMonth + "-" + scheduleDay); if (viewHolder.ifExistsAlert) { // if(AlertCalendarActivity.previousOnclickDateView == view) return; resetItems(scheduleYear, scheduleMonth - 1, scheduleDay); } else { ListView listView = (ListView) activity .findViewById(R.id.service_message_scroll_view_id); listView.setAdapter(null); } } /** * 插入提醒项 * */ public void resetItems(int year, int month, int day) { // 搜索当日所有提醒 List<AlertSetting> alertSettings = AlertSettingDao.getInstance() .selectAll( activity.getContentResolver(), AlertContentProvider.COLUMN_YEAR + "=" + year + " AND " + AlertContentProvider.COLUMN_MONTH + "=" + month + " AND " + AlertContentProvider.COLUMN_DAY + "=" + day); ListView listView = (ListView) activity .findViewById(R.id.service_message_scroll_view_id); listView.setAdapter(new CalendarSearchAlertAdapter(context, AlertCalendarActivity.INSTANCE, alertSettings)); /* * listView.setOnItemClickListener(new OnItemClickListener() { * * public void onItemClick(AdapterView<?> parent, View view, int * position, long id) { ViewHolder viewHolder = (ViewHolder) * view.getTag(); * viewHolder.selectedTextView.setVisibility(View.VISIBLE); * view.setBackgroundColor(getResources().getColor( * android.R.color.transparent)); int length = parent.getCount(); * for(int i = 0 ; i < length ; i++){ if(i== position) continue; * parent.getChildAt(i).findViewById(R.id.alert_calendar_selected_id * ).setVisibility(View.GONE); } } }); */ } }
package com.zhirunjia.housekeeper.Utils.Calendar; import java.util.Calendar; /** * 闰年月算法 * * @author Vincent Lee * */ public class SpecialCalendar { private int daysOfMonth = 0; // 某月的天数 private int dayOfWeek = 0; // 具体某一天是星期几 // 判断是否为闰年 public boolean isLeapYear(int year) { if (year % 100 == 0 && year % 400 == 0) { return true; } else if (year % 100 != 0 && year % 4 == 0) { return true; } return false; } // 得到某月有多少天数 public int getDaysOfMonth(boolean isLeapyear, int month) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: daysOfMonth = 31; break; case 4: case 6: case 9: case 11: daysOfMonth = 30; break; case 2: if (isLeapyear) { daysOfMonth = 29; } else { daysOfMonth = 28; } } return daysOfMonth; } // 指定某年中的某月的第一天是星期几 public int getWeekdayOfMonth(int year, int month) { Calendar cal = Calendar.getInstance(); cal.set(year, month - 1, 1); dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1; return dayOfWeek; } }
CalendarAdapter.javaLunarCalendar.javapackage com.xxx.xxx.adapter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.xxx.xxx.R; import com.xxx.xxx.Dao.impl.AlertSettingDao; import com.xxx.xxx.Domain.Object.AlertSetting; import com.xxx.xxx.Listener.View.CalendarItemOnclickListener; import com.xxx.xxx.Utils.Calendar.LunarCalendar; import com.xxx.xxx.Utils.Calendar.SpecialCalendar; import com.xxx.xxx.provider.AlertContentProvider; /** * 日历gridview中的每一个item显示的textview * * @author Vincent Lee * */ public class CalendarAdapter extends BaseAdapter { private final static String TAG = CalendarAdapter.class.getCanonicalName(); // 当月的提醒对象列表 private List<AlertSetting> alertSettings; private boolean isLeapyear = false; // 是否为闰年 private int daysOfMonth = 0; // 某月的天数 private int dayOfWeek = 0; // 具体某一天是星期几 private int lastDaysOfMonth = 0; // 上一个月的总天数 private Context context; private Activity activity; private int dayNumberLength = 42; private List<DayNumber> dayNumbers = new ArrayList<CalendarAdapter.DayNumber>( dayNumberLength); // private String[] dayNumber = new String[42]; // 一个gridview中的日期存入此数组中 // private static String week[] = {"周日","周一","周二","周三","周四","周五","周六"}; private SpecialCalendar specialCalendar = null; private LunarCalendar lunarCalendar = null; private Resources resources = null; private Drawable drawable = null; private int currentYear; private int currentMonth; private int currentDay; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); private int currentFlag = -1; // 用于标记当天 // private int[] schDateTagFlag = null; // 存储当月所有的日程日期 private int showYear; // 用于在头部显示的年份 private int showMonth; // 用于在头部显示的月份 private String animalsYear; private int leapMonth; // 闰哪一个月 private String cyclical = ""; // 天干地支 // 系统当前时间 private String systemDate; private int systemYear; private int systemMonth; private int systemDay; public CalendarAdapter() { Date date = new Date(); systemDate = sdf.format(date); // 当期日期 Calendar calendar = Calendar.getInstance(); systemYear = calendar.get(Calendar.YEAR); systemMonth = calendar.get(Calendar.MONTH); systemDay = calendar.get(Calendar.DAY_OF_MONTH); Log.d(TAG, "当前日期:" + systemDate + " | " + systemYear + "-" + systemMonth + "-" + systemDay); } public CalendarAdapter(Context context, Activity activity, Resources resources, int jumpMonth, int jumpYear, int year_c, int month_c, int day_c) { this(); this.context = context; this.activity = activity; specialCalendar = new SpecialCalendar(); lunarCalendar = new LunarCalendar(); this.resources = resources; int stepYear = year_c + jumpYear; int stepMonth = month_c + jumpMonth; if (stepMonth > 0) { // 往下一个月滑动 if (stepMonth % 12 == 0) { stepYear = year_c + stepMonth / 12 - 1; stepMonth = 12; } else { stepYear = year_c + stepMonth / 12; stepMonth = stepMonth % 12; } } else { // 往上一个月滑动 stepYear = year_c - 1 + stepMonth / 12; stepMonth = stepMonth % 12 + 12; if (stepMonth % 12 == 0) { } } currentYear = stepYear; // 得到当前的年份 currentMonth = stepMonth; // 得到本月 // (jumpMonth为滑动的次数,每滑动一次就增加一月或减一月) currentDay = day_c; // 得到当前日期是哪天 getCalendar(currentYear, currentMonth); // 查询当月所有提醒 alertSettings = AlertSettingDao.getInstance().selectAll( context.getContentResolver(), AlertContentProvider.COLUMN_YEAR + "=" + currentYear + " and " + AlertContentProvider.COLUMN_MONTH + "=" + (Integer.valueOf(currentMonth) - 1) + " ) GROUP BY ( day "); } public CalendarAdapter(Context context, Resources resources, int year, int month, int day) { this(); this.context = context; specialCalendar = new SpecialCalendar(); lunarCalendar = new LunarCalendar(); this.resources = resources; currentYear = year;// 得到跳转到的年份 currentMonth = month; // 得到跳转到的月份 currentDay = day; // 得到跳转到的天 getCalendar(currentYear, currentMonth); } // @Override public int getCount() { // TODO Auto-generated method stub return dayNumbers.size(); } // @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } // @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } // @Override public View getView(int position, View convertView, ViewGroup parent) { CalendarItemViewHolder viewHolder = new CalendarItemViewHolder(); // if (convertView == null) { convertView = View.inflate(context, R.layout.calendar_item, null); // } // 当日有提醒的图片标志 /* * ImageView alertDateImageView = (ImageView) convertView * .findViewById(R.id.alert_date_icon_id); */ // 阳历日期文本控件 TextView dateTextView = (TextView) convertView .findViewById(R.id.alert_date_text_id); // 阴历日期文本控件 TextView chinaDateTextView = (TextView) convertView .findViewById(R.id.alert_china_date_text_id); ImageView imageView = (ImageView) convertView .findViewById(R.id.alert_date_icon_id); DayNumber dayNumber = dayNumbers.get(position); String dateString = dayNumber.day + ""; // dayNumber[position].split("\\.")[0]; String chinaDateString = dayNumber.chinaDayString; dateTextView.setText(dateString); chinaDateTextView.setText(chinaDateString); for (AlertSetting alertSetting : alertSettings) { if (dayNumber.day == alertSetting.getDay() && dayNumber.month == alertSetting.getMonth() + 1 && dayNumber.year == alertSetting.getYear()) { imageView.setBackgroundResource(R.drawable.dot_2x); viewHolder.ifExistsAlert = true; } } setDateTextColor(dateTextView, chinaDateTextView, position, daysOfMonth, dayOfWeek); convertView.setTag(viewHolder); if (currentFlag == position) { // TODO 设置当天的背景 // View checkedView = convertView; /* * AlertCalendarActivity.previousOnclickDateViewPosition[0] = * position; * AlertCalendarActivity.previousOnclickDateViewPosition[1] = * daysOfMonth; * AlertCalendarActivity.previousOnclickDateViewPosition[2] = * dayOfWeek; setCheckedBackground(convertView); * AlertCalendarActivity.previousOnclickDateView = convertView; */ new CalendarItemOnclickListener(context, activity).onItemClick( (AdapterView<?>) parent, convertView, position, position); } final View dateView = convertView; ViewTreeObserver viewTreeObserver = dateView.getViewTreeObserver(); viewTreeObserver .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { dateView.getViewTreeObserver().removeOnPreDrawListener( this); int height = dateView.getMeasuredHeight(); int width = dateView.getMeasuredWidth(); ViewGroup.LayoutParams layoutParams = dateView .getLayoutParams(); layoutParams.width = height; dateView.setLayoutParams(layoutParams); Log.d(TAG, "convertView: " + height + " , " + width); return true; } }); return dateView; } /** * 设置字体颜色 * */ public void setDateTextColor(TextView dateTextView, TextView chinaDateTextView, int position, int daysOfMonth, int dayOfWeek) { dateTextView.setTextColor(Color.parseColor("#b1b1b1"));// 当月字体设黑 chinaDateTextView.setTextColor(dateTextView.getTextColors());// 当月字体设黑 if (position < daysOfMonth + dayOfWeek && position >= dayOfWeek) { // 当前月信息显示 dateTextView.setTextColor(Color.parseColor("#666666"));// 当月字体设黑 chinaDateTextView.setTextColor(dateTextView.getTextColors());// 当月字体设黑 if (position % 7 == 0 || position % 7 == 6) { // 当前月信息显示 dateTextView.setTextColor(Color.parseColor("#b1b1b1"));// 当月字体设黑 chinaDateTextView.setTextColor(dateTextView.getTextColors());// 当月字体设黑 } } } // 得到某年的某月的天数且这月的第一天是星期几 public void getCalendar(int year, int month) { isLeapyear = specialCalendar.isLeapYear(year); // 是否为闰年 daysOfMonth = specialCalendar.getDaysOfMonth(isLeapyear, month); // 某月的总天数 dayOfWeek = specialCalendar.getWeekdayOfMonth(year, month); // 某月第一天为星期几 lastDaysOfMonth = specialCalendar.getDaysOfMonth(isLeapyear, month - 1); // 上一个月的总天数 Log.d("DAY", isLeapyear + " ====== " + daysOfMonth + " ============ " + dayOfWeek + " ========= " + lastDaysOfMonth); getDayNumber(year, month); } /** * 设置选中时的背景色 * * @param view * @return view */ public View setCheckedBackground(View view) { CalendarItemViewHolder viewHolder = (CalendarItemViewHolder) view .getTag(); LinearLayout linearLayout = (LinearLayout) view; linearLayout.setBackgroundResource(R.drawable.calendar_background); ImageView imageView = (ImageView) linearLayout.getChildAt(2); ImageView imageView2 = (ImageView) linearLayout.getChildAt(3); TextView dateTextView = (TextView) linearLayout.getChildAt(0); TextView chinaDateTextView = (TextView) linearLayout.getChildAt(1); if (viewHolder.ifExistsAlert) { imageView2.setVisibility(View.VISIBLE); imageView.setVisibility(View.GONE); } dateTextView.setTextColor(Color.WHITE); chinaDateTextView.setTextColor(Color.WHITE); return view; } /** * 原始样式view * * @param oldView * @param newView */ public void recoverStyle(View view, int[] defaultViewPosition) { // default /* * LinearLayout defaultViewLinearLayout = (LinearLayout)defaultView; * ImageView defaultViewImageView = (ImageView) * defaultViewLinearLayout.getChildAt(0); TextView * defaultViewDateTextView = * (TextView)defaultViewLinearLayout.getChildAt(1); TextView * defaultViewChinaDateTextView = * (TextView)defaultViewLinearLayout.getChildAt(2); */ // new LinearLayout viewLinearLayout = (LinearLayout) view; viewLinearLayout.setBackgroundColor(Color.parseColor("#F5F5F5")); ImageView viewImageView = (ImageView) viewLinearLayout.getChildAt(2); ImageView view2ImageView = (ImageView) viewLinearLayout.getChildAt(3); viewImageView.setVisibility(View.VISIBLE); view2ImageView.setVisibility(View.GONE); TextView viewDateTextView = (TextView) viewLinearLayout.getChildAt(0); TextView viewChinaDateTextView = (TextView) viewLinearLayout .getChildAt(1); // if(defaultViewImageView.getVisibility() == View.VISIBLE){ // viewImageView.setBackgroundResource(R.drawable.dot_2x); setDateTextColor(viewDateTextView, viewChinaDateTextView, defaultViewPosition[0], defaultViewPosition[1], defaultViewPosition[2]); } // 将一个月中的每一天的值添加入数组dayNumber中 private void getDayNumber(int year, int month) { int j = 1; int flag = 0; String lunarDay = ""; for (int i = 0; i < dayNumberLength; i++) { DayNumber dayNumber = new DayNumber(); dayNumber.setYear(year); // 周一 // if(i<7){ // dayNumber[i]=week[i]+"."+" "; // } if (i < dayOfWeek) { // 前一个月 int temp = lastDaysOfMonth - dayOfWeek + 1; lunarDay = lunarCalendar.getLunarDate(year, month - 1, temp + i, false); dayNumber.setMonth(month - 1); dayNumber.setDay(temp + i); dayNumber.setChinaDayString(lunarDay); } else if (i < daysOfMonth + dayOfWeek) { // 本月 int day = i - dayOfWeek + 1; // 得到的日期 lunarDay = lunarCalendar.getLunarDate(year, month, i - dayOfWeek + 1, false); dayNumber.setMonth(month); dayNumber.setDay(day); dayNumber.setChinaDayString(lunarDay); // 对于当前月才去标记当前日期 if (systemYear == year && systemMonth + 1 == month && systemDay == day) { // 标记当前日期 currentFlag = i; } setShowYear(year); setShowMonth(month); setAnimalsYear(lunarCalendar.animalsYear(year)); setLeapMonth(lunarCalendar.leapMonth == 0 ? 0 : lunarCalendar.leapMonth); setCyclical(lunarCalendar.cyclical(year)); } else { // 下一个月 lunarDay = lunarCalendar .getLunarDate(year, month + 1, j, false); dayNumber.setMonth(month + 1); dayNumber.setDay(j); dayNumber.setChinaDayString(lunarDay); j++; } dayNumbers.add(dayNumber); } String abc = ""; for (int i = 0; i < dayNumberLength; i++) { abc = abc + dayNumbers.get(i).getYear() + "-" + dayNumbers.get(i).getMonth() + "-" + dayNumbers.get(i).getDay() + " " + dayNumbers.get(i).getChinaDayString(); if ((i + 1) % 7 == 0) { abc = abc + "\n"; } } Log.d(TAG, "DAYNUMBER" + abc); } public void matchScheduleDate(int year, int month, int day) { } /** * 点击每一个item时返回item中的日期 * * @param position * @return */ public DayNumber getDateByClickItem(int position) { return dayNumbers.get(position); } /** * 在点击gridView时,得到这个月中第一天的位置 * * @return */ public int getStartPositon() { return dayOfWeek + 7; } /** * 在点击gridView时,得到这个月中最后一天的位置 * * @return */ public int getEndPosition() { return (dayOfWeek + daysOfMonth + 7) - 1; } public int getShowYear() { return showYear; } public void setShowYear(int showYear) { this.showYear = showYear; } public int getShowMonth() { return showMonth; } public void setShowMonth(int showMonth) { this.showMonth = showMonth; } public String getAnimalsYear() { return animalsYear; } public void setAnimalsYear(String animalsYear) { this.animalsYear = animalsYear; } public int getLeapMonth() { return leapMonth; } public void setLeapMonth(int leapMonth) { this.leapMonth = leapMonth; } public String getCyclical() { return cyclical; } public void setCyclical(String cyclical) { this.cyclical = cyclical; } public static class CalendarItemViewHolder { public boolean ifExistsAlert = false; } public class DayNumber { private int year; private int month; private int day; private int week; private String chinaDayString; public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { if (month < 0) { this.year -= 1; this.month = 12; return; } if (month > 12) { this.year += 1; this.month = month - 12; return; } this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public int getWeek() { return week; } public void setWeek(int week) { this.week = week; } public String getChinaDayString() { return chinaDayString; } public void setChinaDayString(String chinaDayString) { this.chinaDayString = chinaDayString; } } }
package com.xxx.xxx.Utils.Calendar; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * 农历算法 * * @author Vincent Lee * */ public class LunarCalendar { private int year; // 农历的年份 private int month; private int day; private String lunarMonth; // 农历的月份 private boolean leap; public int leapMonth = 0; // 闰的是哪个月 final static String chineseNumber[] = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" }; static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); final static long[] lunarInfo = 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 }; // 农历部分假日 final static String[] lunarHoliday = new String[] { "0101 春节", "0115 元宵", "0505 端午", "0707 情人", "0715 中元", "0815 中秋", "0909 重阳", "1208 腊八", "1224 小年", "0100 除夕" }; // 公历部分节假日 final static String[] solarHoliday = new String[] { // "0101 元旦", "0214 情人", "0308 妇女", "0312 植树", "0315 消费者权益日", "0401 愚人", "0501 劳动", "0504 青年", // "0512 护士", "0601 儿童", "0701 建党", "0801 建军", "0808 父亲", "0909 毛泽东逝世纪念", "0910 教师", "0928 孔子诞辰",// "1001 国庆", "1006 老人", "1024 联合国日", "1112 孙中山诞辰纪念", "1220 澳门回归纪念", "1225 圣诞", "1226 毛泽东诞辰纪念" }; // ====== 传回农历 y年的总天数 final private static int yearDays(int y) { int i, sum = 348; for (i = 0x8000; i > 0x8; i >>= 1) { if ((lunarInfo[y - 1900] & i) != 0) sum += 1; } return (sum + leapDays(y)); } // ====== 传回农历 y年闰月的天数 final private static int leapDays(int y) { if (leapMonth(y) != 0) { if ((lunarInfo[y - 1900] & 0x10000) != 0) return 30; else return 29; } else return 0; } // ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0 final private static int leapMonth(int y) { int result = (int) (lunarInfo[y - 1900] & 0xf); return result; } // ====== 传回农历 y年m月的总天数 final private static int monthDays(int y, int m) { if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) return 29; else return 30; } // ====== 传回农历 y年的生肖 final public String animalsYear(int year) { final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; return Animals[(year - 4) % 12]; } // ====== 传入 月日的offset 传回干支, 0=甲子 final 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=甲子 final public String cyclical(int year) { int num = year - 1900 + 36; return (cyclicalm(num)); } 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] + chineseNumber[n]; } /** */ /** * 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数 * dayCyl5:与1900年1月31日相差的天数,再加40 ? * * isday: 这个参数为false---日期为节假日时,阴历日期就返回节假日 ,true---不管日期是否为节假日依然返回这天对应的阴历日期 * * @param cal * @return */ public String getLunarDate(int year_log, int month_log, int day_log, boolean isday) { // @SuppressWarnings("unused") int yearCyl, monCyl, dayCyl; // int leapMonth = 0; String nowadays; Date baseDate = null; Date nowaday = null; try { baseDate = chineseDateFormat.parse("1900年1月31日"); } catch (ParseException e) { e.printStackTrace(); // To change body of catch statement use // Options | File Templates. } nowadays = year_log + "年" + month_log + "月" + day_log + "日"; try { nowaday = chineseDateFormat.parse(nowadays); } catch (ParseException e) { e.printStackTrace(); // To change body of catch statement use // Options | File Templates. } // 求出和1900年1月31日相差的天数 int offset = (int) ((nowaday.getTime() - baseDate.getTime()) / 86400000L); dayCyl = offset + 40; monCyl = 14; // 用offset减去每农历年的天数 // 计算当天是农历第几天 // i最终结果是农历的年份 // offset是当年的第几天 int iYear, daysOfYear = 0; for (iYear = 1900; iYear < 10000 && offset > 0; iYear++) { daysOfYear = yearDays(iYear); offset -= daysOfYear; monCyl += 12; } if (offset < 0) { offset += daysOfYear; iYear--; monCyl -= 12; } // 农历年份 year = iYear; setYear(year); // 设置公历对应的农历年份 yearCyl = iYear - 1864; leapMonth = leapMonth(iYear); // 闰哪个月,1-12 leap = false; // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天 int iMonth, daysOfMonth = 0; for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) { // 闰月 if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { --iMonth; leap = true; daysOfMonth = leapDays(year); } else daysOfMonth = monthDays(year, iMonth); offset -= daysOfMonth; // 解除闰月 if (leap && iMonth == (leapMonth + 1)) leap = false; if (!leap) monCyl++; } // offset为0时,并且刚才计算的月份是闰月,要校正 if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { if (leap) { leap = false; } else { leap = true; --iMonth; --monCyl; } } // offset小于0时,也要校正 if (offset < 0) { offset += daysOfMonth; --iMonth; --monCyl; } month = iMonth; setLunarMonth(chineseNumber[month - 1] + "月"); // 设置对应的阴历月份 day = offset + 1; if (isday) { // 如果日期为节假日则阴历日期则返回节假日 // setLeapMonth(leapMonth); for (int i = 0; i < solarHoliday.length; i++) { // 返回公历节假日名称 String sd = solarHoliday[i].split(" ")[0]; // 节假日的日期 String sdv = solarHoliday[i].split(" ")[1]; // 节假日的名称 String smonth_v = month_log + ""; String sday_v = day_log + ""; String smd = ""; if (month_log < 10) { smonth_v = "0" + month_log; } if (day_log < 10) { sday_v = "0" + day_log; } smd = smonth_v + sday_v; if (sd.trim().equals(smd.trim())) { return sdv; } } for (int i = 0; i < lunarHoliday.length; i++) { // 返回农历节假日名称 String ld = lunarHoliday[i].split(" ")[0]; // 节假日的日期 String ldv = lunarHoliday[i].split(" ")[1]; // 节假日的名称 String lmonth_v = month + ""; String lday_v = day + ""; String lmd = ""; if (month < 10) { lmonth_v = "0" + month; } if (day < 10) { lday_v = "0" + day; } lmd = lmonth_v + lday_v; if (ld.trim().equals(lmd.trim())) { return ldv; } } } if (day == 1) return chineseNumber[month - 1] + "月"; else return getChinaDayString(day); } public String toString() { if (chineseNumber[month - 1] == "一" && getChinaDayString(day) == "初一") return "农历" + year + "年"; else if (getChinaDayString(day) == "初一") return chineseNumber[month - 1] + "月"; else return getChinaDayString(day); // return year + "年" + (leap ? "闰" : "") + chineseNumber[month - 1] + // "月" + getChinaDayString(day); } /* * public static void main(String[] args) { System.out.println(new * LunarCalendar().getLunarDate(2012, 1, 23)); } */ public int getLeapMonth() { return leapMonth; } public void setLeapMonth(int leapMonth) { this.leapMonth = leapMonth; } /** * 得到当前日期对应的阴历月份 * * @return */ public String getLunarMonth() { return lunarMonth; } public void setLunarMonth(String lunarMonth) { this.lunarMonth = lunarMonth; } /** * 得到当前年对应的农历年份 * * @return */ public int getYear() { return year; } public void setYear(int year) { this.year = year; } }
这个功能为临时整理的,省略的了查询和显示提醒部分的代码。如果你需要这样的功能,或发现有未提供的代码,可给我留言!
Android仿IOS日历
最新推荐文章于 2022-09-02 23:27:02 发布