├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ ├── app-release.apk │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tuanhuo │ │ └── android │ │ └── myapplication │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── android │ │ │ └── myapplication │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── tuanhuo │ └── android │ └── myapplication │ └── ExampleUnitTest.java ├── build.gradle ├── calendarlibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tuanhuo │ │ └── android │ │ └── calendarlibrary │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── android │ │ │ └── calendarlibrary │ │ │ ├── CollapseCalendarView.java │ │ │ ├── listener │ │ │ ├── OnDateSelect.java │ │ │ ├── OnMonthChangeListener.java │ │ │ └── OnTitleClickListener.java │ │ │ ├── manager │ │ │ ├── CalendarManager.java │ │ │ ├── CalendarUnit.java │ │ │ ├── Day.java │ │ │ ├── DefaultFormatter.java │ │ │ ├── Formatter.java │ │ │ ├── Month.java │ │ │ ├── ProgressManager.java │ │ │ ├── ProgressManagerImpl.java │ │ │ ├── RangeUnit.java │ │ │ ├── ResizeManager.java │ │ │ └── Week.java │ │ │ ├── models │ │ │ ├── AbstractViewHolder.java │ │ │ ├── SizeViewHolder.java │ │ │ └── StubViewHolder.java │ │ │ ├── utils │ │ │ └── ChinaDate.java │ │ │ └── widget │ │ │ ├── DayView.java │ │ │ └── WeekView.java │ └── res │ │ ├── color │ │ ├── text_calendar.xml │ │ ├── text_calendar_out_month.xml │ │ ├── text_calendar_week.xml │ │ └── text_calendar_week_out_month.xml │ │ ├── drawable-xxhdpi │ │ ├── ic_arrow_left_normal.png │ │ └── ic_arrow_right_normal.png │ │ ├── drawable │ │ ├── bg_btn_calendar.xml │ │ ├── bg_btn_calendar_today.xml │ │ ├── bg_btn_calendar_today_selected.xml │ │ ├── bg_calendar_point_blue.xml │ │ ├── bg_calendar_point_white.xml │ │ ├── bg_day_type_blue.xml │ │ ├── bg_day_type_gray.xml │ │ ├── bg_day_type_green.xml │ │ ├── bg_day_type_red.xml │ │ ├── ic_arrow_left.xml │ │ └── ic_arrow_right.xml │ │ ├── layout │ │ ├── calendar_layout.xml │ │ ├── day_layout.xml │ │ └── week_layout.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── color.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── tuanhuo │ └── android │ └── calendarlibrary │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── BMmh.png ├── preview.gif └── shot.jpg └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | /.idea 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 主要特性 2 | 3 | * 设置自定义日期角标 4 | * 农历切换 5 | * 左右滑动切换上下周月,上下滑动切换周月模式 6 | * 抽屉式周月切换效果 7 | * 标记指定日期(marker) 8 | * 跳转到指定日期 9 | 10 |
11 | 12 | 13 | ![预览图片](/screenshot/shot.jpg) 14 | 15 | ## 使用方法 16 | 17 | #### 在layout中使用: 18 | 19 | ```xml 20 | 24 | ``` 25 | 26 | #### 使用此方法初始化日历标记数据 27 | 28 | ```java 29 | mManager = new CalendarManager(LocalDate.now(), 30 | CalendarManager.State.MONTH, 31 | LocalDate.now().withYear(100), 32 | LocalDate.now().plusYears(100)); 33 | calendarView.init(mManager); 34 | ``` 35 | 36 | #### 使用方法设置日历数据 37 | 38 | 是否显示农历 39 | ```java 40 | calendarView.showChinaDay(true); 41 | ``` 42 | 回到今天 43 | ```java 44 | calendarView.changeDate(LocalDate.now().toString()); 45 | ``` 46 | 周月切换 47 | ```java 48 | // TODO Auto-generated method stub 49 | mManager.toggleView(); 50 | calendarView.populateLayout(); 51 | ``` 52 | 班排 53 | ```java 54 | calendarView.setArrayData(json); 55 | calendarView.populateLayout(); 56 | ``` 57 | 58 | #### 使用方法添加上相关监听 59 | 60 | 月份切换监听器 61 | ```java 62 | mManager.setMonthChangeListener(new OnMonthChangeListener() { 63 | @Override 64 | public void monthChange(String month, LocalDate mSelected) { 65 | // TODO Auto-generated method stub 66 | //Toast.makeText(MainActivity.this, month, Toast.LENGTH_SHORT).show(); 67 | } 68 | }); 69 | ``` 70 | 日期选中监听器 71 | ```java 72 | calendarView.setDateSelectListener(new OnDateSelect() { 73 | @Override 74 | public void onDateSelected(LocalDate date) { 75 | // Toast.makeText(MainActivity.this, date.toString(), Toast.LENGTH_SHORT).show(); 76 | } 77 | }); 78 | ``` 79 | ## APK 80 | 安装 [apk](https://www.pgyer.com/BMmh) 文件预览效果,或者通过下面二维码去下载安装: 81 | 82 | ![DEMO下载二维码](/screenshot/BMmh.png) 83 | 84 | ## 感谢 85 | [android-collapse-calendar-view](https://github.com/blazsolar/android-collapse-calendar-view) 86 | 87 | ## License 88 | 89 | 90 | Copyright 2018 chenyongci 91 | 92 | Licensed under the Apache License, Version 2.0 (the "License"); 93 | you may not use this file except in compliance with the License. 94 | You may obtain a copy of the License at 95 | 96 | http://www.apache.org/licenses/LICENSE-2.0 97 | 98 | Unless required by applicable law or agreed to in writing, software 99 | distributed under the License is distributed on an "AS IS" BASIS, 100 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 101 | See the License for the specific language governing permissions and 102 | limitations under the License. 103 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion '25.0.2' 6 | defaultConfig { 7 | applicationId "com.tuanhuo.android.myapplication" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(include: ['*.jar'], dir: 'libs') 24 | implementation 'com.android.support:appcompat-v7:25.1.1' 25 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 26 | testImplementation 'junit:junit:4.12' 27 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 28 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 29 | implementation project(':calendarlibrary') 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyongci/Android-Week-Calendar/7d8d27c67237158dbd04e36117240f2d31497101/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1},"path":"app-release.apk","properties":{"packageId":"com.tuanhuo.android.myapplication","split":"","minSdkVersion":"15"}}] -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tuanhuo/android/myapplication/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tuanhuo.android.myapplication; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.tuanhuo.android.myapplication", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/myapplication/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.android.myapplication; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | import android.widget.CompoundButton; 7 | import android.widget.Switch; 8 | 9 | import com.android.calendarlibrary.CollapseCalendarView; 10 | import com.android.calendarlibrary.listener.OnDateSelect; 11 | import com.android.calendarlibrary.listener.OnMonthChangeListener; 12 | import com.android.calendarlibrary.listener.OnTitleClickListener; 13 | import com.android.calendarlibrary.manager.CalendarManager; 14 | 15 | import org.joda.time.LocalDate; 16 | import org.json.JSONArray; 17 | import org.json.JSONObject; 18 | 19 | import java.text.SimpleDateFormat; 20 | import java.util.Calendar; 21 | 22 | /** 23 | * @Author android 24 | * @date 2018/1/22 25 | * @return 26 | */ 27 | public class MainActivity extends AppCompatActivity { 28 | 29 | private CollapseCalendarView calendarView; 30 | private Switch switchChinaDay; 31 | 32 | private CalendarManager mManager; 33 | 34 | private JSONObject json; 35 | 36 | private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 37 | 38 | @Override 39 | protected void onCreate(Bundle savedInstanceState) { 40 | super.onCreate(savedInstanceState); 41 | setContentView(R.layout.activity_main); 42 | 43 | calendarView = (CollapseCalendarView) findViewById(R.id.calendar); 44 | switchChinaDay = (Switch) findViewById(R.id.switch_china_day); 45 | initView(); 46 | initListener(); 47 | initData(); 48 | } 49 | 50 | 51 | private void initView() { 52 | mManager = new CalendarManager(LocalDate.now(), 53 | CalendarManager.State.MONTH, 54 | LocalDate.now(),//默认这个月,如果LocalDate.now().minusYears(1)); 55 | LocalDate.now().plusYears(1));//可以划之后一年 56 | calendarView.init(mManager); 57 | 58 | calendarView.showChinaDay(true);//显示农历 59 | 60 | switchChinaDay.setChecked(true); 61 | } 62 | 63 | private void initListener(){ 64 | switchChinaDay.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 65 | @Override 66 | public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 67 | calendarView.showChinaDay(b); 68 | if(b){ 69 | switchChinaDay.setText("显示农历"); 70 | }else{ 71 | switchChinaDay.setText("隐藏农历"); 72 | } 73 | } 74 | }); 75 | 76 | /** 77 | *月份切换监听器 78 | */ 79 | mManager.setMonthChangeListener(new OnMonthChangeListener() { 80 | 81 | @Override 82 | public void monthChange(String month, LocalDate mSelected) { 83 | // TODO Auto-generated method stub 84 | //Toast.makeText(MainActivity.this, month, Toast.LENGTH_SHORT).show(); 85 | } 86 | 87 | }); 88 | /** 89 | * 日期选中监听器 90 | */ 91 | calendarView.setDateSelectListener(new OnDateSelect() { 92 | 93 | @Override 94 | public void onDateSelected(LocalDate date) { 95 | // Toast.makeText(MainActivity.this, date.toString(), Toast.LENGTH_SHORT).show(); 96 | } 97 | }); 98 | 99 | calendarView.setTitleClickListener(new OnTitleClickListener() { 100 | 101 | @Override 102 | public void onTitleClick() { 103 | // Toast.makeText(MainActivity.this, "点击标题", Toast.LENGTH_SHORT).show(); 104 | } 105 | }); 106 | /** 107 | * 回到今天 108 | */ 109 | findViewById(R.id.btn_today).setOnClickListener(new View.OnClickListener() { 110 | 111 | @Override 112 | public void onClick(View v) { 113 | // TODO Auto-generated method stub 114 | calendarView.changeDate(LocalDate.now().toString()); 115 | } 116 | }); 117 | /** 118 | * 周月切换 119 | */ 120 | findViewById(R.id.btn_changemode).setOnClickListener(new View.OnClickListener() { 121 | 122 | @Override 123 | public void onClick(View v) { 124 | // TODO Auto-generated method stub 125 | mManager.toggleView(); 126 | calendarView.populateLayout(); 127 | } 128 | }); 129 | } 130 | 131 | 132 | private void initData() { 133 | Calendar cal = Calendar.getInstance(); 134 | // cal.set(Calendar.MONTH, 9); 135 | // cal.set(Calendar.DAY_OF_MONTH, 0); 136 | json = new JSONObject(); 137 | try { 138 | for (int i = 0; i < 30; i++) { 139 | JSONObject jsonObject2 = new JSONObject(); 140 | if (i <= 6) { 141 | jsonObject2.put("type", "休"); 142 | } else if ( i > 6 && i< 11) { 143 | jsonObject2.put("type", "班"); 144 | } 145 | if (i%3 == 0) { 146 | jsonObject2.put("list", new JSONArray()); 147 | } 148 | 149 | json.put(sdf.format(cal.getTime()), jsonObject2); 150 | 151 | cal.add(Calendar.DAY_OF_MONTH, 1); 152 | } 153 | } catch (Exception e) { 154 | // TODO: handle exception 155 | e.printStackTrace(); 156 | } 157 | //设置数据显示 158 | calendarView.setArrayData(json); 159 | //刷新日期 160 | calendarView.populateLayout(); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 22 | 23 |