- 浏览: 426093 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
xinzhengjie:
服务器用什么实现
pjsip -
yxhloen01:
只放debug.keystore但是没给密码啊。。。。。。 ...
静默安装实现方法 -
tabolt:
android 应用强制停止 -
li1046964106:
[color=green][size=x-small][ali ...
安卓图表引擎AChartEngine(二) - 示例源码概述和分析 -
smallk2013:
用你这个方法为什么我只想模拟点击 无法实现啊
Android下执行Runtime.getRuntime().exec后返回状态
1.calendar.xml文件
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.jykenan.CalendarWidget
android:id="@+id/calenaract_calendar_widget"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
2.日历view
public class CalendarWidget extends View implements OnTouchListener {
private Context context;
private Paint paint = new Paint();
private RectF borderRect;
private Rect canlendarRect;
private Rect dayCellContextRect;
private CalendarHeader header;
private DayCell[] dayCells = new DayCell[42];
private Calendar calendar = Calendar.getInstance();
private Calendar todayCalendar = Calendar.getInstance();
private DayCell curDayCell;
private int moveX = 0;// X方向上在onScroll中的移动像素
private GestureDetector detector;// 手势运动委托器
private CalendarAction gestureAction;
private OnCalendarSelectedListenter calendarSelectedListenter;
private SimpleDateFormat chineseDateFormat = new SimpleDateFormat(
"yyyy年MM月dd日");
private int lunaryear;
private int lunarmonth;
private int lunarday;
private boolean leap;
private String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
private final 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 };
public CalendarWidget(Context context) {
super(context, null);
}
public CalendarWidget(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
this.context = context;
gestureAction = CalendarAction.CALENDAR_DEFAULT;
setOnTouchListener(this);
detector = new GestureDetector(context, new MyGestureListener());
setLongClickable(true);// 这样才能启动Gesture [dʒestʃə]
header = new CalendarHeader(this.context);
for (int i = 0; i < 42; i++) {
dayCells[i] = new DayCell();
}
setCalendar();
}
private void setCalendar() {
// 先清除状态
for (int i = 0; i < 42; i++) {
dayCells[i].clearState();
}
// 根据日期设置DayCell
// 设置日历是本月1号
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
1);
// 获得本月有多少天
int maxday = calendar.getActualMaximum(Calendar.DATE);
// 第一天是星期几
int dayofweek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
for (int i = dayofweek; i < maxday + dayofweek; i++) {
setLunar(calendar.getTime().getTime());
int day = calendar.get(Calendar.DATE);
dayCells[i].setText("" + day);
if(lunarday==1){
dayCells[i].setLunarText(""+lunarmonth+"月");
}else{
dayCells[i].setLunarText(""+getChinaDayString(lunarday));
}
// 今天 (年月日三者相等 小时毫秒这些不比较)
if (todayCalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR)
&& todayCalendar.get(Calendar.MONTH) == calendar
.get(Calendar.MONTH)
&& todayCalendar.get(Calendar.DATE) == calendar
.get(Calendar.DATE)) {
dayCells[i].setToday(true);
}
// 周六
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
dayCells[i].setFontColor(context.getResources().getColor(
R.color.canlendar_week_6));
}
// 周日
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
dayCells[i].setFontColor(context.getResources().getColor(
R.color.canlendar_week_7));
}
// 设置值
dayCells[i].setYear(calendar.get(Calendar.YEAR));
dayCells[i].setMonth(calendar.get(Calendar.MONTH));
dayCells[i].setDay(calendar.get(Calendar.DATE));
dayCells[i].setLunarYear(lunaryear);
dayCells[i].setLunarMonth(lunarmonth);
dayCells[i].setLunarDay(lunarday);
// +1天,注意运行到最后,就是第二个月的第一天了。
calendar.add(Calendar.DATE, 1);
}
// 最后要重新设置为本月的第一天,这样为了滑动作准备
calendar.add(Calendar.MONTH, -1);
}
private 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];
}
private void setLunar(long currentStamp) {
@SuppressWarnings("unused")
int yearCyl, monCyl, dayCyl;
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.
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 求出和1900年1月31日相差的天数
int offset = (int) ((currentStamp - 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;
}
// 农历年份
lunaryear = iYear;
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(lunaryear);
} else
daysOfMonth = monthDays(lunaryear, 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;
}
lunarmonth = iMonth;
lunarday = offset + 1;
}
// ====== 传回农历 y年的总天数
final private 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 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 int leapMonth(int y) {
return (int) (lunarInfo[y - 1900] & 0xf);
}
// ====== 传回农历 y年m月的总天数
final private int monthDays(int y, int m) {
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
return 29;
else
return 30;
}
@Override
public boolean onTouch(View arg0, MotionEvent e) {
detector.onTouchEvent(e);
if (e.getAction() == MotionEvent.ACTION_UP) {
if (gestureAction == CalendarAction.CALENDAR_RIGHT) {
moveX = 0;
calendar.add(Calendar.MONTH, -1);
setCalendar();
anycInvalidate();
}
if (gestureAction == CalendarAction.CALENDAR_LEFT) {
moveX = 0;
calendar.add(Calendar.MONTH, 1);
setCalendar();
anycInvalidate();
}
if (gestureAction == CalendarAction.CALENDAR_NONE) {
moveX = 0;
setCalendar();
anycInvalidate();
}
// 转发事件
if (gestureAction == CalendarAction.CALENDAR_TOUCH) {
if (calendarSelectedListenter != null) {
calendarSelectedListenter.onSelected(curDayCell.getYear(),
curDayCell.getMonth(), curDayCell.getDay());
}
}
gestureAction = CalendarAction.CALENDAR_DEFAULT;// 清除状态
}
return false;
}
private void anycInvalidate() {
new Thread(new Runnable() {
@Override
public void run() {
postInvalidate();
}
}).start();
}
@Override
public void onDraw(Canvas canvas) {
compute();
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
| Paint.FILTER_BITMAP_FLAG));
drawBackGround(canvas);
// drawBorder(canvas);
drawTitle(canvas);
header.drawWeekHeader(canvas, canlendarRect);
drawDayCells(canvas);
}
private void drawDayCells(Canvas canvas) {
for (DayCell cell : dayCells) {
cell.drawDay(canvas);
}
}
private void drawBackGround(Canvas canvas){
Bitmap bmp = ((BitmapDrawable)getResources ().getDrawable( R.drawable.summer)).getBitmap( ) ;
Bitmap newbmp=Bitmap.createScaledBitmap(bmp,getWidth(),getHeight(),true);
canvas.drawBitmap( newbmp, 0, 0, null ) ;
}
private void drawBorder(Canvas canvas) {
paint.setColor(context.getResources()
.getColor(R.color.canlendar_border));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawRoundRect(borderRect, 10, 10, paint);
}
private void compute() {
// Stroke宽度为3,留白1,这样就空4出来
borderRect = new RectF(4, 4, getWidth() - 4, getHeight() - 4);
canlendarRect = new Rect(moveX + 14, 35, getWidth() + moveX - 14,
getHeight() - 14);
header.setHeaderRect(canlendarRect);
dayCellContextRect = header.computeDayCellRect();
// 计算每个Cell的高和宽
int cellWidth = dayCellContextRect.width() / 7;
int cellHeight = dayCellContextRect.height() / 6;// 最多6行
int startX = dayCellContextRect.left;
int startY = dayCellContextRect.top;
int colIndex = 1;
for (int i = 0; i < 42; i++) {
Rect rect = new Rect(startX, startY, startX + cellWidth, startY
+ cellHeight);
// 7个一行
if (colIndex % 7 != 0) {
startX = startX + cellWidth;
}
// 换行,Y下移一个cell的高度,X回到起点
else {
startX = dayCellContextRect.left;
startY = startY + cellHeight;
}
colIndex++;
DayCell dayCell = dayCells[i];
dayCell.setRect(rect);
}
}
private void drawTitle(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(15);
paint.setFakeBoldText(true);// 伪粗体,中文使用
paint.setTextAlign(Align.CENTER);
paint.setColor(context.getResources()
.getColor(R.color.canlendar_header));
int month = calendar.get(Calendar.MONTH) + 1;
canvas.drawText(calendar.get(Calendar.YEAR) + "年" + month + "月",
canlendarRect.left + canlendarRect.width()/2,
canlendarRect.top - 4, paint);
}
class MyGestureListener extends SimpleOnGestureListener {
// 用户按下触摸屏,尚未松开或拖动,由一个MotionEvent.ACTION_DOWN触发.
// 注意和onDown的区别,强调的是没有松开或者拖动的状态
@Override
public void onShowPress(MotionEvent arg0) {
super.onShowPress(arg0);
}
// 用户按下触摸屏,由一个MotionEvent.ACTION_DOWN触发
@Override
public boolean onDown(MotionEvent e) {
// 只增加背景,不触发处理
for (final DayCell cell : dayCells) {
if (cell.isClicked((int) e.getX(), (int) e.getY())
&& cell.getText() != null) {
if (curDayCell != null) {
curDayCell.setSelected(false);
// 更新局部,提高性能
CalendarWidget.this.invalidate(
curDayCell.getRect().left,
curDayCell.getRect().top,
curDayCell.getRect().right,
curDayCell.getRect().bottom);
}
cell.setSelected(true);
CalendarWidget.this.invalidate(cell.getRect().left,
cell.getRect().top, cell.getRect().right,
cell.getRect().bottom);
curDayCell = cell;
gestureAction = CalendarAction.CALENDAR_TOUCH;
}
}
return false;
}
// 用户(用户按下触摸屏后)松开,由MotionEvent.ACTION_UP触发
// 如果在onDown和onFling之中2选1,那么使用这个事件是可以区分的
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
return false;
}
// 长按 多个ACTION_DOWN触发
@Override
public void onLongPress(MotionEvent arg0) {
super.onLongPress(arg0);
}
// 用户按下触摸屏,快速移动后松开,由一个MotionEvent.ACTION_DOWN,多个ACTION_MOVE,一个ACTION_UP触发.
// velocityX和velocityY分别表示在X和Y方向上移动的速度
// e1 第一个Down,e2最后一个move
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Toast.makeText(context, "飞行了", Toast.LENGTH_SHORT).show();
// 向左,速度每秒>200个像素
if ((e1.getX() - e2.getX() > getWidth() / 2)
&& (Math.abs(velocityX)) > 200) {
gestureAction = CalendarAction.CALENDAR_LEFT;
}
// 向右,速度每秒>200个像素
else if ((e2.getX() - e1.getX() > getWidth() / 2)
&& (Math.abs(velocityX)) > 200) {
gestureAction = CalendarAction.CALENDAR_RIGHT;
}
return false;
}
// 按下屏幕,并拖动,一个DOWM,多个MOVE触发
// e1 第一个Down,e2当前移动的point
// distance表示Scroll过程中的移动的像素。distanceX >0 表示向左,distanceY >0
// 表示向上,两个都大就是左上
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
moveX -= distanceX;
new Thread(new Runnable() {
@Override
public void run() {
CalendarWidget.this.postInvalidate();
}
}).start();
// 向右
if (e2.getX() - e1.getX() > getWidth() / 2) {
gestureAction = CalendarAction.CALENDAR_RIGHT;
}
// 向左
else if (e1.getX() - e2.getX() > getWidth() / 2) {
gestureAction = CalendarAction.CALENDAR_LEFT;
} else {
gestureAction = CalendarAction.CALENDAR_NONE;
}
return false;
}
}
public void setCalendarSelectedListenter(
OnCalendarSelectedListenter calendarSelectedListenter) {
this.calendarSelectedListenter = calendarSelectedListenter;
}
}
enum CalendarAction {
CALENDAR_DEFAULT, CALENDAR_NONE, CALENDAR_TOUCH, CALENDAR_LEFT, CALENDAR_RIGHT,
}
3.日历标题
public class CalendarHeader
{
private Context context;
private Rect headerRect;
private static final String[] week = new String[]{"日","一","二","三","四","五","六"};
public Rect getHeaderRect() {
return headerRect;
}
public void setHeaderRect(Rect headerRect) {
this.headerRect = headerRect;
}
public CalendarHeader(Context context)
{
this.context = context;
}
public void drawWeekHeader(Canvas canvas,Rect canlendarRect)
{
int cellWidth = canlendarRect.width()/7;
Paint paint = new Paint();
//这里可以实现移动 ,以后需要提取
int start = canlendarRect.left;
paint.setTextAlign(Align.CENTER);
paint.setTextSize(15);
for(int i=0;i<7;i++)
{
paint.setColor(Color.BLACK);
if(week[i].equals("六"))
{
paint.setColor(context.getResources().getColor(R.color.canlendar_week_6));
}
if(week[i].equals("日"))
{
paint.setColor(context.getResources().getColor(R.color.canlendar_week_7));
}
canvas.drawText(week[i], start+cellWidth/2, canlendarRect.top+20, paint);
start+=cellWidth;
}
}
public Rect computeDayCellRect()
{
return new Rect(headerRect.left,headerRect.top+40,headerRect.right,headerRect.bottom);
}
}
4.填写每天的内容
class DayCell
{
private Rect rect;
private String text;
private String lunarText;
private boolean selected;
private int fontColor = Color.BLACK;
private int year;
private int month;
private int day;
private int lunarYear;
private int lunarMonth;
private int lunarDay;
private boolean today;
public boolean isClicked(int mouseX,int mouseY)
{
if(rect.contains(mouseX, mouseY))
{
return true;
}
return false;
}
public void drawDay(Canvas canvas)
{
Paint paint = new Paint();
//选中状态,增加背景色
if(selected && !today)
{
Shader bgShader = new LinearGradient(rect.left, rect.top, rect.right, rect.bottom, Color.parseColor("#43682f"), Color.parseColor("#5cc35c"), Shader.TileMode.MIRROR);
paint.setShader(bgShader);
canvas.drawRoundRect(new RectF(rect), 3, 3, paint);
}
//是今天,增加背景标识
if(today)
{
Shader bgShader = new LinearGradient(rect.left, rect.top, rect.right, rect.bottom, Color.parseColor("#ff8200"), Color.parseColor("#ffcea8"), Shader.TileMode.MIRROR);
paint.setShader(bgShader);
canvas.drawRoundRect(new RectF(rect), 3, 3, paint);
}
paint.setShader(null);
paint.setColor(fontColor);
paint.setTextAlign(Align.CENTER);
//rect的开始+宽度/2,这样得到rect的X中点坐标
//计算字体高度,计算出居中的定位
FontMetrics fm = paint.getFontMetrics();
int fontHeight = (int) Math.ceil(fm.descent - fm.top)-6;
if(text != null)
{
canvas.drawText(text, rect.left+rect.width()/2, rect.bottom-(rect.height()-fontHeight)/2-7, paint);
canvas.drawText(lunarText, rect.left+rect.width()/2, rect.bottom-(rect.height()-fontHeight)/4, paint);
}
}
public void clearState()
{
setText(null);
setSelected(false);
setDay(0);
setMonth(0);
setYear(0);
setLunarText(null);
setLunarYear(0);
setLunarMonth(0);
setLunarDay(0);
setToday(false);
}
public Rect getRect() {
return rect;
}
public void setRect(Rect rect) {
this.rect = rect;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getLunarText() {
return lunarText;
}
public void setLunarText(String lunarText) {
this.lunarText = lunarText;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getLunarYear(){
return lunarYear;
}
public void setLunarYear(int lunarYear){
this.lunarYear=lunarYear;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getLunarMonth() {
return lunarMonth;
}
public void setLunarMonth(int lunarmonth) {
this.lunarMonth = lunarmonth;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getLunarDay() {
return lunarDay;
}
public void setLunarDay(int lunarday) {
this.lunarDay = lunarday;
}
public int getFontColor() {
return fontColor;
}
public void setFontColor(int fontColor) {
this.fontColor = fontColor;
}
public boolean isToday()
{
return today;
}
public void setToday(boolean today)
{
this.today = today;
}
}
(4)接口实现
public interface OnCalendarSelectedListenter
{
public void onSelected(int year,int month,int day);
}
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.jykenan.CalendarWidget
android:id="@+id/calenaract_calendar_widget"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
2.日历view
public class CalendarWidget extends View implements OnTouchListener {
private Context context;
private Paint paint = new Paint();
private RectF borderRect;
private Rect canlendarRect;
private Rect dayCellContextRect;
private CalendarHeader header;
private DayCell[] dayCells = new DayCell[42];
private Calendar calendar = Calendar.getInstance();
private Calendar todayCalendar = Calendar.getInstance();
private DayCell curDayCell;
private int moveX = 0;// X方向上在onScroll中的移动像素
private GestureDetector detector;// 手势运动委托器
private CalendarAction gestureAction;
private OnCalendarSelectedListenter calendarSelectedListenter;
private SimpleDateFormat chineseDateFormat = new SimpleDateFormat(
"yyyy年MM月dd日");
private int lunaryear;
private int lunarmonth;
private int lunarday;
private boolean leap;
private String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
private final 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 };
public CalendarWidget(Context context) {
super(context, null);
}
public CalendarWidget(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
this.context = context;
gestureAction = CalendarAction.CALENDAR_DEFAULT;
setOnTouchListener(this);
detector = new GestureDetector(context, new MyGestureListener());
setLongClickable(true);// 这样才能启动Gesture [dʒestʃə]
header = new CalendarHeader(this.context);
for (int i = 0; i < 42; i++) {
dayCells[i] = new DayCell();
}
setCalendar();
}
private void setCalendar() {
// 先清除状态
for (int i = 0; i < 42; i++) {
dayCells[i].clearState();
}
// 根据日期设置DayCell
// 设置日历是本月1号
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
1);
// 获得本月有多少天
int maxday = calendar.getActualMaximum(Calendar.DATE);
// 第一天是星期几
int dayofweek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
for (int i = dayofweek; i < maxday + dayofweek; i++) {
setLunar(calendar.getTime().getTime());
int day = calendar.get(Calendar.DATE);
dayCells[i].setText("" + day);
if(lunarday==1){
dayCells[i].setLunarText(""+lunarmonth+"月");
}else{
dayCells[i].setLunarText(""+getChinaDayString(lunarday));
}
// 今天 (年月日三者相等 小时毫秒这些不比较)
if (todayCalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR)
&& todayCalendar.get(Calendar.MONTH) == calendar
.get(Calendar.MONTH)
&& todayCalendar.get(Calendar.DATE) == calendar
.get(Calendar.DATE)) {
dayCells[i].setToday(true);
}
// 周六
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
dayCells[i].setFontColor(context.getResources().getColor(
R.color.canlendar_week_6));
}
// 周日
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
dayCells[i].setFontColor(context.getResources().getColor(
R.color.canlendar_week_7));
}
// 设置值
dayCells[i].setYear(calendar.get(Calendar.YEAR));
dayCells[i].setMonth(calendar.get(Calendar.MONTH));
dayCells[i].setDay(calendar.get(Calendar.DATE));
dayCells[i].setLunarYear(lunaryear);
dayCells[i].setLunarMonth(lunarmonth);
dayCells[i].setLunarDay(lunarday);
// +1天,注意运行到最后,就是第二个月的第一天了。
calendar.add(Calendar.DATE, 1);
}
// 最后要重新设置为本月的第一天,这样为了滑动作准备
calendar.add(Calendar.MONTH, -1);
}
private 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];
}
private void setLunar(long currentStamp) {
@SuppressWarnings("unused")
int yearCyl, monCyl, dayCyl;
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.
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 求出和1900年1月31日相差的天数
int offset = (int) ((currentStamp - 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;
}
// 农历年份
lunaryear = iYear;
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(lunaryear);
} else
daysOfMonth = monthDays(lunaryear, 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;
}
lunarmonth = iMonth;
lunarday = offset + 1;
}
// ====== 传回农历 y年的总天数
final private 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 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 int leapMonth(int y) {
return (int) (lunarInfo[y - 1900] & 0xf);
}
// ====== 传回农历 y年m月的总天数
final private int monthDays(int y, int m) {
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
return 29;
else
return 30;
}
@Override
public boolean onTouch(View arg0, MotionEvent e) {
detector.onTouchEvent(e);
if (e.getAction() == MotionEvent.ACTION_UP) {
if (gestureAction == CalendarAction.CALENDAR_RIGHT) {
moveX = 0;
calendar.add(Calendar.MONTH, -1);
setCalendar();
anycInvalidate();
}
if (gestureAction == CalendarAction.CALENDAR_LEFT) {
moveX = 0;
calendar.add(Calendar.MONTH, 1);
setCalendar();
anycInvalidate();
}
if (gestureAction == CalendarAction.CALENDAR_NONE) {
moveX = 0;
setCalendar();
anycInvalidate();
}
// 转发事件
if (gestureAction == CalendarAction.CALENDAR_TOUCH) {
if (calendarSelectedListenter != null) {
calendarSelectedListenter.onSelected(curDayCell.getYear(),
curDayCell.getMonth(), curDayCell.getDay());
}
}
gestureAction = CalendarAction.CALENDAR_DEFAULT;// 清除状态
}
return false;
}
private void anycInvalidate() {
new Thread(new Runnable() {
@Override
public void run() {
postInvalidate();
}
}).start();
}
@Override
public void onDraw(Canvas canvas) {
compute();
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
| Paint.FILTER_BITMAP_FLAG));
drawBackGround(canvas);
// drawBorder(canvas);
drawTitle(canvas);
header.drawWeekHeader(canvas, canlendarRect);
drawDayCells(canvas);
}
private void drawDayCells(Canvas canvas) {
for (DayCell cell : dayCells) {
cell.drawDay(canvas);
}
}
private void drawBackGround(Canvas canvas){
Bitmap bmp = ((BitmapDrawable)getResources ().getDrawable( R.drawable.summer)).getBitmap( ) ;
Bitmap newbmp=Bitmap.createScaledBitmap(bmp,getWidth(),getHeight(),true);
canvas.drawBitmap( newbmp, 0, 0, null ) ;
}
private void drawBorder(Canvas canvas) {
paint.setColor(context.getResources()
.getColor(R.color.canlendar_border));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawRoundRect(borderRect, 10, 10, paint);
}
private void compute() {
// Stroke宽度为3,留白1,这样就空4出来
borderRect = new RectF(4, 4, getWidth() - 4, getHeight() - 4);
canlendarRect = new Rect(moveX + 14, 35, getWidth() + moveX - 14,
getHeight() - 14);
header.setHeaderRect(canlendarRect);
dayCellContextRect = header.computeDayCellRect();
// 计算每个Cell的高和宽
int cellWidth = dayCellContextRect.width() / 7;
int cellHeight = dayCellContextRect.height() / 6;// 最多6行
int startX = dayCellContextRect.left;
int startY = dayCellContextRect.top;
int colIndex = 1;
for (int i = 0; i < 42; i++) {
Rect rect = new Rect(startX, startY, startX + cellWidth, startY
+ cellHeight);
// 7个一行
if (colIndex % 7 != 0) {
startX = startX + cellWidth;
}
// 换行,Y下移一个cell的高度,X回到起点
else {
startX = dayCellContextRect.left;
startY = startY + cellHeight;
}
colIndex++;
DayCell dayCell = dayCells[i];
dayCell.setRect(rect);
}
}
private void drawTitle(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(15);
paint.setFakeBoldText(true);// 伪粗体,中文使用
paint.setTextAlign(Align.CENTER);
paint.setColor(context.getResources()
.getColor(R.color.canlendar_header));
int month = calendar.get(Calendar.MONTH) + 1;
canvas.drawText(calendar.get(Calendar.YEAR) + "年" + month + "月",
canlendarRect.left + canlendarRect.width()/2,
canlendarRect.top - 4, paint);
}
class MyGestureListener extends SimpleOnGestureListener {
// 用户按下触摸屏,尚未松开或拖动,由一个MotionEvent.ACTION_DOWN触发.
// 注意和onDown的区别,强调的是没有松开或者拖动的状态
@Override
public void onShowPress(MotionEvent arg0) {
super.onShowPress(arg0);
}
// 用户按下触摸屏,由一个MotionEvent.ACTION_DOWN触发
@Override
public boolean onDown(MotionEvent e) {
// 只增加背景,不触发处理
for (final DayCell cell : dayCells) {
if (cell.isClicked((int) e.getX(), (int) e.getY())
&& cell.getText() != null) {
if (curDayCell != null) {
curDayCell.setSelected(false);
// 更新局部,提高性能
CalendarWidget.this.invalidate(
curDayCell.getRect().left,
curDayCell.getRect().top,
curDayCell.getRect().right,
curDayCell.getRect().bottom);
}
cell.setSelected(true);
CalendarWidget.this.invalidate(cell.getRect().left,
cell.getRect().top, cell.getRect().right,
cell.getRect().bottom);
curDayCell = cell;
gestureAction = CalendarAction.CALENDAR_TOUCH;
}
}
return false;
}
// 用户(用户按下触摸屏后)松开,由MotionEvent.ACTION_UP触发
// 如果在onDown和onFling之中2选1,那么使用这个事件是可以区分的
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
return false;
}
// 长按 多个ACTION_DOWN触发
@Override
public void onLongPress(MotionEvent arg0) {
super.onLongPress(arg0);
}
// 用户按下触摸屏,快速移动后松开,由一个MotionEvent.ACTION_DOWN,多个ACTION_MOVE,一个ACTION_UP触发.
// velocityX和velocityY分别表示在X和Y方向上移动的速度
// e1 第一个Down,e2最后一个move
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Toast.makeText(context, "飞行了", Toast.LENGTH_SHORT).show();
// 向左,速度每秒>200个像素
if ((e1.getX() - e2.getX() > getWidth() / 2)
&& (Math.abs(velocityX)) > 200) {
gestureAction = CalendarAction.CALENDAR_LEFT;
}
// 向右,速度每秒>200个像素
else if ((e2.getX() - e1.getX() > getWidth() / 2)
&& (Math.abs(velocityX)) > 200) {
gestureAction = CalendarAction.CALENDAR_RIGHT;
}
return false;
}
// 按下屏幕,并拖动,一个DOWM,多个MOVE触发
// e1 第一个Down,e2当前移动的point
// distance表示Scroll过程中的移动的像素。distanceX >0 表示向左,distanceY >0
// 表示向上,两个都大就是左上
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
moveX -= distanceX;
new Thread(new Runnable() {
@Override
public void run() {
CalendarWidget.this.postInvalidate();
}
}).start();
// 向右
if (e2.getX() - e1.getX() > getWidth() / 2) {
gestureAction = CalendarAction.CALENDAR_RIGHT;
}
// 向左
else if (e1.getX() - e2.getX() > getWidth() / 2) {
gestureAction = CalendarAction.CALENDAR_LEFT;
} else {
gestureAction = CalendarAction.CALENDAR_NONE;
}
return false;
}
}
public void setCalendarSelectedListenter(
OnCalendarSelectedListenter calendarSelectedListenter) {
this.calendarSelectedListenter = calendarSelectedListenter;
}
}
enum CalendarAction {
CALENDAR_DEFAULT, CALENDAR_NONE, CALENDAR_TOUCH, CALENDAR_LEFT, CALENDAR_RIGHT,
}
3.日历标题
public class CalendarHeader
{
private Context context;
private Rect headerRect;
private static final String[] week = new String[]{"日","一","二","三","四","五","六"};
public Rect getHeaderRect() {
return headerRect;
}
public void setHeaderRect(Rect headerRect) {
this.headerRect = headerRect;
}
public CalendarHeader(Context context)
{
this.context = context;
}
public void drawWeekHeader(Canvas canvas,Rect canlendarRect)
{
int cellWidth = canlendarRect.width()/7;
Paint paint = new Paint();
//这里可以实现移动 ,以后需要提取
int start = canlendarRect.left;
paint.setTextAlign(Align.CENTER);
paint.setTextSize(15);
for(int i=0;i<7;i++)
{
paint.setColor(Color.BLACK);
if(week[i].equals("六"))
{
paint.setColor(context.getResources().getColor(R.color.canlendar_week_6));
}
if(week[i].equals("日"))
{
paint.setColor(context.getResources().getColor(R.color.canlendar_week_7));
}
canvas.drawText(week[i], start+cellWidth/2, canlendarRect.top+20, paint);
start+=cellWidth;
}
}
public Rect computeDayCellRect()
{
return new Rect(headerRect.left,headerRect.top+40,headerRect.right,headerRect.bottom);
}
}
4.填写每天的内容
class DayCell
{
private Rect rect;
private String text;
private String lunarText;
private boolean selected;
private int fontColor = Color.BLACK;
private int year;
private int month;
private int day;
private int lunarYear;
private int lunarMonth;
private int lunarDay;
private boolean today;
public boolean isClicked(int mouseX,int mouseY)
{
if(rect.contains(mouseX, mouseY))
{
return true;
}
return false;
}
public void drawDay(Canvas canvas)
{
Paint paint = new Paint();
//选中状态,增加背景色
if(selected && !today)
{
Shader bgShader = new LinearGradient(rect.left, rect.top, rect.right, rect.bottom, Color.parseColor("#43682f"), Color.parseColor("#5cc35c"), Shader.TileMode.MIRROR);
paint.setShader(bgShader);
canvas.drawRoundRect(new RectF(rect), 3, 3, paint);
}
//是今天,增加背景标识
if(today)
{
Shader bgShader = new LinearGradient(rect.left, rect.top, rect.right, rect.bottom, Color.parseColor("#ff8200"), Color.parseColor("#ffcea8"), Shader.TileMode.MIRROR);
paint.setShader(bgShader);
canvas.drawRoundRect(new RectF(rect), 3, 3, paint);
}
paint.setShader(null);
paint.setColor(fontColor);
paint.setTextAlign(Align.CENTER);
//rect的开始+宽度/2,这样得到rect的X中点坐标
//计算字体高度,计算出居中的定位
FontMetrics fm = paint.getFontMetrics();
int fontHeight = (int) Math.ceil(fm.descent - fm.top)-6;
if(text != null)
{
canvas.drawText(text, rect.left+rect.width()/2, rect.bottom-(rect.height()-fontHeight)/2-7, paint);
canvas.drawText(lunarText, rect.left+rect.width()/2, rect.bottom-(rect.height()-fontHeight)/4, paint);
}
}
public void clearState()
{
setText(null);
setSelected(false);
setDay(0);
setMonth(0);
setYear(0);
setLunarText(null);
setLunarYear(0);
setLunarMonth(0);
setLunarDay(0);
setToday(false);
}
public Rect getRect() {
return rect;
}
public void setRect(Rect rect) {
this.rect = rect;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getLunarText() {
return lunarText;
}
public void setLunarText(String lunarText) {
this.lunarText = lunarText;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getLunarYear(){
return lunarYear;
}
public void setLunarYear(int lunarYear){
this.lunarYear=lunarYear;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getLunarMonth() {
return lunarMonth;
}
public void setLunarMonth(int lunarmonth) {
this.lunarMonth = lunarmonth;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getLunarDay() {
return lunarDay;
}
public void setLunarDay(int lunarday) {
this.lunarDay = lunarday;
}
public int getFontColor() {
return fontColor;
}
public void setFontColor(int fontColor) {
this.fontColor = fontColor;
}
public boolean isToday()
{
return today;
}
public void setToday(boolean today)
{
this.today = today;
}
}
(4)接口实现
public interface OnCalendarSelectedListenter
{
public void onSelected(int year,int month,int day);
}
相关推荐
【标题】:“仿百度日历,横向日历” 在IT领域,日历组件是许多应用程序不可或缺的部分,尤其在管理时间、计划任务或者查看日期事件时。"仿百度日历,横向日历"是一个专为满足这些需求而设计的开发项目。它的主要...
详细请参考驴妈妈 酒店和门票的价格日历。 index.html 入口文件 data.php 包含一个价格日历生成类和 一些实例 product.php ajax产品的json格式 style 样式和js文件 说明: 此程序中js是驴妈妈上的,我做了些修改,...
本压缩包文件"calendaar.rar"包含了一个名为"calendaar.vi"的LabVIEW虚拟仪器(VI)程序,该程序是一个日历应用程序,能够帮助用户便捷地查看和设置日期。 在LabVIEW中,一个VI由前面板和程序框图两部分组成。前...
在IT领域,日历插件是网页开发中常见的组件,用于展示日期并提供与日期相关的交互功能。"百度日历JS版本"是一个基于JavaScript实现的日历控件,它旨在为用户提供与百度官方日历相似的视觉体验和功能。在这个项目中,...
在Delphi编程环境中,日历控件是一种常用的组件,用于展示日期并允许用户进行交互。在本案例中,我们关注的是一个特别的日历控件,它以横向的方式显示日期,同时支持单击和双击事件。这个控件的实现可能涉及到自定义...
【日历+签到(日历签到html)】是一个基于HTML和JavaScript的实用插件,主要用于实现用户在网页上的签到功能。这个插件设计精巧,允许用户自定义已签到的日期,同时也支持签到行为的个性化设置,为网站或应用增加了...
标题中的“桌面显示Outlook日历”指的是在个人电脑的桌面上设置Outlook日历的实时显示功能,以便用户能够方便地查看和管理他们的日程安排。Outlook是一款由Microsoft开发的电子邮件、日历和任务管理应用,它提供了...
在IT行业中,日历和日历待办事项是常见的功能模块,尤其在移动端应用中,它们为用户提供了方便的时间管理和任务规划。在这个场景下,我们主要关注的是如何使用JavaScript(js)、Vue.js框架来构建一个移动端的日历及...
在JavaScript中,创建一个日历控件主要涉及到DOM操作、事件处理和一些基本的CSS样式设计。下面我们将详细探讨这些知识点: 1. **DOM操作**:HTML文档对象模型(DOM)是HTML和XML文档的编程接口。在JavaScript中,...
本主题涉及的是一个利用VBA创建的简单日历窗体,它可以帮助用户更直观地选择日期,并能与Excel表格数据进行交互。这个日历窗体特别适合于那些需要频繁输入或管理日期信息的工作表。 首先,让我们详细了解一下VBA...
【标题】"带标记的简易日历"是一个项目,它可能是一个日历应用或库的示例,旨在提供一种简洁的方式展示日期,并且允许用户在特定日期上添加标记。这样的功能常见于各种日程管理软件,帮助用户追踪重要的事件、纪念日...
在Android开发领域,创建一个与华为日历高度相似的功能是一个挑战性的任务,涉及到对系统日历API的理解、自定义视图的设计以及用户交互的优化。本项目提供的源码旨在实现一个具备显示二十四节气和特殊节假日功能的...
在IT行业中,日历和时间轴是常见的用户界面元素,尤其在日程管理、事件规划和数据可视化等应用中扮演着重要角色。日历通常用于显示日期,而时间轴则提供了一个直观的方式来组织和呈现时间相关的事件或数据。让我们...
JavaScript弹出式日历是一种常见的前端交互功能,它允许用户在网页上方便地选择日期,而无需离开当前页面。这种日历通常以对话框或浮动窗口的形式出现,点击后会在输入框旁边显示一个包含日期的选择界面。用户选择...
在Unity游戏开发中,日历插件是一种非常实用的工具,尤其对于那些需要涉及时间管理、事件安排或者模拟现实世界时间的游戏来说。本篇将详细探讨Unity中的日历插件,包括其功能、应用场景以及如何在项目中集成和使用。...
本主题聚焦于"Axure日历元件库",它为设计者提供了一系列预置的日历和时间选择器组件,帮助快速构建交互式原型。 首先,我们来详细了解"Axure时间选择器"。时间选择器是用户界面中常见的元素,用于让用户方便地选取...
在本场景中,我们关注的是“Qt自定义Calendar日历控件”。这涉及到使用Qt库中的QCalendarWidget或者完全从头构建一个自定义的日历组件。通过自定义,我们可以更好地控制日历的显示、交互和样式,以适应应用程序的...
在iOS开发中,Objective-C(OC)是主要的编程语言之一,用于构建各种应用程序,包括与日历功能相关的应用。本篇文章将详细讲解如何在OC中实现一个“火车日历”功能,参考自...
在Android开发中,实现一个横向滑动的日历视图是一个常见的需求,特别是在设计用户界面时,需要简洁且直观地展示日期。"Android横向滑动日历"是一个这样的示例项目,它专注于创建一个只显示一行日历的轻量级组件。...
《人生日历:日常生活的小助手》 在数字化时代,日历应用已经成为我们日常生活不可或缺的一部分,它们帮助我们规划时间,管理日常事务。今天我们要探讨的是“人生日历4.0”,这款应用以其独特的设计理念和全面的...