Android 仿365日历支持左右切换月份上下收缩


Android 仿365日历支持左右切换月份上下收缩_第1张图片           Android 仿365日历支持左右切换月份上下收缩_第2张图片


公司项目内要求添加日历功能,网上找了几个demo,修改了一下这是最终效果

需求:

左右切换月份,点击某一天,背景变色,只显示本月的,上下月不显示(原demo是支持的,我只是把上下月的textview背景置为白色了,可修改回来),支持上下收缩定住在所选的那一天的行,由于,我擅自修改了上下月,所有有的月份会有六行,有的月份会有五行,这给上下收缩带来了困难,每次还要计算收缩的位置。。。。

代码:

月份的显示就不说了,里面的算法看懂就行,切换时每次添加一个GridView来显示,切换月份是根据手势来控制的,左滑上一个月,右滑下一个月

@Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {
        if (e1.getX() - e2.getX() > 120) {
            //像左滑动
            jumpMonth++;     //下一个月
            upDateView();
            return true;
        } else if (e1.getX() - e2.getX() < -120) {
            //向右滑动
            jumpMonth--;     //上一个月
            upDateView();
            return true;
        }
        return false;
    }


private void upDateView(){
        addGridView();   //添加一个gridView
        calV = new CalendarAdapter(this, getResources(), jumpMonth, jumpYear, year_c, month_c, day_c);
        gridView.setAdapter(calV);
        addTextToTopTextView(topText);
    }

//添加gridview
    private void addGridView() {
        // TODO 如果滑动到其他月默认定位到第一行,划回本月定位到当天那行
        if (jumpMonth == 0){
            location = currentLoction;
        }else{
            location = 1f;
        }
        // TODO 选择的月份 定位到选择的那天
        if (((jumpMonth + month_c)+"").equals(Constants.zMonth)){
            location = selectLoction;
        }
        Log.d("location", "location == " + location + "   currentLoction == " + currentLoction);

        gridView.setOnTouchListener(new OnTouchListener() {
            //将gridview中的触摸事件回传给gestureDetector
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                return CalendarActivity.this.gestureDetector.onTouchEvent(event);
            }
        });

        gridView.setOnItemClickListener(new OnItemClickListener() {
            //gridView中的每一个item的点击事件
            @Override
            public void onItemClick(AdapterView arg0, View arg1, int position,
                                    long arg3) {
                //点击任何一个item,得到这个item的日期(排除点击的是周日到周六(点击不响应))
                int startPosition = calV.getStartPositon();
                int endPosition = calV.getEndPosition();
                String scheduleDay;
                String scheduleYear;
                String scheduleMonth;
                location = (float) ((5 - position/7) * 0.2);
                if (startPosition <= position + 7 && position <= endPosition - 7) {
                    scheduleDay = calV.getDateByClickItem(position).split("\\.")[0];  //这一天的阳历
                    //String scheduleLunarDay = calV.getDateByClickItem(position).split("\\.")[1];  //这一天的阴历
                    scheduleYear = calV.getShowYear();
                    scheduleMonth = calV.getShowMonth();
                    Constants.zYear = scheduleYear;
                    Constants.zMonth = scheduleMonth;
                    Constants.zDay = scheduleDay;

                    if (Constants.scale == 0.2f){
                        location = (5 - position/7) * Constants.scale;
                    }else{
                        location = (4 - position/7) * Constants.scale;
                    }
                    selectLoction = location;
                    calV.notifyDataSetChanged();
                    Toast.makeText(CalendarActivity.this, scheduleYear + "-" + scheduleMonth + "-" + scheduleDay, Toast.LENGTH_SHORT).show();

                }
            }

        });
    }

 在CalendarAdapter中,判断这个月能占几行

