/* * Copyright (C) 2012 www.amsoft.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ab.view.app; import java.util.List; import java.util.TimeZone; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Paint.FontMetrics; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.text.format.Time; import android.view.View; // TODO: Auto-generated Javadoc /** * © 2012 amsoft.cn * 名称:AbCalendar.java * 描述:自定义显示日期的view * * @author 还如一梦中 * @version v1.0 * @date:2013-11-7 下午2:35:05 */ public class AbCalendar extends View { /** The m calendar. */ private Time mCalendar; /** The m cale bg. */ private Drawable mCaleBg; /** The m cale dot. */ private Drawable mCaleDot; /** The m pos year. */ private Point mPosYear; /** The d array year. */ private List<Drawable> dArrayYear; /** The m pos month. */ private Point mPosMonth; /** The d array month. */ private List<Drawable> dArrayMonth; /** The m pos date. */ private Point mPosDate; /** The d array date. */ private List<Drawable> dArrayDate; /** The m pos week. */ private Point mPosWeek; /** The d array week. */ private List<Drawable> dArrayWeek; /** The m bg width. */ private int mBgWidth; /** The m bg height. */ private int mBgHeight; /** The m date text size. */ private float mDateTextSize; /** The date changed receiver. */ private final BroadcastReceiver dateChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) { String tz = intent.getStringExtra("time-zone"); mCalendar = new Time(TimeZone.getTimeZone(tz).getID()); } invalidate(); } }; /** The m attached. */ private boolean mAttached; /** * Instantiates a new ab calendar. * * @param context the context * @param caleBg the cale bg * @param caleDot the cale dot * @param posYear the pos year * @param dYearArray the d year array * @param posMonth the pos month * @param dMonthArray the d month array * @param posDate the pos date * @param dDateArray the d date array * @param posWeek the pos week * @param dWeekArray the d week array */ public AbCalendar(Context context, Drawable caleBg, Drawable caleDot, Point posYear, List<Drawable> dYearArray, Point posMonth, List<Drawable> dMonthArray, Point posDate, List<Drawable> dDateArray, Point posWeek, List<Drawable> dWeekArray) { super(context); mCaleBg = caleBg; mCaleDot = caleDot; mPosYear = posYear; dArrayYear = dYearArray; mPosMonth = posMonth; dArrayMonth = dMonthArray; mPosDate = posDate; dArrayDate = dDateArray; mPosWeek = posWeek; dArrayWeek = dWeekArray; mBgWidth = mCaleBg.getIntrinsicWidth(); mBgHeight = mCaleBg.getIntrinsicHeight(); mCalendar = new Time(); mDateTextSize = 14; } /* (non-Javadoc) * @see android.view.View#onAttachedToWindow() */ @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (!mAttached) { mAttached = true; IntentFilter intentFilter = new IntentFilter( Intent.ACTION_DATE_CHANGED); getContext().registerReceiver(dateChangedReceiver, intentFilter); } mCalendar = new Time(); } /* (non-Javadoc) * @see android.view.View#onDetachedFromWindow() */ @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mAttached) { mAttached = false; getContext().unregisterReceiver(dateChangedReceiver); } } /* (non-Javadoc) * @see android.view.View#onMeasure(int, int) */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); float hScale = 1.0f; float vScale = 1.0f; if (widthMode != MeasureSpec.UNSPECIFIED && widthSize < mBgWidth) { hScale = (float) widthSize / (float) mBgWidth; } if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mBgHeight) { vScale = (float) heightSize / (float) mBgHeight; } float scale = Math.min(hScale, vScale); setMeasuredDimension(mBgWidth * (int)scale,mBgHeight * (int)scale); } /* (non-Javadoc) * @see android.view.View#onSizeChanged(int, int, int, int) */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } /* (non-Javadoc) * @see android.view.View#onDraw(android.graphics.Canvas) */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int availableWidth = getRight() - getLeft(); int availableHeight = getBottom() - getTop(); int x = availableWidth / 2; int y = availableHeight / 2; final Drawable bg = mCaleBg; int w = bg.getIntrinsicWidth(); int h = bg.getIntrinsicHeight(); boolean scaled = false; if (availableWidth < w || availableHeight < h) { scaled = true; float scale = Math.min((float) availableWidth / (float) w, (float) availableHeight / (float) h); canvas.save(); canvas.scale(scale, scale, x, y); } bg.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); bg.draw(canvas); canvas.save(); mCalendar.setToNow(); if ((!dArrayYear.isEmpty() && dArrayYear.size() > 0) || (!dArrayMonth.isEmpty() && dArrayMonth.size() > 0) || (!dArrayDate.isEmpty() && dArrayDate.size() > 0) || (!dArrayWeek.isEmpty() && dArrayWeek.size() > 0)) { if (!dArrayYear.isEmpty() && dArrayYear.size() > 0) { String sYear = String.format("%04d", mCalendar.year); int pos = Integer.parseInt(sYear.substring(0, 1)); Drawable dBmpYear = dArrayYear.get(pos); int bmpW = dBmpYear.getIntrinsicWidth(); int bmpH = dBmpYear.getIntrinsicHeight(); dBmpYear.setBounds(x - (w / 2) + mPosYear.x, y - (h / 2) + mPosYear.y, x - (w / 2) + mPosYear.x + bmpW, y - (h / 2) + mPosYear.y + bmpH); dBmpYear.draw(canvas); pos = Integer.parseInt(sYear.substring(1, 2)); dBmpYear = dArrayYear.get(pos); dBmpYear.setBounds(x - (w / 2) + mPosYear.x + bmpW, y - (h / 2) + mPosYear.y, x - (w / 2) + mPosYear.x + 2 * bmpW, y - (h / 2) + mPosYear.y + bmpH); dBmpYear.draw(canvas); pos = Integer.parseInt(sYear.substring(2, 3)); dBmpYear = dArrayYear.get(pos); dBmpYear.setBounds(x - (w / 2) + mPosYear.x + 2 * bmpW, y - (h / 2) + mPosYear.y, x - (w / 2) + mPosYear.x + 3 * bmpW, y - (h / 2) + mPosYear.y + bmpH); dBmpYear.draw(canvas); pos = Integer.parseInt(sYear.substring(3, 4)); dBmpYear = dArrayYear.get(pos); dBmpYear.setBounds(x - (w / 2) + mPosYear.x + 3 * bmpW, y - (h / 2) + mPosYear.y, x - (w / 2) + mPosYear.x + 4 * bmpW, y - (h / 2) + mPosYear.y + bmpH); dBmpYear.draw(canvas); if ((mCaleDot != null) && (mPosYear.y == mPosMonth.y)) { int dotW = mCaleDot.getIntrinsicWidth(); int dotH = mCaleDot.getIntrinsicHeight(); if (dotH < bmpW) { mCaleDot.setBounds(x - (w / 2) + mPosYear.x + 4 * bmpW, y - (h / 2) + mPosYear.y + (bmpH - dotH) / 2, x - (w / 2) + mPosYear.x + 4 * bmpW + dotW, y - (h / 2) + mPosYear.y + (bmpH - dotH) / 2 + dotH); } else { mCaleDot.setBounds(x - (w / 2) + mPosYear.x + 4 * bmpW, y - (h / 2) + mPosYear.y, x - (w / 2) + mPosYear.x + 4 * bmpW + dotW, y - (h / 2) + mPosYear.y + dotH); } mCaleDot.draw(canvas); } } if (!dArrayMonth.isEmpty() && dArrayMonth.size() > 0) { if (dArrayMonth.size() > 10) { Drawable dBmpMonth = dArrayMonth.get(mCalendar.month); int bmpW = dBmpMonth.getIntrinsicWidth(); int bmpH = dBmpMonth.getIntrinsicHeight(); dBmpMonth.setBounds(x - (w / 2) + mPosMonth.x, y - (h / 2) + mPosMonth.y, x - (w / 2) + mPosMonth.x + bmpW, y - (h / 2) + mPosMonth.y + bmpH); dBmpMonth.draw(canvas); } else { String sMonth = String.format("%02d", mCalendar.month + 1); int pos = Integer.parseInt(sMonth.substring(0, 1)); Drawable dBmpMonth = dArrayMonth.get(pos); int bmpW = dBmpMonth.getIntrinsicWidth(); int bmpH = dBmpMonth.getIntrinsicHeight(); dBmpMonth.setBounds(x - (w / 2) + mPosMonth.x, y - (h / 2) + mPosMonth.y, x - (w / 2) + mPosMonth.x + bmpW, y - (h / 2) + mPosMonth.y + bmpH); dBmpMonth.draw(canvas); pos = Integer.parseInt(sMonth.substring(1, 2)); dBmpMonth = dArrayMonth.get(pos); dBmpMonth.setBounds(x - (w / 2) + mPosMonth.x + bmpW, y - (h / 2) + mPosMonth.y, x - (w / 2) + mPosMonth.x + 2 * bmpW, y - (h / 2) + mPosMonth.y + bmpH); dBmpMonth.draw(canvas); if ((mCaleDot != null) && (mPosMonth.y == mPosDate.y)) { int dotW = mCaleDot.getIntrinsicWidth(); int dotH = mCaleDot.getIntrinsicHeight(); if (dotH < bmpW) { mCaleDot.setBounds(x - (w / 2) + mPosMonth.x + 2 * bmpW, y - (h / 2) + mPosMonth.y + (bmpH - dotH) / 2, x - (w / 2) + mPosMonth.x + 2 * bmpW + dotW, y - (h / 2) + mPosMonth.y + (bmpH - dotH) / 2 + dotH); } else { mCaleDot.setBounds(x - (w / 2) + mPosMonth.x + 2 * bmpW, y - (h / 2) + mPosMonth.y, x - (w / 2) + mPosMonth.x + 2 * bmpW + dotW, y - (h / 2) + mPosMonth.y + dotH); } mCaleDot.draw(canvas); } } } if (!dArrayDate.isEmpty() && dArrayDate.size() > 0) { String sDate = String.format("%02d", mCalendar.monthDay); int pos = Integer.parseInt(sDate.substring(0, 1)); Drawable dBmpDate = dArrayDate.get(pos); int bmpW = dBmpDate.getIntrinsicWidth(); int bmpH = dBmpDate.getIntrinsicHeight(); dBmpDate.setBounds(x - (w / 2) + mPosDate.x, y - (h / 2) + mPosDate.y, x - (w / 2) + mPosDate.x + bmpW, y - (h / 2) + mPosDate.y + bmpH); dBmpDate.draw(canvas); pos = Integer.parseInt(sDate.substring(1, 2)); dBmpDate = dArrayDate.get(pos); dBmpDate.setBounds(x - (w / 2) + mPosDate.x + bmpW, y - (h / 2) + mPosDate.y, x - (w / 2) + mPosDate.x + 2 * bmpW, y - (h / 2) + mPosDate.y + bmpH); dBmpDate.draw(canvas); } if (!dArrayWeek.isEmpty() && dArrayWeek.size() > 0) { Drawable dBmpWeek = dArrayWeek.get(mCalendar.weekDay); int bmpW = dBmpWeek.getIntrinsicWidth(); int bmpH = dBmpWeek.getIntrinsicHeight(); dBmpWeek.setBounds(x - (w / 2) + mPosWeek.x, y - (h / 2) + mPosWeek.y, x - (w / 2) + mPosWeek.x + bmpW, y - (h / 2) + mPosWeek.y + bmpH); dBmpWeek.draw(canvas); } } else { Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); String day = String.format("%02d", mCalendar.monthDay); textPaint.setTextAlign(Align.CENTER); textPaint.setTextSize(mDateTextSize); textPaint.setColor(Color.BLACK); int width = getWidth(); int height = getHeight(); FontMetrics fontMetrics = textPaint.getFontMetrics(); float fontHeight = fontMetrics.bottom - fontMetrics.top; float pos_x = width / 2; float pos_y = height - (height - fontHeight) / 2 - fontMetrics.bottom; canvas.drawText(day, pos_x, pos_y, textPaint); } if (scaled) { canvas.restore(); } } /** * Gets the date text size. * * @return the date text size */ public float getDateTextSize() { return mDateTextSize; } /** * Sets the date text size. * * @param dateTextSize the new date text size */ public void setDateTextSize(float dateTextSize) { this.mDateTextSize = dateTextSize; } }