轉載請注明出處:http://blog.csdn.net/ym4189/article/details/77008361
1.概述
前段時間項目需要一個月曆提醒,需求是:可以左右無限滑動,可點選監聽,根據事件日期在視圖中描出,右上角顯示事件個數。
在網上搜了很多,但是不是很滿足項目特定的需求,是以在網上的例子的基礎上自定義了一個,供大家參考。
2.先上圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiQ3chVEa0V3bT9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwVNnRVTwAzVlZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DO2QTMyMDMwEDMxgDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
這裡日期是自己畫的,沒有使用GridView,使用自定義view更友善。
我們通過計算每個月的日期,然後根據計算出來的位置繪制我們的日期。這裡使用标準的6*7方格圖。
我會把注釋放在代碼裡,直接上代碼:
1.CalendarView
package com.example.calendar;
import java.util.List;
import com.example.calendar.DateInfo;
import com.example.calendar.DateUtil;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public class CalendarView extends View {
private static final String TAG = "CalendarView";
/**
* 列
*/
private static final int TOTAL_COL = ;
/**
* 行
*/
private static final int TOTAL_ROW = ;
private Paint BlueBgPaint, HuiseBgPaint, mCirclePaint, linePaint;
private Paint mTextPaint, mCutTextPaint;
private int mViewWidth;//控件寬度
private int mViewHight;//控件高度
private float mCellSpace, mCellwide;//方格的寬和高
private Row rows[] = new Row[TOTAL_ROW];//行數組
private static DateInfo mShowDate;// 自定義的單元格資訊 包括year month day
private CallBack mCallBack;// 回調
private int touchSlop;
private float radius;//提醒圓的半徑
private Cell mClickCell = null;//點選的單元格
private float mDownX;
private float mDownY;
private boolean callBackCellSpace = false;
String[] str = { "日", "一", "二", "三", "四", "五", "六" };
public interface CallBack {
void clickDate(RepayPlanInfo date);// 回調點選的日期
void onMesureCellHeight(float mCellSpace, float mCellwide);/// 回調cell的高度确定slidingDrawer高度
void changeDate(DateInfo date);// 回調滑動viewPager改變的日期
}
public CalendarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public CalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CalendarView(Context context) {
super(context);
init(context);
}
public CalendarView(Context context, CallBack mCallBack) {
super(context);
// CalendarView.style = style;
this.mCallBack = mCallBack;
init(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫頂部的星期
drawWeek(canvas);
//畫日期單元格
for (int i = ; i < TOTAL_ROW; i++) {
if (rows[i] != null)
rows[i].drawCells(canvas);
}
}
private void drawWeek(Canvas canvas) {
for (int i = ; i < TOTAL_COL; i++) {
if (i == ) {
mTextPaint.setColor(Color.parseColor("#b1b1b1"));
} else {
mTextPaint.setColor(Color.parseColor("#80000000"));
}
canvas.drawText(str[i], (float) ((i + ) * mCellSpace - mTextPaint.measureText(str[i]) / ),
(float) ( * mCellwide + mTextPaint.measureText(str[i]) / ), mTextPaint);
}
canvas.drawLine(, mCellwide, mViewWidth, mCellwide, linePaint);
}
//初始化畫筆
private void init(Context context) {
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCutTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setTextSize(f);
linePaint.setColor();
BlueBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
BlueBgPaint.setStyle(Paint.Style.FILL);
BlueBgPaint.setColor(Color.parseColor("#3693fd"));
HuiseBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
HuiseBgPaint.setStyle(Paint.Style.FILL);
HuiseBgPaint.setColor(Color.parseColor("#e9e9e9"));
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setStyle(Paint.Style.FILL);
mCirclePaint.setColor(Color.parseColor("#fa4548"));
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
initDate();
}
private void initDate() {
mShowDate = new DateInfo();
//填充日期的資料
fillDate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mViewWidth = w;
mViewHight = h;
mCellSpace = mViewWidth / TOTAL_COL;
radius = mCellSpace / ;//紅色圓圈的半徑,這裡根據單元格寬度确定
//要在第一行頂部留下畫圓的高度,是以這裡減去半徑
mCellwide = (mViewHight - radius) / ;
if (!callBackCellSpace) {
mCallBack.onMesureCellHeight(mCellSpace, mCellwide);
callBackCellSpace = true;
}
mTextPaint.setTextSize(mCellSpace / );
mCutTextPaint.setTextSize(mCellSpace / );
mCutTextPaint.setColor(Color.parseColor("#fffffe"));
}
/*
*
* 觸摸事件為了确定點選的位置日期
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = event.getX();
mDownY = event.getY();
break;
case MotionEvent.ACTION_UP:
float disX = event.getX() - mDownX;
float disY = event.getY() - mDownY;
if (Math.abs(disX) < touchSlop && Math.abs(disY) < touchSlop && event.getY() > mCellwide) {
int col = (int) (mDownX / mCellSpace);
int row = (int) ((mDownY - mCellwide) / mCellwide);
measureClickCell(col, row);
}
break;
}
return true;
}
/**
* 計算繪制點選的單元格
* @param col
* @param row
*/
private void measureClickCell(int col, int row) {
if (col >= TOTAL_COL || row >= TOTAL_ROW)
return;
if (mClickCell != null) {
rows[mClickCell.j].cells[mClickCell.i] = mClickCell;
}
if (rows[row] != null) {
mClickCell = new Cell(rows[row].cells[col].date, rows[row].cells[col].state, rows[row].cells[col].i,
rows[row].cells[col].j);
rows[row].cells[col].state = State.CLICK_DAY;
DateInfo date = rows[row].cells[col].date;
date.week = col;
mCallBack.clickDate(date);
invalidate();
}
}
// 組
class Row {
public int j;
Row(int j) {
this.j = j;
}
public Cell[] cells = new Cell[TOTAL_COL];
public void drawCells(Canvas canvas) {
for (int i = ; i < cells.length; i++) {
if (cells[i] != null)
cells[i].drawSelf(canvas);
}
}
}
// 單元格
class Cell {
public DateInfo date;
public State state;
/**
* i = 行 j = 列
*/
public int i;
public int j;
public Cell(DateInfo date, State state, int i, int j) {
super();
this.date = date;
this.state = state;
this.i = i;
this.j = j;
}
// 繪制一個單元格 如果顔色需要自定義可以修改
public void drawSelf(Canvas canvas) {
switch (state) {
case CURRENT_MONTH_DAY:
mTextPaint.setColor(Color.parseColor("#80000000"));
break;
case NEXT_MONTH_DAY:
case PAST_MONTH_DAY:
mTextPaint.setColor(Color.parseColor("#b1b1b1"));
break;
case TODAY:
mTextPaint.setColor(Color.parseColor("#F24949"));
break;
case CLICK_DAY:
mTextPaint.setColor(Color.parseColor("#fffffe"));
canvas.drawRect((float) (mCellSpace * i), (float) (mCellwide * (j + ) + radius / ),
(float) (mCellSpace * (i + )), (float) (mCellwide * (j + ) + radius / ), BlueBgPaint);
break;
case REMIND_DAY:
mTextPaint.setColor(Color.parseColor("#80000000"));
canvas.drawRect((float) (mCellSpace * i), (float) (mCellwide * (j + ) + radius / ),
(float) (mCellSpace * (i + )), (float) (mCellwide * (j + ) + radius / ), HuiseBgPaint);
break;
}
// 繪制日期文字
String content = date.day + "";
canvas.drawText(content, (float) ((i + ) * mCellSpace - mTextPaint.measureText(content) / ),
(float) ((j + ) * mCellwide + mTextPaint.measureText(content, , ) / + radius / ),
mTextPaint);
// 繪制右上角提示
String count = date.getCount() + "";
if (!"0".equals(count) && count != null) {
canvas.drawCircle((float) (mCellSpace * (i + ) - radius / ),
(float) ((j + ) * mCellwide + radius / ), radius / , mCirclePaint);
canvas.drawText(count, (float) (mCellSpace * (i + ) - radius / - mCutTextPaint.measureText("3") / ),
(float) ((j + ) * mCellwide + radius / + mCutTextPaint.measureText("3") / ), mCutTextPaint);
}
}
}
/**
* 單元格狀态: 目前月日期,過去的月的日期,下個月的日期,今天,點選的日期,提醒日期
*/
enum State {
CURRENT_MONTH_DAY, PAST_MONTH_DAY, NEXT_MONTH_DAY, TODAY, CLICK_DAY, REMIND_DAY;
}
/**
* 填充日期的資料
*/
private void fillDate() {
fillMonthDate();
}
/**
* 通過getWeekDayFromDate得到一個月第一天是星期幾就可以算出所有的日期的位置 然後依次填充 這裡最好重構一下
*/
private void fillMonthDate() {
int monthDay = DateUtil.getCurrentMonthDay();// 今天
// 上個月的天數
int lastMonthDays = DateUtil.getMonthDays(mShowDate.year, mShowDate.month - );
// 目前月的天數
int currentMonthDays = DateUtil.getMonthDays(mShowDate.year, mShowDate.month);
//當月1号是星期幾
int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year, mShowDate.month);
boolean isCurrentMonth = false;
if (DateUtil.isCurrentMonth(mShowDate)) {
isCurrentMonth = true;
}
int day = ;
for (int j = ; j < TOTAL_ROW; j++) {
rows[j] = new Row(j);
for (int i = ; i < TOTAL_COL; i++) {
int postion = i + j * TOTAL_COL;// 單元格位置
// 這個月的
if (postion >= firstDayWeek && postion < firstDayWeek + currentMonthDays) {
day++;
if (isCurrentMonth && day == monthDay) {
DateInfo date = DateInfo.modifiDayForObject(mShowDate, day);
mClickCell = new Cell(date, State.TODAY, i, j);
date.week = i;
rows[j].cells[i] = new Cell(date, State.CLICK_DAY, i, j);
continue;
}
rows[j].cells[i] = new Cell(DateInfo.modifiDayForObject(mShowDate, day),
State.CURRENT_MONTH_DAY, i, j);
} else if (postion < firstDayWeek) {
// 上個月
rows[j].cells[i] = new Cell(new DateInfo(mShowDate.year, mShowDate.month - ,
lastMonthDays - (firstDayWeek - postion - )), State.PAST_MONTH_DAY, i, j);
} else if (postion >= firstDayWeek + currentMonthDays) {
// 下個月
rows[j].cells[i] = new Cell((new DateInfo(mShowDate.year, mShowDate.month + ,
postion - firstDayWeek - currentMonthDays + )), State.NEXT_MONTH_DAY, i, j);
}
}
}
}
/**
* 繪制提醒單元格
*
* @param i
* @return
*
*/
public void updateMonthDate(List<DateInfo> dateInfos) {
DateInfo dateInfo;
for (int k = ; k < dateInfos.size(); k++) {
dateInfo = dateInfos.get(k);
//目前顯示view為提醒月時繪制提醒日期
if (mShowDate.year == dateInfo.getYear() && mShowDate.month == dateInfo.getMonth()) {
int[] cut = getSubscript(dateInfo.getDay());
rows[cut[]].cells[cut[]].state = State.REMIND_DAY;
rows[cut[]].cells[cut[]].date = dateInfo;
if (mClickCell != null && mClickCell.date.getDay() == dateInfo.getDay()) {
mClickCell = rows[cut[]].cells[cut[]];
measureClickCell(cut[], cut[]);
}
}
}
invalidate();
}
/**
* 根據日期獲得單元格下标
* @param i
* @return
*/
private int[] getSubscript(int i) {
int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year, mShowDate.month);
i = i + firstDayWeek - ;
int a = i / ;
int b = i % ;
int[] cut = { a, b };
return cut;
}
//更新日期,用于月份切換時
public void update() {
mClickCell = null;
mCallBack.changeDate(mShowDate);
fillDate();
invalidate();
}
//傳回目前時間
public void backToday() {
initDate();
invalidate();
}
// 點選選擇切換月份
public void clickSelect(int year, int month) {
mShowDate.month = month;
mShowDate.year = year;
update();
}
// 向右滑動
public void rightSilde() {
if (mShowDate.month == ) {
mShowDate.month = ;
mShowDate.year += ;
} else {
mShowDate.month += ;
}
update();
}
// 向左滑動
public void leftSilde() {
if (mShowDate.month == ) {
mShowDate.month = ;
mShowDate.year -= ;
} else {
mShowDate.month -= ;
}
update();
}
}
這裡紅色圓心不是在右上角的頂角,需要改成在頂角的話,隻需在右邊留下圓半徑距離即可,和留頂部距離方式一樣。
2.DateUtil時間工具類
package com.example.calendar;
import android.annotation.SuppressLint;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public static int getMonthDays(int year, int month) {
if (month > ) {
month = ;
year += ;
} else if (month < ) {
month = ;
year -= ;
}
int[] arr = { , , , , , , , , , , , };
int days = ;
if ((year % == && year % != ) || year % == ) {
arr[] = ; // 閏年2月29天
}
try {
days = arr[month - ];
} catch (Exception e) {
e.getStackTrace();
}
return days;
}
public static int getYear() {
return Calendar.getInstance().get(Calendar.YEAR);
}
public static int getMonth() {
return Calendar.getInstance().get(Calendar.MONTH) + ;
}
public static int getCurrentMonthDay() {
return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
}
public static int getWeekDay() {
return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
}
public static int getHour() {
return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
}
public static int getMinute() {
return Calendar.getInstance().get(Calendar.MINUTE);
}
public static int[] getWeekSunday(int year, int month, int day, int pervious) {
int[] time = new int[];
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day);
c.add(Calendar.DAY_OF_MONTH, pervious);
time[] = c.get(Calendar.YEAR);
time[] = c.get(Calendar.MONTH) + ;
time[] = c.get(Calendar.DAY_OF_MONTH);
return time;
}
public static int getWeekDayFromDate(int year, int month) {
Calendar cal = Calendar.getInstance();
cal.setTime(getDateFromString(year, month));
int week_index = cal.get(Calendar.DAY_OF_WEEK) - ;
if (week_index < ) {
week_index = ;
}
return week_index;
}
@SuppressLint("SimpleDateFormat")
public static Date getDateFromString(int year, int month) {
String dateString = year + "-" + (month > ? month : ("0" + month)) + "-01";
Date date = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
date = sdf.parse(dateString);
} catch (ParseException e) {
System.out.println(e.getMessage());
}
return date;
}
public static boolean isToday(RepayPlanInfo date) {
return (date.year == DateUtil.getYear() && date.month == DateUtil.getMonth()
&& date.day == DateUtil.getCurrentMonthDay());
}
public static boolean isCurrentMonth(RepayPlanInfo date) {
return (date.year == DateUtil.getYear() && date.month == DateUtil.getMonth());
}
public static String getTimeParseInt(int year, int month, int day) {
String dateString = year + "" + (month > ? month : ("0" + month))
+ (day > ? day : ("0" + day));
return dateString;
}
public static String getTimeParseInt(int year, int month) {
String dateString = year + "" + (month > ? month : ("0" + month));
return dateString;
}
}
3.自定義日期類DateInfo
package com.example.calendar.data;
import java.io.Serializable;
import package com.example.calendar.DateUtil;
import android.os.Parcel;
import android.os.Parcelable;
/**
* 自定義的日期類
*
**/
public class DateInfo implements Serializable {
private static final long serialVersionUID = L;
public int year;
public int month;
public int day;
public int week;
public DateInfo(int year, int month, int day) {
if (month > ) {
month = ;
year++;
} else if (month < ) {
month = ;
year--;
}
this.year = year;
this.month = month;
this.day = day;
}
public DateInfo() {
this.year = DateUtil.getYear();
this.month = DateUtil.getMonth();
this.day = DateUtil.getCurrentMonthDay();
}
public static DateInfo modifiDayForObject(RepayPlanInfo date, int day) {
DateInfo modifiDate = new DateInfo(date.year, date.month, day);
return modifiDate;
}
@Override
public String toString() {
return year + "-" + month + "-" + day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
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;
}
}
好了,自定義的view已經準備好了,接下來就是使用了。
3.使用
首先,左右滑動使用的是viewpage,為了使能無限滑動,這裡我們自定義一個PagerAdapter 。傳入一個月曆卡數組,讓ViewPager循環複用這幾個月曆卡,避免消耗記憶體。
同時viewpage在左右滑動時要判斷是左滑還是右滑去加載月曆資料,是以這裡自定義了OnPageChangeListener
package com.example.calendar;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
public class CustomViewPagerAdapter<V extends View> extends PagerAdapter {
private V[] views;
public CustomViewPagerAdapter(V[] views) {
super();
this.views = views;
}
@Override
public void finishUpdate(View arg0) {
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public Object instantiateItem(View arg0, int arg1) {
if (((ViewPager) arg0).getChildCount() == views.length) {
((ViewPager) arg0).removeView(views[arg1 % views.length]);
}
((ViewPager) arg0).addView(views[arg1 % views.length], );
return views[arg1 % views.length];
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == (arg1);
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
}
@Override
public void startUpdate(View arg0) {
}
public V[] getAllItems() {
return views;
}
}
CalendarActivity.java
package com.example.calendar;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.example.calendar.DateInfo;
import com.example.calendar.DateUtil;
import com.example.calendar.CalendarView;
import com.example.calendar.CalendarView.CallBack;
import com.example.calendar.CustomViewPagerAdapter;
import com.example.calendar.HomePopMenuWindow;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.PopupWindow.OnDismissListener;
public class CalendarActivityextends Activity implements CallBack {
private ViewPager viewPager;
private CustomViewPagerAdapter<CalendarView> viewPagerAdapter;
private LinearLayout linearRepayPlan;
private TextView showYearView, showMonthView, title, xhdtxtMenu;
private List<DateInfo> remindDateInfos = new ArrayList<DateInfo>();
private List<DateInfo> menuDateInfos = new ArrayList<DateInfo>();
private CalendarView[] calendarViews;
private int width;
private int currentYear = DateUtil.getYear();
private int currentMonth = DateUtil.getMonth();
private Context context;
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
context = this;
initData();
initView();
}
private void initData() {
for (int i = ; i < ; i++) {
DateInfo info = new DateInfo();
info.setYear(currentYear);
info.setMonth(currentMonth);
if (currentMonth == ) {
currentYear = currentYear + ;
currentMonth = ;
} else {
currentMonth += ;
}
menuDateInfos.add(, info);
}
DateInfo info = new DateInfo();
info.setBillDate("2017-08-15");
info.setCount();
repayDateInfos.add(info);
}
private void initView() {
viewPager = (ViewPager) findViewById(R.id.viewpager);
showMonthView = (TextView) findViewById(R.id.show_month_view);
showYearView = (TextView) findViewById(R.id.show_year_view);
showYearView.setText(TimeUtil.getCurrentYear1());
showMonthView.setText(TimeUtil.getCurrentMonth1() + "/");
createMassCalendarViews(this, , this);
viewPagerAdapter = new CustomViewPagerAdapter<CalendarView>(calendarViews);
viewPager.setAdapter(viewPagerAdapter);
viewPager.setCurrentItem();
viewPager.setOnPageChangeListener(new CalendarViewPagerLisenter(viewPagerAdapter));
/**
* 當有提醒資料時,調用此方法繪制提醒日期
*/
updateData();
}
public void OnButtonClick(View view) {
switch (view.getId()) {
case R.id.img_calendar:
showPopMenu();
break;
case R.id.xhdTopBack:
finish();
break;
default:
break;
}
}
/**
* 顯示彈窗
*/
private void showPopMenu() {
// 點選彈出一個popupwindow
final HomePopMenuWindow pop = new HomePopMenuWindow(this, menuDateInfos, );
// 定義彈窗按鈕
pop.showAsDropDown1(findViewById(R.id.img_calendar));
pop.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DateInfo info = menuDateInfos.get(position);
CalendarView[] mShowViews = viewPagerAdapter.getAllItems();
mShowViews[viewPager.getCurrentItem() % mShowViews.length].clickSelect(info.getYear(), info.getMonth());
pop.dismiss();
}
});
setBackgroundAlpha(f);
pop.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
setBackgroundAlpha(f);
}
});
}
/**
* 設定添加螢幕的背景透明度
*
* @param bgAlpha
* 螢幕透明度0.0-1.0 1表示完全不透明
*/
public void setBackgroundAlpha(float bgAlpha) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = bgAlpha;
getWindow().setAttributes(lp);
}
//繪制提醒日期
private void updateData() {
CalendarView[] mShowViews = viewPagerAdapter.getAllItems();
mShowViews[viewPager.getCurrentItem() % mShowViews.length].updateMonthDate(remindDateInfos);
}
/**
* 生産多個CalendarView
*
*/
private void createMassCalendarViews(Context context, int count, CallBack callBack) {
calendarViews = new CalendarView[count];
for (int i = ; i < count; i++) {
calendarViews[i] = new CalendarView(context, callBack);
}
}
class CalendarViewPagerLisenter implements OnPageChangeListener {
private SildeDirection mDirection = SildeDirection.NO_SILDE;
int mCurrIndex = ;
private CalendarView[] mShowViews;
public CalendarViewPagerLisenter(CustomViewPagerAdapter<CalendarView> viewAdapter) {
super();
this.mShowViews = viewAdapter.getAllItems();
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int arg0) {
measureDirection(arg0);
updateCalendarView(arg0);
linearRepayPlan.setVisibility(View.GONE);
}
private void updateCalendarView(int arg0) {
if (mDirection == SildeDirection.RIGHT) {
mShowViews[arg0 % mShowViews.length].rightSilde();
} else if (mDirection == SildeDirection.LEFT) {
mShowViews[arg0 % mShowViews.length].leftSilde();
}
mDirection = SildeDirection.NO_SILDE;
}
/**
* 判斷滑動方向
*
* @param arg0
*/
private void measureDirection(int arg0) {
if (arg0 > mCurrIndex) {
mDirection = SildeDirection.RIGHT;
} else if (arg0 < mCurrIndex) {
mDirection = SildeDirection.LEFT;
}
mCurrIndex = arg0;
}
}
enum SildeDirection {
RIGHT, LEFT, NO_SILDE;
}
/**
* CandlendarView回到目前日期
*/
private void backTodayCalendarViews() {
if (calendarViews != null)
for (int i = ; i < calendarViews.length; i++) {
calendarViews[i].backToday();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
//viewpage滑動時顯示目前日期
public void setShowDateViewText(int year, int month) {
showYearView.setText(year + "");
if (month < ) {
showMonthView.setText("0" + month + "/");
} else {
showMonthView.setText(month + "/");
}
}
@Override
public void onMesureCellHeight(float cellSpace, float cellwide) {
}
@Override
public void clickDate(RepayPlanInfo dates) {
// 當點選月曆時回調
}
@Override
public void changeDate(RepayPlanInfo dates) {
//viewpage滑動時回調
setShowDateViewText(dates.year, dates.month);
}
}
上面代碼中我還使用了popupWindow,就是彈出一個listview,可以點選切換月份,我就不貼代碼了
布局activity_calendar
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="40dip"
android:background="@color/white"
android:paddingLeft="15dip"
android:paddingRight="15dip" >
<LinearLayout
android:id="@+id/layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/show_month_view"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:gravity="center"
android:text="01/"
android:textColor="#646464"
android:textSize="15sp" />
<TextView
android:id="@+id/show_year_view"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:text="2017"
android:textColor="#646464"
android:textSize="15sp" />
</LinearLayout>
<ImageView
android:id="@+id/img_calendar"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:onClick="OnButtonClick"
android:padding="10dp"
android:src="@drawable/img_schoolyear" />
</RelativeLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:background="#20000000" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="280dp"
android:layout_gravity="center"
android:background="#ffffff"
android:paddingLeft="15dip"
android:paddingRight="15dip" >
</android.support.v4.view.ViewPager>
</LinearLayout>
好了,大功告成了,相關代碼就這些了~~~