//得到某年的某月的天数且这月的第一天是星期几
	public void getCalendar(int year, int month){
		isLeapyear = sc.isLeapYear(year);              //是否为闰年
		daysOfMonth = sc.getDaysOfMonth(isLeapyear, month);  //某月的总天数
		dayOfWeek = sc.getWeekdayOfMonth(year, month);      //某月第一天为星期几
		lastDaysOfMonth = sc.getDaysOfMonth(isLeapyear, month-1);  //上一个月的总天数

		int days = daysOfMonth;
		if (dayOfWeek != 7){
			days = days + dayOfWeek;
		}
		if (days <= 35){
			items = 35;
			Constants.scale = 0.25f;
		}else{
			items = 42;
			Constants.scale = 0.2f;
		}

		Log.d("DAY", isLeapyear+" ======  "+daysOfMonth+"  ============  "+dayOfWeek+"  =========   "+lastDaysOfMonth);
		getweek(year,month);
	}

adapter中显示背景:

private void getweek(int year, int month) {
		int j = 1;
		int flag = 0;
		String lunarDay = "";
		
		//得到当前月的所有日程日期(这些日期需要标记)

		for (int i = 0; i < dayNumber.length; i++) {
			// 周一
			 if(i < dayOfWeek){  //前一个月
				int temp = lastDaysOfMonth - dayOfWeek+1;
//				lunarDay = lc.getLunarDate(year, month-1, temp+i,false);
				dayNumber[i] = (temp + i)+"."+lunarDay;
//				 setShowMonth(String.valueOf(""));
				
			}else if(i < daysOfMonth + dayOfWeek){   //本月
				String day = String.valueOf(i-dayOfWeek+1);   //得到的日期
//				lunarDay = lc.getLunarDate(year, month, i-dayOfWeek+1,false);
				dayNumber[i] = i-dayOfWeek+1+"."+lunarDay;
				//对于当前月才去标记当前日期
				if(sys_year.equals(String.valueOf(year)) && sys_month.equals(String.valueOf(month)) && sys_day.equals(day)){
					//标记当前日期
					currentFlag = i;
				}
				setShowYear(String.valueOf(year));
				setShowMonth(String.valueOf(month));
				setAnimalsYear(lc.animalsYear(year));
				setLeapMonth(lc.leapMonth == 0?"":String.valueOf(lc.leapMonth));
				setCyclical(lc.cyclical(year));
			}else{   //下一个月
//				lunarDay = lc.getLunarDate(year, month+1, j,false);
				dayNumber[i] = j+"."+lunarDay;
//				 setShowMonth(String.valueOf(""));
				j++;
			}
		}
        
        String abc = "";
        for(int i = 0; i < dayNumber.length; i++){
        	 abc = abc+dayNumber[i]+":";
        }
        Log.d("DAYNUMBER",abc);


	}

Activity onCreate()中添加收缩效果,注意计算比例的部分,

日历显示五行的比例是:0.25  0.5  0.75  1

日历显示六行的比例是:0.2   0.4   0.6  0.75  1

/**
         * 如果 少于或者等于35天显示五行 多余35天显示六行
         * 五行: 收缩比例是:0.25,0.5,0.75,1
         * 六行: 收缩比例是:0.2,0.4,0.6,0.8,1
         */
        if (days <= 35){
            Constants.scale = 0.25f;
            currentLoction = (4 - todayPosition/7) * Constants.scale;
        }else{
            Constants.scale = 0.2f;
            currentLoction = (5 - todayPosition/7) * Constants.scale;
        }
        location = currentLoction;
        mTopLayout = (RelativeLayout) findViewById(R.id.rl_head);
        mScrollLayout = (ScrollableLayout)findViewById(R.id.scrollableLayout);

        // TODO 添加收缩效果
        mScrollLayout.setOnScrollListener(new ScrollableLayout.OnScrollListener() {
            @Override
            public void onScroll(int currentY, int maxY) {

                ViewHelper.setTranslationY(mTopLayout, currentY * location);
            }
        });
        mScrollLayout.getHelper().setCurrentContainer(mListView);

源码地址: http://download.csdn.net/detail/qq55214/9467039




你可能感兴趣的:(自定义控件)