您的位置:首页 > 其它

自定义日历 ViewPager FragmentStatePagerAdapter 自定义View

2014-10-23 21:39 246 查看
一直想给最近在做的笔记本加一个日历查找的功能,但是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,
									Color.parseColor("#44FFFFFF")
									, true);
							if (selectedYear == todayYear
									&& selectedMonth == todayMonth
									&& selectedDay == todayDay) {
								paint.reset();
								paint.setStyle(Style.FILL);
								paint.setColor(selectedCellBG);
								paint.setAntiAlias(true);
								paint.setAlpha(90);
								paint.setAntiAlias(true);
								canvas.drawCircle(
										j * gridWidth + 5 + (gridWidth - 10)
												/ 2,
										((0.5F * gridHeight + (i + 1)
												* gridHeight - 5) - (titleGridHeight + 5 + i
												* gridHeight))
												/ 2
												+ titleGridHeight
												+ 5
												+ i
												* gridHeight,
										(gridHeight - 20) / 2, paint);
							}
							paint.reset();
							paint.setTextSize(currentMonthTextSize);
							paint.setTextAlign(Align.CENTER);
							paint.setColor(currentMonthTextColor);
							paint.setAntiAlias(true);
							paint.setTypeface(Typeface.DEFAULT_BOLD);
							canvas.drawText(
									String.valueOf(currentMonthArray[i][j].dayOfMonth),
									STARTX + j * titleGridWidth + 0.5F
											* gridWidth, STARTY
											+ titleGridHeight + (i + 0.65F)
											* gridHeight, paint);

						} else if (currentMonthArray[i][j].year == this.selectedYear
								&& currentMonthArray[i][j].month == this.selectedMonth
								&& currentMonthArray[i][j].dayOfMonth == this.selectedDay) {
							drawCellBG(canvas, i, j, selectedCellBG,
									false);
							paint.reset();
							paint.setTextSize(currentMonthTextSize);
							paint.setTextAlign(Align.CENTER);
							paint.setColor(Color.WHITE);
							paint.setAntiAlias(true);
							paint.setTypeface(Typeface.DEFAULT_BOLD);
							canvas.drawText(
									String.valueOf(currentMonthArray[i][j].dayOfMonth),
									STARTX + j * titleGridWidth + 0.5F
											* gridWidth, STARTY
											+ titleGridHeight + (i + 0.65F)
											* gridHeight, paint);
						} else {
							// drawCellBG(canvas, i, j, Color.argb(200, 200,
							// 220, 230));
							paint.reset();
							paint.setTextSize(currentMonthTextSize);
							paint.setTextAlign(Align.CENTER);
							paint.setColor(currentMonthTextColor);
							paint.setAntiAlias(true);
							paint.setTypeface(Typeface.DEFAULT_BOLD);
							canvas.drawText(
									String.valueOf(currentMonthArray[i][j].dayOfMonth),
									STARTX + j * titleGridWidth + 0.5F
											* gridWidth, STARTY
											+ titleGridHeight + (i + 0.65F)
											* gridHeight, paint);
						}
						if (currentMonthArray[i][j].record_count != 0) {
							paint.reset();
							paint.setTextSize(34);
							paint.setTextAlign(Align.CENTER);
							paint.setColor(countColor);
							paint.setTypeface(Typeface.DEFAULT_BOLD);
							paint.setAntiAlias(true);
							canvas.drawText(
									String.valueOf(currentMonthArray[i][j].record_count),
									STARTX + j * titleGridWidth + 0.75F
											* gridWidth, STARTY
											+ titleGridHeight + (i + 0.3F)
											* gridHeight, paint);
						}
					} else {
						paint.reset();
						paint.setTextSize(otherMonthTextSize);
						paint.setTextAlign(Align.CENTER);
						paint.setColor(otherMonthTextColor);
						paint.setAntiAlias(true);
						paint.setTypeface(Typeface.DEFAULT_BOLD);
						canvas.drawText(String
								.valueOf(currentMonthArray[i][j].dayOfMonth),
								STARTX + j * titleGridWidth + 0.5F * gridWidth,
								STARTY + titleGridHeight + (i + 0.65F)
										* gridHeight, paint);
					}
				}
			}
		}
	}

	public void drawCellBG(Canvas canvas, int x, int y, int color, boolean today) {
		paint.reset();
		paint.setStyle(Style.FILL);
		paint.setColor(color);
		paint.setAntiAlias(true);
		paint.setAlpha(100);
		if (today) {
			// canvas.drawRect(y * gridWidth + 5, titleGridHeight + 5 + x
			// * gridHeight, (y + 1) * gridWidth - 5, 0.5F * gridHeight
			// + (x + 1) * gridHeight - 5, paint);
			canvas.drawCircle(
					y * gridWidth + 5 + (gridWidth - 10) / 2,
					((0.5F * gridHeight + (x + 1) * gridHeight - 5) - (titleGridHeight + 5 + x
							* gridHeight))
							/ 2 + titleGridHeight + 5 + x * gridHeight,
					(gridHeight - 10) / 2, paint);
		} else {
			canvas.drawCircle(
					y * gridWidth + 5 + (gridWidth - 10) / 2,
					((0.5F * gridHeight + (x + 1) * gridHeight - 5) - (titleGridHeight + 5 + x
							* gridHeight))
							/ 2 + titleGridHeight + 5 + x * gridHeight,
					(gridHeight - 10) / 2, paint);
		}

	}

	public void drawWeeks(Canvas canvas) {
		paint.reset();
		paint.setStrokeWidth(1);
		canvas.drawLine(0, STARTY + titleGridHeight, this.nums_of_columns
				* titleGridWidth, STARTY + titleGridHeight, paint);
		String[] weekTitles = this.getContext().getResources()
				.getStringArray(R.array.week_titles);
		paint.reset();
		paint.setTextSize(45);
		paint.setColor(Color.DKGRAY);
		paint.setTypeface(Typeface.DEFAULT_BOLD);
		paint.setTextAlign(Align.CENTER);
		for (int i = 0; i < this.nums_of_columns; i++) {
			canvas.drawText(weekTitles[i], STARTX + i * titleGridWidth + 0.5F
					* titleGridWidth, (STARTY + titleGridHeight) * 0.7F, paint);
		}
	}

	public void drawRowsAndColumns(Canvas canvas) {
		paint.reset();
		paint.setStrokeWidth(2);
		paint.setColor(Color.DKGRAY);
		// drawRows
		if (showGridRowLine) {
			for (int i = 0; i < this.nums_of_columns - 2; i++) {
				canvas.drawLine(0, STARTY + titleGridHeight + (i + 1)
						* gridHeight, this.nums_of_columns * gridWidth, STARTY
						+ titleGridHeight + (i + 1) * gridHeight, paint);
			}
		}
		if (showGridColumnLine) {
			for (int h = 0; h < this.nums_of_columns - 1; h++) {
				canvas.drawLine(STARTX + (h + 1) * gridWidth, STARTY, STARTX
						+ (h + 1) * gridWidth, STARTY
						+ (this.nums_of_row + 0.5F) * gridHeight, paint);
			}
		}
		// paint.setColor(Color.BLACK);
		// canvas.drawLine(0, STARTY, this.nums_of_columns * gridWidth, STARTY,
		// paint);
	}

	public void drawCalendarEdge(Canvas canvas) {
		paint.reset();
		paint.setColor(Color.DKGRAY);
		paint.setStrokeWidth(3);
		paint.setStyle(Style.STROKE);
		canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);
	}

	public void drawCalendarBG(Canvas canvas) {
		paint.reset();
		paint.setStyle(Style.FILL);
		paint.setColor(backgroundColor);
		canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);
	}

	public int getDayOfWeek(int year, int month, int dayOfMonth) {
		Date date = new Date(year - 1900, month - 1, dayOfMonth);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		if (dayOfWeek == 0) {
			return 7;
		}
		return dayOfWeek;
	}

	public int getDaysOfMonth(int year, int month) {
		Calendar test = Calendar.getInstance();
		test.set(Calendar.YEAR, year);
		test.set(Calendar.MONTH, month - 1);
		int totalDay = test.getActualMaximum(Calendar.DAY_OF_MONTH);
		return totalDay;
	}

	public void caculateOtherMonthDates() {
		// caculate previous month
		Calendar previous = Calendar.getInstance();
		int previousMonth = 0;
		int previousYear = 0;
		if (this.Month == 1) {
			previousMonth = 12;
			previousYear = this.Year - 1;
		} else {
			previousMonth = this.Month - 1;
			previousYear = this.Year;
		}
		previous.set(Calendar.YEAR, previousYear); // actual year
		previous.set(Calendar.MONTH, previousMonth - 1); // actual month - 1
		int dayOfPreviousMonth = getDaysOfMonth(previousYear, previousMonth) + 1;

		int dayOfWeekOfFirstDayOfMonth = getDayOfWeek(this.Year, this.Month, 1);
		for (int i = dayOfWeekOfFirstDayOfMonth - 2; i >= 0; i--) {
			dayOfPreviousMonth--;
			Cell cell = new Cell();
			cell.year = previousYear;
			cell.month = previousMonth;
			cell.dayOfMonth = dayOfPreviousMonth;
			currentMonthArray[0][i] = cell;
		}

		// caculate next month
		int dayOfNextMonth = 0;
		int nextMonth = 0;
		int nextYear = 0;
		if (this.Month == 12) {
			nextMonth = 1;
			nextYear = this.Year + 1;
		} else {
			nextMonth = this.Month + 1;
			nextYear = this.Year;
		}
		boolean begin = false;
		if (this.currentMonthEndX == 5) {
			for (int j = this.currentMonthEndY; j < this.currentMonthArray[5].length; j++) {
				dayOfNextMonth++;
				Cell cell = new Cell();
				cell.year = nextYear;
				cell.month = nextMonth;
				cell.dayOfMonth = dayOfNextMonth;
				currentMonthArray[5][j] = cell;
			}
		} else {
			for (int i = this.currentMonthEndX; i < this.currentMonthArray.length; i++) {
				for (int j = 0; j < this.currentMonthArray[i].length; j++) {
					if (i < this.currentMonthArray.length - 1
							&& j == this.currentMonthEndY) {
						dayOfNextMonth++;
						Cell cell = new Cell();
						cell.year = nextYear;
						cell.month = nextMonth;
						cell.dayOfMonth = dayOfNextMonth;
						currentMonthArray[i][j] = cell;
						begin = true;
					} else {
						if (begin) {
							dayOfNextMonth++;
							Cell cell = new Cell();
							cell.year = nextYear;
							cell.month = nextMonth;
							cell.dayOfMonth = dayOfNextMonth;
							currentMonthArray[i][j] = cell;
						}
					}
				}
			}
		}

	}

	public void caculateCurrentMonthDates() {
		int dayOfWeekOfFirstDayOfMonth = getDayOfWeek(this.Year, this.Month, 1);
		int totalDaysOfMonth = getDaysOfMonth(this.Year, this.Month);
		int dayOfMonth = 0;
		// Log.d("time", "dayOfWeek = " + dayOfWeekOfFirstDayOfMonth);
		// Log.d("time", "getDaysOfMonth = " + totalDaysOfMonth);
		record_count = mNoteDataBaseManager.getCurrentMonthRecordCount(
				this.Year, this.Month, totalDaysOfMonth);
		// for(int i = 0 ; i<record_count.length;i++){
		// Log.d("db","["+(i+1)+"] = "+record_count[i]);
		// }

		boolean begin = false;
		// Log.d("time", "start");
		currentMonthArray = new Cell[nums_of_row][nums_of_columns];
		// monthDates = new ArrayList<Cell>();

		boolean flag = true;
		for (int i = 0; i < this.currentMonthArray.length; i++) {
			if (!flag) {
				break;
			}
			for (int j = 0; j < this.currentMonthArray[i].length; j++) {
				if (i == 0 && (j + 1) == dayOfWeekOfFirstDayOfMonth) {
					dayOfMonth = dayOfMonth + 1;
					Cell cell = new Cell();
					cell.year = this.Year;
					cell.month = this.Month;
					cell.dayOfMonth = dayOfMonth;
					cell.isCurrentDayOfMonth = true;
					cell.record_count = record_count[(dayOfMonth - 1)];
					currentMonthArray[i][j] = cell;
					begin = true;
				} else {
					if (begin) {
						if (dayOfMonth < totalDaysOfMonth) {
							dayOfMonth = dayOfMonth + 1;
							Cell cell = new Cell();
							cell.year = this.Year;
							cell.month = this.Month;
							cell.dayOfMonth = dayOfMonth;
							cell.isCurrentDayOfMonth = true;
							cell.record_count = record_count[(dayOfMonth - 1)];
							currentMonthArray[i][j] = cell;
						} else {
							currentMonthEndX = i;
							currentMonthEndY = j;
							flag = false;
							break;
						}
					}
				}
			}
		}
		for (int i = 0; i < this.currentMonthArray.length; i++) {
			for (int j = 0; j < this.currentMonthArray[i].length; j++) {
				// Log.d("time", "currentMonthArray[" + (i + 1) + "][" + (j + 1)
				// + "] = " + currentMonthArray[i][j]);
			}
		}
		// Log.d("time", "finish");
	}

	private class Cell {
		public int year;
		public int month;
		public int dayOfMonth;
		boolean isCurrentDayOfMonth;
		public int record_count;
	}

	private void touchToChangeDate(float x, float y) {
		int row = (int) ((y - this.titleGridHeight) / this.gridHeight);
		int column = (int) (x / this.gridWidth);
		android.util.Log.d("touch", "row = " + row);
		android.util.Log.d("touch", "column = " + column);

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {

			begin = event.getX();
			android.util.Log.d("touch", "begin = " + begin);
			if (event.getY() > this.titleGridHeight) {
				row1 = (int) ((event.getY() - this.titleGridHeight) / this.gridHeight);
				column1 = (int) (event.getX() / this.gridWidth);
			}
		}
		if (event.getAction() == MotionEvent.ACTION_MOVE) {

			row2 = (int) ((event.getY() - this.titleGridHeight) / this.gridHeight);
			column2 = (int) (event.getX() / this.gridWidth);
			if (row2 != row1 || column2 != column1) {
				this.notOutOfRange = false;
			}

		}
		if (event.getAction() == MotionEvent.ACTION_UP) {
			this.setBackgroundResource(R.color.transparent);
			if (event.getY() > this.titleGridHeight && touchable) {
				row3 = (int) ((event.getY() - this.titleGridHeight) / this.gridHeight);
				column3 = (int) (event.getX() / this.gridWidth);
				// android.util.Log.d("touch","row2 = "+(row2+1));
				// android.util.Log.d("touch","column2 = "+(column2+1));
				if (notOutOfRange && row1 == row3 && column1 == column3) {
					// android.util.Log.d("touch", "change Date!");
					Log.d("test", "calendar onPageScrollStateChanged state = "
							+ Config.contentPagerScrollState);
					if (Config.contentPagerScrollState == 0) {
						changeDate(row3, column3);
					}
				}
			}
			notOutOfRange = true;
			float end = event.getX();
		}
		return true;
	}

	private void changeDate(int row, int column) {
		Cell cell = this.currentMonthArray[row][column];
		setSelectedDay(cell.year, cell.month, cell.dayOfMonth);
		this.invalidate();
	}

	public int getYear() {
		return this.Year;
	}

	public int getMonth() {
		return this.Month;
	}

	public int getDayOfMonth() {
		return this.DayOfMonth;
	}

	public interface ChangeDateListener {
		abstract void onChangeSelectedDate(int year, int month, int day);

		// abstract void onChangeMonth();
	}

	public void setYearAndMonth(int year, int month) {
		this.Year = year;
		this.Month = month;
		this.invalidate();
	}
}
实现该view绘制完全用的是Canvas的draw方法。考虑到交互方面要有点击选中的效果,在onTouchEvent函数监听点击的位置并算出点击的日期。个人觉得实现的有点不好。

