自定义日历 ViewPager FragmentStatePagerAdapter 自定义View

本文介绍了如何使用ViewPager和FragmentStatePagerAdapter实现一个自定义的日历功能,支持左右滑动和标注记录数。通过创建自定义日历View并封装到Fragment中,再利用FragmentStatePagerAdapter进行管理,确保流畅的滑动体验和内存效率。同时提到了避免Fragment构造方法传参、对象共享的最佳实践,以及解决滑动卡顿的方法。
摘要由CSDN通过智能技术生成

一直想给最近在做的笔记本加一个日历查找的功能,但是google源生的calendarView似乎只能上下滑动,而且不支持在日历上标注文字。

本人才浅,面对谷歌日历源码无从下手,于是想自己开发一个可以左右滑动,并且支持标注当日记录数的日历。


实现效果如图



实现思路:

android.support.v4.view.ViewPager可以提供一个左右滑动的效果,实现其适配器android.support.v4.app.FragmentStatePagerAdapter,其中每个日历界面是它的一个Fragment,在这个Fragment中的onCreateView加载自定义的日历View。

FragmentStatePagerAdapter这个适配器可以不缓存每个自定义View的视图,当左右滑动后,前一个Fragment会被销毁,因此保证大量滑动不会造成太多内存浪费。


1 自定义日历View

public class NoteCalendar2 extends View {
	private int nums_of_row = 6;
	private int nums_of_columns = 7;
	private final static float STARTX = 0;
	private final static float STARTY = 0;
	private float gridWidth;
	private float gridHeight;
	private float titleGridHeight;
	private float titleGridWidth;
	private int backgroundColor = Color.TRANSPARENT;
	private boolean showGridRowLine = false;
	private boolean showGridColumnLine = false;

	private int currentMonthEndX;
	private int currentMonthEndY;

	private final int currentMonthTextColor = Color.DKGRAY;
	private final int otherMonthTextColor = Color.LTGRAY;
	private final int countColor = Color.BLACK;
	private final int selectedCellBG = Color.RED;

	private final int currentMonthTextSize = 50;
	private final int otherMonthTextSize = 43;

	private boolean touchable = true;

	public boolean isTouchable() {
		return touchable;
	}

	public void setTouchable(boolean touchable) {
		this.touchable = touchable;
	}

	private NoteDataBaseManager mNoteDataBaseManager;

	// List<Cell> monthDates;
	Cell[][] currentMonthArray;
	int[] record_count;

	// curent date
	private int Year; // actual year

	public void setYear(int year) {
		Year = year;
	}

	public void setMonth(int month) {
		Month = month;
	}

	public void setDayOfMonth(int dayOfMonth) {
		DayOfMonth = dayOfMonth;
	}

	private int Month; // actual month
	private int DayOfMonth; // actual day
	private int selectedYear;

	public int getSelectedYear() {
		return selectedYear;
	}

	public int getSelectedMonth() {
		return selectedMonth;
	}

	public int getSelectedDay() {
		return selectedDay;
	}

	private int selectedMonth;
	private int selectedDay;
	private int todayYear;
	private int todayMonth;
	private int todayDay;
	public int SLIDING_LENGTH = 300;

	Paint paint;

	int row1, row2, row3, column1, column2, column3;
	boolean notOutOfRange = true;
	float begin, end;

	ChangeDateListener mChangeDateListener;

	public void setSelectedDay(int year, int month, int dayOfMonth) {
		this.selectedYear = year;
		this.selectedMonth = month;
		this.selectedDay = dayOfMonth;
		if (mChangeDateListener != null) {
			mChangeDateListener.onChangeSelectedDate(selectedYear,
					selectedMonth, selectedDay);
		}
	}

	public NoteCalendar2(Context context) {
		super(context);
		paint = new Paint();
		setCurrentDate();
		initNoteDataBaseManager(context);
	}

	private void initNoteDataBaseManager(Context context) {
		mNoteDataBaseManager = NoteApplication.getDbManager();
	}

	private void setCurrentDate() {
		Calendar cal = Calendar.getInstance();
		this.Year = cal.get(Calendar.YEAR);
		this.Month = cal.get(Calendar.MONTH) + 1;
		this.DayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
		this.todayYear = this.Year;
		this.todayMonth = this.Month;
		this.todayDay = this.DayOfMonth;

	}

	public void setOnChangeDateListener(ChangeDateListener c) {
		mChangeDateListener = c;
	}

	public NoteCalendar2(Context context, AttributeSet attrs) {
		super(context, attrs);

		// TODO Auto-generated constructor stub
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.NoteCalendar);
		backgroundColor = a.getColor(R.styleable.NoteCalendar_backgroundColor,
				backgroundColor);
		a.recycle();
		paint = new Paint();
		setCurrentDate();
		initNoteDataBaseManager(context);
	}

	@Override
	public void onDraw(Canvas canvas) {
		// Log.d("screen", "view width = " + getWidth());
		// Log.d("screen", "view width = " + getHeight());
		caculateCurrentMonthDates();
		caculateOtherMonthDates();
		gridHeight = this.getHeight() / (this.nums_of_row + 0.5F);
		gridWidth = this.getWidth() / this.nums_of_columns;
		titleGridWidth = gridWidth;
		titleGridHeight = (this.getHeight() / (this.nums_of_row + 0.5F)) * 0.5F;
		drawCalendarBG(canvas);
		drawCalendarEdge(canvas);
		drawWeeks(canvas);
		drawRowsAndColumns(canvas);
		drawDayOfMonth(canvas);
		super.onDraw(canvas);
	}

	public void drawDayOfMonth(Canvas canvas) {
		for (int i = 0; i < nums_of_row; i++) {
			for (int j = 0; j < nums_of_columns; j++) {
				if (currentMonthArray[i][j] != null) {
					if (currentMonthArray[i][j].isCurrentDayOfMonth == true) {
						if (currentMonthArray[i][j].year == this.todayYear
								&& currentMonthArray[i][j].month == this.todayMonth
								&& currentMonthArray[i][j].dayOfMonth == this.todayDay) {
							drawCellBG(canvas, i, j,
									
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值