您的位置:首页 > 移动开发 > Android开发

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

2016-03-24 20:55 615 查看


          


公司项目内要求添加日历功能,网上找了几个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息