2 将自定义的日历View装入Fragment,以供Viewpager的适配器调用

public class CalendarItem extends Fragment implements NoteCalendar2.ChangeDateListener{
	private static final String TAG = "CalendarItem";
	private Activity mActivity;
	NoteDataBaseManager noteDBManager;
	int pos;
	NoteCalendar2 calendarView;
	int calendar_year;
    int calendar_month;
    int calendar_selected_year;
    int calendar_selected_month;
    int calendar_selected_day;
    boolean sync;
    
    CallBack mCallBack;
    
    public void setCalendarCallBack(CallBack cb){
    	mCallBack = cb;
    }
	
    public CalendarItem(){}
    
	public CalendarItem(int pos,int sY,int sM,int sD,boolean b) {
		this.pos = pos;
		calendar_year = 1900 + (pos / 12);
		calendar_month = pos % 12 +1;
		calendar_selected_year = sY;
    	calendar_selected_month = sM;
    	calendar_selected_day = sD;
    	sync = b;
	}

	@Override
	public void onAttach(Activity mActivity) {
		super.onAttach(mActivity);
		this.mActivity = mActivity;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//initDBManager();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment_calendar_item, container, false);
		calendarView = (NoteCalendar2) v.findViewById(R.id.calendar);
		calendarView.setSelectedDay(calendar_selected_year, calendar_selected_month, calendar_selected_day);
		calendarView.setYearAndMonth(calendar_year,calendar_month);
		calendarView.setOnChangeDateListener(this);
		calendarView.setTouchable(sync);
		return v;
	}

	@Override
	public void onChangeSelectedDate(int year, int month, int day) {
		// TODO Auto-generated method stub
		
		mCallBack.onChangeSelectedDate(year, month, day);
		
	}
	
	public interface CallBack{
		abstract void onChangeSelectedDate(int year,int month ,int day);
	}
}
在onCreateView加载自定义的View,并让该Fragment 实现自定义View的回调,接受日期选中事件,并定义自身的回调接口,暴露给上层。

3 实现FragmentStatePagerAdapter

private class CalendarPagerAdapter extends FragmentStatePagerAdapter {
		private static final int YEAR_MAX = 2100;
		private static final int YEAR_MIN = 1900;
		private boolean sync;

		public CalendarPagerAdapter(FragmentManager fm) {
			super(fm);
			// TODO Auto-generated constructor stub
		}

		public CalendarPagerAdapter(android.support.v4.app.Fragment fragment,
				boolean b) {
			super(fragment.getChildFragmentManager());
			sync = b;
		}

		@Override
		public Fragment getItem(int pos) {
			// TODO Auto-generated method stub
			CalendarItem ci = new CalendarItem(pos, calendar_selected_year,
					calendar_selected_month, calendar_selected_day, sync);
			ci.setCalendarCallBack(CalendarFragment2.this);
			return ci;
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return (YEAR_MAX - YEAR_MIN) * 12;
		}

	}


简单定义适配器,算出总共有多少个月,每个Fragment就是上面写的,并且实现它的回调接受日期选中事件。\

</pre><pre code_snippet_id="494662" snippet_file_name="blog_20141023_5_3057056" name="code" class="java">4 在Viewpager中添加适配器
</pre><pre code_snippet_id="494662" snippet_file_name="blog_20141023_6_8455249" name="code" class="java">MyViewPager mViewPager;
...
mViewPager = (MyViewPager) v.findViewById(R.id.calendar_pager);
mViewPagerAdapter = new CalendarPagerAdapter(
					CalendarFragment2.this, sync);
mViewPager.setAdapter(mViewPagerAdapter);
...




上面的代码有bug,Fragment最好不要加带参数的构造方法,如

public CalendarItem(int pos,int sY,int sM,int sD,boolean b) {
		this.pos = pos;
		calendar_year = 1900 + (pos / 12);
		calendar_month = pos % 12 +1;
		calendar_selected_year = sY;
    	calendar_selected_month = sM;
    	calendar_selected_day = sD;
    	sync = b;
	}
</pre><pre code_snippet_id="494662" snippet_file_name="blog_20141023_9_4823772" name="code" class="java">CalendarItem ci = new CalendarItem(pos, calendar_selected_year,
calendar_selected_month, calendar_selected_day, sync);
ci.setCalendarCallBack(CalendarFragment2.this);
</pre><pre code_snippet_id="494662" snippet_file_name="blog_20141023_11_7712928" name="code" class="java">改用 setArguments(args)这个方法向fragment传参就不会在最小化恢复后报错。


另外

ci.setCalendarCallBack(CalendarFragment2.this);
这种方式实现回调可能在最小化后丢失回调对象跑出NullPointerException。

最好写成这样

@Override

public void onAttach(Activity mActivity) {

super.onAttach(mActivity);

this.mActivity = mActivity;

mCallBack = (CallBack)mActivity;

}

另外想要向fragment共享复杂类型对象,可以通过继承Application的方法,在Application对象中提供对象的接口。不要把对象加在Fragment的构造函数里,因为程序最小化后可能调用无参的默认的构造行数。

如果你觉得平移的滑动方式不够炫酷可以使用JazzyViewPager满足你的需求,封装了多种左右滑动的切换动画。

如果滑动觉得卡顿,可以像我一样自定义Viewpager,在onTouchEvent作判断,超过一段距离就返回true,把touch事件消耗掉,而不是传递给子view。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