├── .gitignore ├── CalendarPicker.iml ├── LICENSE ├── README.md ├── app ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── maxproj │ │ └── calendarpicker │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── maxproj │ │ │ └── calendarpicker │ │ │ ├── Builder.java │ │ │ ├── Config │ │ │ └── MyConfig.java │ │ │ ├── Fragments │ │ │ ├── FragmentBase.java │ │ │ ├── FragmentCalendarMonthBase.java │ │ │ ├── FragmentCalendarPicker.java │ │ │ └── FragmentCalendarViewpager.java │ │ │ ├── MainActivity.java │ │ │ ├── Models │ │ │ ├── CalendarDay.java │ │ │ ├── CalendarMonth.java │ │ │ ├── CalendarWeek.java │ │ │ ├── Custom.java │ │ │ ├── EventCalendarSelectDay.java │ │ │ └── YearMonthDay.java │ │ │ └── Views │ │ │ ├── ViewCalendarDayWithActivity.java │ │ │ └── ViewCalendarWeekWithActivity.java │ └── res │ │ ├── drawable │ │ ├── com_maxproj_calendarpicker_audio_unread_dot_3x.png │ │ ├── com_maxproj_calendarpicker_calendar_selected_circle.xml │ │ ├── com_maxproj_calendarpicker_calendar_today_circle.xml │ │ ├── com_maxproj_calendarpicker_shape_button_bg_selected.xml │ │ └── com_maxproj_calendarpicker_shape_button_bg_today.xml │ │ ├── layout │ │ ├── com_maxproj_calendarpicker_activity_main.xml │ │ ├── com_maxproj_calendarpicker_calendar_day_with_activity.xml │ │ ├── com_maxproj_calendarpicker_calendar_week_with_activity.xml │ │ ├── com_maxproj_calendarpicker_fragment_calendar_base.xml │ │ ├── com_maxproj_calendarpicker_fragment_calendar_picker.xml │ │ └── com_maxproj_calendarpicker_fragment_calendar_viewpager.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── maxproj │ └── calendarpicker │ └── ExampleUnitTest.java ├── build.gradle ├── example-release.apk ├── ezgif.com-resize.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | 43 | # Keystore files 44 | *.jks 45 | 46 | # External native build folder generated in Android Studio 2.2 and later 47 | .externalNativeBuild 48 | 49 | # Google Services (e.g. APIs or Firebase) 50 | google-services.json 51 | 52 | # Freeline 53 | freeline.py 54 | freeline/ 55 | freeline_project_description.json 56 | -------------------------------------------------------------------------------- /CalendarPicker.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Hongyu You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Calendar Picker 2 | 3 | Calendar Picker 4 | 5 | --- 6 | 7 | Can preset a selected day. Can customize almost all text size, color, bg color, and month title. 8 | 9 | Update:
10 | v1.1: If no preset day, hide Selected button. Show it when a day be clicked.
11 | v1.1.2: Remove no needed example code and intent filter which create no needed launch icon.
12 | 13 | 14 | [demo apk](https://github.com/maxyou/CalendarPicker/blob/master/example-release.apk?raw=true)
15 | 16 | ![pic][1] 17 | 18 | [1]: https://raw.githubusercontent.com/maxyou/CalendarPicker/master/ezgif.com-resize.gif 19 | 20 | 21 | Add it in your root build.gradle at the end of repositories: 22 | 23 | allprojects { 24 | repositories { 25 | ... 26 | maven { url 'https://jitpack.io' } 27 | } 28 | } 29 | 30 | Add the dependency: 31 | 32 | dependencies { 33 | compile 'com.github.maxyou:CalendarPicker:v1.1.2' 34 | } 35 | 36 | 37 | Only new a dialog:
38 | 39 | Builder builder = new Builder(MainActivity.this, new Builder.CalendarPickerOnConfirm() { 40 | @Override 41 | public void onComplete(YearMonthDay yearMonthDay) { 42 | MyConfig.uiToast("You pick "+yearMonthDay.year+"-"+yearMonthDay.month+"-"+yearMonthDay.day); 43 | } 44 | }) 45 | .setPromptText("选择一个日期") 46 | .setPromptSize(18) 47 | .setPromptColor(Color.RED) 48 | .setPromptBgColor(0xFFFFFFFF) 49 | 50 | .setSelectedText("已选") 51 | .setSelectedSize(14) 52 | .setSelectedColor(Color.WHITE) 53 | .setSelectedBgColor(0xFF1E90FF) 54 | 55 | .setTodayText("今天") 56 | .setTodaySize(14) 57 | .setTodayColor(Color.DKGRAY) 58 | .setTodayBgColor(Color.YELLOW) 59 | 60 | .setMonthTitle(new Builder.FormatMonthTitle() { 61 | @Override 62 | public String setMonthTitle(int year, int month) { 63 | return ""+year+"年"+month+"月"; 64 | } 65 | }) 66 | .setMonthTitleSize(16) 67 | .setMonthTitleColor(0xFFB22222) 68 | .setMonthTitleBgColor(0x00000000) 69 | 70 | .setWeekIndex(new String[]{"一", "二", "三", "四", "五", "六", "日"}) 71 | .setWeekIndexSize(16) 72 | .setWeekIndexColor(0xFFFF00FF) 73 | .setWeekIndexBgColor(0x00000000) 74 | 75 | .setCancelText("取消") 76 | .setCancelSize(14) 77 | .setCancelColor(Color.RED) 78 | .setCancelBgColor(0xFFFFFFFF) 79 | 80 | .setConfirmText("确定") 81 | .setConfirmSize(14) 82 | .setConfirmColor(Color.RED) 83 | .setConfirmBgColor(0xFFB0E0E6) 84 | 85 | .setPreset(new YearMonthDay(2017, 11, 4)) 86 | .setDaySize(16) 87 | .setDayColor(Color.BLUE) 88 | .setDayOtherMonthColor(0xFF87CEFA) 89 | .setMonthBaseBgColor(0xFFD0EED0) 90 | 91 | .setJump2Preset(true) 92 | //.restoreDefault() 93 | ; 94 | 95 | builder.show(); 96 | 97 | 98 | ## License
99 | under [MIT License](http://www.opensource.org/licenses/MIT). 100 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | apply plugin: 'com.github.dcendents.android-maven' 4 | 5 | group='com.github.maxyou' 6 | 7 | android { 8 | compileSdkVersion 25 9 | buildToolsVersion "25.0.0" 10 | resourcePrefix "com_maxproj_calendarpicker_" 11 | defaultConfig { 12 | minSdkVersion 16 13 | targetSdkVersion 25 14 | versionCode 2 15 | versionName "1.1" 16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 29 | exclude group: 'com.android.support', module: 'support-annotations' 30 | }) 31 | compile 'com.android.support:appcompat-v7:25.0.0' 32 | compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7' 33 | testCompile 'junit:junit:4.12' 34 | compile 'com.android.support:support-v13:25.0.0' 35 | compile 'de.greenrobot:eventbus:2.4.0' 36 | 37 | 38 | compile 'joda-time:joda-time:2.9.3' 39 | } 40 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/youhy/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/maxproj/calendarpicker/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker; 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 | * Instrumentation 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.maxproj.calendarpicker", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Builder.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker; 2 | 3 | import android.app.Activity; 4 | 5 | import com.maxproj.calendarpicker.Config.MyConfig; 6 | import com.maxproj.calendarpicker.Models.Custom; 7 | import com.maxproj.calendarpicker.Models.YearMonthDay; 8 | 9 | /** 10 | * Created by youhy on 17/12/11. 11 | */ 12 | 13 | public class Builder { 14 | 15 | private CalendarPickerOnConfirm calendarPickerOnConfirm; 16 | 17 | 18 | /** 19 | * Calendar Prompt部分 20 | */ 21 | public Builder setPromptText(String promptText) { 22 | MyConfig.custom.promptText = promptText; 23 | return this; 24 | } 25 | 26 | public Builder setPromptSize(int promptSize) { 27 | MyConfig.custom.promptSize = promptSize; 28 | return this; 29 | } 30 | 31 | public Builder setPromptColor(int promptColor) { 32 | MyConfig.custom.promptColor = promptColor; 33 | return this; 34 | } 35 | 36 | public Builder setPromptBgColor(int promptBgColor) { 37 | MyConfig.custom.promptBgColor = promptBgColor; 38 | return this; 39 | } 40 | 41 | public Builder setTodayText(String todayText) { 42 | MyConfig.custom.todayText = todayText; 43 | return this; 44 | } 45 | 46 | public Builder setTodaySize(int todaySize) { 47 | MyConfig.custom.todaySize = todaySize; 48 | return this; 49 | } 50 | 51 | public Builder setTodayColor(int todayColor) { 52 | MyConfig.custom.todayColor = todayColor; 53 | return this; 54 | } 55 | 56 | public Builder setTodayBgColor(int todayBgColor) { 57 | MyConfig.custom.todayBgColor = todayBgColor; 58 | return this; 59 | } 60 | 61 | public Builder setSelectedText(String selectedText) { 62 | MyConfig.custom.selectedText = selectedText; 63 | return this; 64 | } 65 | 66 | 67 | public Builder setSelectedSize(int selectedSize) { 68 | MyConfig.custom.selectedSize = selectedSize; 69 | return this; 70 | } 71 | 72 | public Builder setSelectedColor(int selectedColor) { 73 | MyConfig.custom.selectedColor = selectedColor; 74 | return this; 75 | } 76 | 77 | public Builder setSelectedBgColor(int selectedBgColor) { 78 | MyConfig.custom.selectedBgColor = selectedBgColor; 79 | return this; 80 | } 81 | 82 | /** 83 | * Month Title部分 84 | */ 85 | 86 | public interface FormatMonthTitle { 87 | String setMonthTitle(int year, int month); 88 | } 89 | 90 | public Builder setMonthTitle(FormatMonthTitle formatMonthTitle) { 91 | MyConfig.custom.formatMonthTitle = formatMonthTitle; 92 | return this; 93 | } 94 | 95 | 96 | public Builder setMonthTitleSize(int monthTitleSize) { 97 | MyConfig.custom.monthTitleSize = monthTitleSize; 98 | return this; 99 | } 100 | 101 | public Builder setMonthTitleColor(int monthTitleColor) { 102 | MyConfig.custom.monthTitleColor = monthTitleColor; 103 | return this; 104 | } 105 | 106 | public Builder setMonthTitleBgColor(int monthTitleBgColor) { 107 | MyConfig.custom.monthTitleBgColor = monthTitleBgColor; 108 | return this; 109 | } 110 | 111 | 112 | /** 113 | * Week Index部分 114 | */ 115 | 116 | public Builder setWeekIndex(String index[]) { 117 | MyConfig.custom.weekIndex = index; 118 | return this; 119 | } 120 | 121 | public Builder setWeekIndexSize(int weekIndexSize) { 122 | MyConfig.custom.weekIndexSize = weekIndexSize; 123 | return this; 124 | } 125 | 126 | public Builder setWeekIndexColor(int weekIndexColor) { 127 | MyConfig.custom.weekIndexColor = weekIndexColor; 128 | return this; 129 | } 130 | 131 | public Builder setWeekIndexBgColor(int weekIndexBgColor) { 132 | MyConfig.custom.weekIndexBgColor = weekIndexBgColor; 133 | return this; 134 | } 135 | 136 | 137 | /** 138 | * Day部分 139 | */ 140 | 141 | 142 | public Builder setPreset(YearMonthDay preset) { 143 | MyConfig.custom.preset = preset; 144 | return this; 145 | } 146 | 147 | public Builder setDaySize(int daySize) { 148 | MyConfig.custom.daySize = daySize; 149 | return this; 150 | } 151 | 152 | public Builder setDayColor(int dayColor) { 153 | MyConfig.custom.dayColor = dayColor; 154 | return this; 155 | } 156 | 157 | // public Builder setDayBgColor(int dayBgColor) { 158 | // MyConfig.custom.dayBgColor = dayBgColor; 159 | // return this; 160 | // } 161 | 162 | public Builder setDayOtherMonthColor(int dayOtherMonthColor) { 163 | MyConfig.custom.dayOtherMonthColor = dayOtherMonthColor; 164 | return this; 165 | } 166 | 167 | public Builder setMonthBaseBgColor(int monthBaseBgColor) { 168 | MyConfig.custom.monthBaseBgColor = monthBaseBgColor; 169 | return this; 170 | } 171 | 172 | /** 173 | * Confirm部分 174 | */ 175 | 176 | public Builder setCancelText(String cancelText) { 177 | MyConfig.custom.cancelText = cancelText; 178 | return this; 179 | } 180 | 181 | public Builder setCancelSize(int cancelSize) { 182 | MyConfig.custom.cancelSize = cancelSize; 183 | return this; 184 | } 185 | 186 | public Builder setCancelColor(int cancelColor) { 187 | MyConfig.custom.cancelColor = cancelColor; 188 | return this; 189 | } 190 | 191 | public Builder setCancelBgColor(int cancelBgColor) { 192 | MyConfig.custom.cancelBgColor = cancelBgColor; 193 | return this; 194 | } 195 | 196 | 197 | public Builder setConfirmText(String confirmText) { 198 | MyConfig.custom.confirmText = confirmText; 199 | return this; 200 | } 201 | 202 | public Builder setConfirmSize(int confirmSize) { 203 | MyConfig.custom.confirmSize = confirmSize; 204 | return this; 205 | } 206 | 207 | public Builder setConfirmColor(int confirmColor) { 208 | MyConfig.custom.confirmColor = confirmColor; 209 | return this; 210 | } 211 | 212 | public Builder setConfirmBgColor(int confirmBgColor) { 213 | MyConfig.custom.confirmBgColor = confirmBgColor; 214 | return this; 215 | } 216 | 217 | 218 | public interface CalendarPickerOnConfirm { 219 | void onComplete(YearMonthDay yearMonthDay); 220 | } 221 | 222 | public Builder(Activity activity, CalendarPickerOnConfirm calendarPickerOnConfirm) { 223 | MyConfig.activity = activity; 224 | this.calendarPickerOnConfirm = calendarPickerOnConfirm; 225 | } 226 | 227 | /** 228 | * jump to preset if have 229 | */ 230 | public Builder setJump2Preset(boolean jump2Preset) { 231 | MyConfig.custom.jump2Preset = jump2Preset; 232 | return this; 233 | } 234 | 235 | public Builder restoreDefault() { 236 | MyConfig.custom = new Custom(); 237 | return this; 238 | } 239 | 240 | public void show() { 241 | 242 | if (MyConfig.isPortraitStatus()) { 243 | 244 | MyConfig.builder = this; 245 | MyConfig.openCalendarPicker(MyConfig.custom.preset, calendarPickerOnConfirm); 246 | }else{ 247 | MyConfig.uiToast("not in portrait status"); 248 | } 249 | 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Config/MyConfig.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Config; 2 | 3 | import android.app.Activity; 4 | import android.app.FragmentTransaction; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.graphics.drawable.Drawable; 7 | import android.graphics.drawable.GradientDrawable; 8 | import android.graphics.drawable.ShapeDrawable; 9 | import android.os.Handler; 10 | import android.os.Looper; 11 | import android.util.TypedValue; 12 | import android.view.View; 13 | import android.widget.LinearLayout; 14 | import android.widget.TextView; 15 | import android.widget.Toast; 16 | 17 | import com.maxproj.calendarpicker.Builder; 18 | import com.maxproj.calendarpicker.Fragments.FragmentCalendarPicker; 19 | import com.maxproj.calendarpicker.Models.CalendarMonth; 20 | import com.maxproj.calendarpicker.Models.CalendarWeek; 21 | import com.maxproj.calendarpicker.Models.Custom; 22 | import com.maxproj.calendarpicker.Models.YearMonthDay; 23 | 24 | import org.joda.time.DateTimeConstants; 25 | import org.joda.time.LocalDate; 26 | 27 | /** 28 | * Created by youhy on 17/12/4. 29 | */ 30 | 31 | public class MyConfig { 32 | 33 | public static Activity activity; 34 | public static Builder builder; 35 | public static Custom custom = new Custom(); 36 | 37 | public static boolean isPortraitStatus(){ 38 | 39 | View contentView = activity.findViewById(android.R.id.content); 40 | 41 | int height = contentView.getHeight(); 42 | int width = contentView.getWidth(); 43 | 44 | if (height > width){ 45 | return true; 46 | }else{ 47 | return false; 48 | } 49 | 50 | } 51 | 52 | // public static int dp2Px(float dp) { 53 | // final float scale = app.getResources().getDisplayMetrics().density; 54 | // return (int) (dp * scale + 0.5f); //from http://developer.android.com/guide/practices/screens_support.html#screen-independence 55 | // } 56 | // 57 | // public static int px2dip(float pxValue) { 58 | // final float scale = app.getResources().getDisplayMetrics().density; 59 | // return (int) (pxValue / scale + 0.5f); 60 | // } 61 | // 62 | // public static int getPxFromDimen(int dimen_id) { 63 | // return app.getResources().getDimensionPixelSize(dimen_id); 64 | // } 65 | // 66 | // public static Date string_yyyy_MM_dd_HH_mm2Date(String time) { 67 | // Date date; 68 | // 69 | // SimpleDateFormat df = new SimpleDateFormat(MyConfig.app.getString(R.string.time_yyyy_MM_dd_HH_mm)); 70 | // try { 71 | // date = df.parse(time); 72 | // } catch (Exception e) { 73 | // date = null; 74 | // } 75 | // return date; 76 | // } 77 | 78 | public static CalendarWeek getWeekIncludeThisDay(LocalDate localDate) { 79 | 80 | LocalDate monday = localDate.withDayOfWeek(DateTimeConstants.MONDAY); 81 | LocalDate tuesday = localDate.withDayOfWeek(DateTimeConstants.TUESDAY); 82 | LocalDate wednesday = localDate.withDayOfWeek(DateTimeConstants.WEDNESDAY); 83 | LocalDate thursday = localDate.withDayOfWeek(DateTimeConstants.THURSDAY); 84 | LocalDate friday = localDate.withDayOfWeek(DateTimeConstants.FRIDAY); 85 | LocalDate saturday = localDate.withDayOfWeek(DateTimeConstants.SATURDAY); 86 | LocalDate sunday = localDate.withDayOfWeek(DateTimeConstants.SUNDAY); 87 | 88 | CalendarWeek calendarWeek = new CalendarWeek( 89 | monday, 90 | tuesday, 91 | wednesday, 92 | thursday, 93 | friday, 94 | saturday, 95 | sunday 96 | ); 97 | calendarWeek.firstDayOfCurrentMonth = localDate.withDayOfMonth(1); 98 | calendarWeek.originDate = localDate; 99 | 100 | return calendarWeek; 101 | } 102 | 103 | 104 | public static CalendarMonth getMonthIncludeThisDay(LocalDate localDate) { 105 | 106 | CalendarMonth calendarMonth = new CalendarMonth(); 107 | 108 | calendarMonth.firstDayOfCurrentMonth = localDate.withDayOfMonth(1); 109 | 110 | for (int i = 0; i < 6; i++) {//每个月最多6周,最少4周 111 | CalendarWeek w = getWeekIncludeThisDay(calendarMonth.firstDayOfCurrentMonth.plusDays(7 * i)); 112 | 113 | if (i < 4) { 114 | calendarMonth.calendarWeeks.addLast(w); 115 | } else if (w.calendarDayList.getFirst().day.getMonthOfYear() == calendarMonth.firstDayOfCurrentMonth.getMonthOfYear()) { 116 | /** 117 | * 从第5周开始检 118 | * 如果w的第一天的月份等于本月第一天的月份,那么这一周也算本月的周 119 | */ 120 | calendarMonth.calendarWeeks.addLast(w); 121 | } else { 122 | break; 123 | } 124 | 125 | } 126 | calendarMonth.originDate = localDate; 127 | 128 | return calendarMonth; 129 | } 130 | 131 | 132 | 133 | public static void openCalendarPicker(YearMonthDay preset, Builder.CalendarPickerOnConfirm calendarPickerOnConfirm) { 134 | 135 | FragmentCalendarPicker fragmentCalendarPicker = FragmentCalendarPicker.newInstance( 136 | preset, 137 | calendarPickerOnConfirm); 138 | FragmentTransaction ft = activity.getFragmentManager().beginTransaction(); 139 | ft.add(android.R.id.content, fragmentCalendarPicker); 140 | ft.addToBackStack("com.maxproj.calendarpicker"); 141 | ft.commit(); 142 | } 143 | 144 | 145 | public static void uiToast(final String s){ 146 | 147 | uiRun(new Runnable() { 148 | @Override 149 | public void run() { 150 | Toast.makeText(activity, s, Toast.LENGTH_SHORT).show(); 151 | } 152 | }); 153 | 154 | } 155 | 156 | public static void uiRun(Runnable runnable){ 157 | 158 | 159 | if (Looper.myLooper() == Looper.getMainLooper()) { 160 | 161 | if (runnable != null) { 162 | runnable.run(); 163 | } 164 | } else { 165 | 166 | // runOnUiThread()) will execute the Runnable immediately. 167 | // post() always puts the Runnable at the end of the event queue, even if you are already on the main application thread. 168 | 169 | new Handler(Looper.getMainLooper()).post(runnable); 170 | 171 | } 172 | 173 | } 174 | 175 | public static void setYearMonthTxt(TextView v, int year, int month){ 176 | 177 | if(MyConfig.custom.formatMonthTitle != null){ 178 | v.setText(MyConfig.custom.formatMonthTitle.setMonthTitle(year, month)); 179 | }else{ 180 | v.setText(year+" - "+month); 181 | } 182 | } 183 | 184 | public static void setTextViewTxt(TextView v, String customStr){ 185 | 186 | if(customStr != null){ 187 | v.setText(customStr); 188 | return; 189 | } 190 | } 191 | 192 | public static void setTextViewSize(TextView v, Integer custom_size_sp){ 193 | 194 | if(custom_size_sp != null) { 195 | v.setTextSize(TypedValue.COMPLEX_UNIT_SP, custom_size_sp); 196 | } 197 | } 198 | 199 | public static void setTextViewColor(TextView v, Integer customColor){ 200 | 201 | if(customColor != null) { 202 | v.setTextColor(customColor); 203 | } 204 | } 205 | 206 | public static void setTextViewBgColor(TextView v, Integer customColor){ 207 | 208 | if(customColor != null) { 209 | v.setBackgroundColor(customColor); 210 | } 211 | } 212 | 213 | public static void setLayoutBgColor(LinearLayout v, Integer customColor){ 214 | 215 | if(customColor != null) { 216 | v.setBackgroundColor(customColor); 217 | } 218 | } 219 | 220 | public static void setDrawableColor(Drawable v, Integer customColor){ 221 | 222 | if(customColor != null) { 223 | if (v instanceof ShapeDrawable) { 224 | ((ShapeDrawable)v).getPaint().setColor(customColor); 225 | } else if (v instanceof GradientDrawable) { 226 | ((GradientDrawable)v).setColor(customColor); 227 | } else if (v instanceof ColorDrawable) { 228 | ((ColorDrawable)v).setColor(customColor); 229 | } 230 | } 231 | } 232 | 233 | 234 | 235 | } 236 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Fragments/FragmentBase.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Fragments; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | 6 | import de.greenrobot.event.EventBus; 7 | 8 | 9 | public class FragmentBase extends Fragment { 10 | 11 | boolean eventbus_registed = false; 12 | 13 | @Override 14 | public void onActivityCreated(Bundle savedInstanceState) { 15 | super.onActivityCreated(savedInstanceState); 16 | 17 | /** 18 | * eventbus消息的处理可能引用view控件,所以eventbus的注册要在view控件初始化之后,所以挪动到这里 19 | * view控件的初始化在onCreateView中 20 | */ 21 | if(!eventbus_registed) { 22 | EventBus.getDefault().register(this); 23 | eventbus_registed = true; 24 | } 25 | 26 | } 27 | 28 | @Override 29 | public void onDestroyView() { 30 | super.onDestroyView(); 31 | 32 | /** 33 | * 要在view控件被解构之前断开eventbus 34 | */ 35 | if(eventbus_registed) { 36 | EventBus.getDefault().unregister(this); 37 | eventbus_registed = false; 38 | } 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Fragments/FragmentCalendarMonthBase.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Fragments; 2 | 3 | import android.os.Bundle; 4 | import android.util.Log; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.LinearLayout; 9 | import android.widget.TextView; 10 | 11 | import com.maxproj.calendarpicker.Models.CalendarDay; 12 | import com.maxproj.calendarpicker.Models.CalendarMonth; 13 | import com.maxproj.calendarpicker.Models.EventCalendarSelectDay; 14 | import com.maxproj.calendarpicker.R; 15 | import com.maxproj.calendarpicker.Config.MyConfig; 16 | import com.maxproj.calendarpicker.Views.ViewCalendarDayWithActivity; 17 | import com.maxproj.calendarpicker.Views.ViewCalendarWeekWithActivity; 18 | 19 | import org.joda.time.LocalDate; 20 | 21 | import de.greenrobot.event.EventBus; 22 | 23 | 24 | public class FragmentCalendarMonthBase extends FragmentBase { 25 | 26 | LinearLayout fragment_calendar_base; 27 | TextView fragment_calendar_year_month; 28 | 29 | TextView fragment_calendar_base_day_index_1; 30 | TextView fragment_calendar_base_day_index_2; 31 | TextView fragment_calendar_base_day_index_3; 32 | TextView fragment_calendar_base_day_index_4; 33 | TextView fragment_calendar_base_day_index_5; 34 | TextView fragment_calendar_base_day_index_6; 35 | TextView fragment_calendar_base_day_index_7; 36 | 37 | ViewCalendarWeekWithActivity viewCalendarWeekWithActivity_0; 38 | ViewCalendarWeekWithActivity viewCalendarWeekWithActivity_1; 39 | ViewCalendarWeekWithActivity viewCalendarWeekWithActivity_2; 40 | ViewCalendarWeekWithActivity viewCalendarWeekWithActivity_3; 41 | ViewCalendarWeekWithActivity viewCalendarWeekWithActivity_4; 42 | ViewCalendarWeekWithActivity viewCalendarWeekWithActivity_5; 43 | 44 | CalendarMonth calendarMonth; 45 | CalendarDay daySelected = new CalendarDay(null); 46 | 47 | 48 | public interface DayInMonthOnClickListener{ 49 | void dayOnClicked(CalendarDay calendarDay); 50 | } 51 | public DayInMonthOnClickListener dayInMonthOnClickListener; 52 | 53 | ViewCalendarDayWithActivity.DayOnClickListener dayOnClickListener = new ViewCalendarDayWithActivity.DayOnClickListener() { 54 | @Override 55 | public void dayOnClicked(CalendarDay calendarDay) { 56 | 57 | EventBus.getDefault().post(new EventCalendarSelectDay(CalendarDay.clone(calendarDay))); 58 | // daySelected = calendarDay; 59 | // updateCalendarPage(); 60 | 61 | if(dayInMonthOnClickListener != null){ 62 | dayInMonthOnClickListener.dayOnClicked(CalendarDay.clone(calendarDay)); 63 | } 64 | 65 | } 66 | }; 67 | 68 | public void onEventMainThread(EventCalendarSelectDay eventCalendarSelectDay) { 69 | 70 | if(eventCalendarSelectDay != null) { 71 | daySelected.copy(eventCalendarSelectDay.calendarDay); 72 | 73 | Log.d("","EventCalendarSelectDay: monthbase "); 74 | 75 | }else{ 76 | daySelected.copy(null); 77 | } 78 | updateCalendarPage(); 79 | } 80 | 81 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 82 | 83 | if(calendarMonth == null){ 84 | return null; 85 | } 86 | 87 | // Log.d("","FragmentCalendarChooserDialog: FragmentCalendarMonthBase.onCreateView " + calendarMonth.firstDayOfCurrentMonth.getMonthOfYear()+"月"); 88 | View v = inflater.inflate(R.layout.com_maxproj_calendarpicker_fragment_calendar_base, null); 89 | 90 | fragment_calendar_base = (LinearLayout)v.findViewById(R.id.fragment_calendar_base); 91 | fragment_calendar_year_month = (TextView)v.findViewById(R.id.fragment_calendar_year_month); 92 | 93 | fragment_calendar_base_day_index_1 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_1); 94 | fragment_calendar_base_day_index_2 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_2); 95 | fragment_calendar_base_day_index_3 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_3); 96 | fragment_calendar_base_day_index_4 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_4); 97 | fragment_calendar_base_day_index_5 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_5); 98 | fragment_calendar_base_day_index_6 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_6); 99 | fragment_calendar_base_day_index_7 = (TextView) v.findViewById(R.id.fragment_calendar_base_day_index_7); 100 | 101 | viewCalendarWeekWithActivity_0 = (ViewCalendarWeekWithActivity) v.findViewById(R.id.fragment_calendar_base_week_0); 102 | viewCalendarWeekWithActivity_1 = (ViewCalendarWeekWithActivity) v.findViewById(R.id.fragment_calendar_base_week_1); 103 | viewCalendarWeekWithActivity_2 = (ViewCalendarWeekWithActivity) v.findViewById(R.id.fragment_calendar_base_week_2); 104 | viewCalendarWeekWithActivity_3 = (ViewCalendarWeekWithActivity) v.findViewById(R.id.fragment_calendar_base_week_3); 105 | viewCalendarWeekWithActivity_4 = (ViewCalendarWeekWithActivity) v.findViewById(R.id.fragment_calendar_base_week_4); 106 | viewCalendarWeekWithActivity_5 = (ViewCalendarWeekWithActivity) v.findViewById(R.id.fragment_calendar_base_week_5); 107 | 108 | updateCalendarPage(); 109 | 110 | return v; 111 | } 112 | 113 | public void updateCalendarPage() { 114 | 115 | makeCustoms(); 116 | 117 | 118 | viewCalendarWeekWithActivity_0.setViewCalendarWeek(calendarMonth.calendarWeeks.get(0), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 119 | viewCalendarWeekWithActivity_1.setViewCalendarWeek(calendarMonth.calendarWeeks.get(1), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 120 | viewCalendarWeekWithActivity_2.setViewCalendarWeek(calendarMonth.calendarWeeks.get(2), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 121 | viewCalendarWeekWithActivity_3.setViewCalendarWeek(calendarMonth.calendarWeeks.get(3), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 122 | 123 | if (calendarMonth.calendarWeeks.size() > 4) { 124 | viewCalendarWeekWithActivity_4.setViewCalendarWeek(calendarMonth.calendarWeeks.get(4), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 125 | } else { 126 | viewCalendarWeekWithActivity_4.setViewCalendarWeek(null, calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 127 | viewCalendarWeekWithActivity_5.setViewCalendarWeek(null, calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 128 | } 129 | if (calendarMonth.calendarWeeks.size() > 5) { 130 | viewCalendarWeekWithActivity_5.setViewCalendarWeek(calendarMonth.calendarWeeks.get(5), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 131 | } else { 132 | viewCalendarWeekWithActivity_5.setViewCalendarWeek(null, calendarMonth.firstDayOfCurrentMonth.getMonthOfYear(), daySelected, dayOnClickListener); 133 | } 134 | } 135 | 136 | private void makeCustoms() { 137 | 138 | MyConfig.setLayoutBgColor(fragment_calendar_base, MyConfig.custom.monthBaseBgColor); 139 | 140 | MyConfig.setYearMonthTxt(fragment_calendar_year_month, calendarMonth.firstDayOfCurrentMonth.getYear(), calendarMonth.firstDayOfCurrentMonth.getMonthOfYear()); 141 | 142 | MyConfig.setTextViewSize(fragment_calendar_year_month, MyConfig.custom.monthTitleSize); 143 | MyConfig.setTextViewColor(fragment_calendar_year_month, MyConfig.custom.monthTitleColor); 144 | MyConfig.setTextViewBgColor(fragment_calendar_year_month, MyConfig.custom.monthTitleBgColor); 145 | 146 | 147 | if(MyConfig.custom.weekIndex != null && MyConfig.custom.weekIndex.length == 7) { 148 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_1, MyConfig.custom.weekIndex[0]); 149 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_2, MyConfig.custom.weekIndex[1]); 150 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_3, MyConfig.custom.weekIndex[2]); 151 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_4, MyConfig.custom.weekIndex[3]); 152 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_5, MyConfig.custom.weekIndex[4]); 153 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_6, MyConfig.custom.weekIndex[5]); 154 | MyConfig.setTextViewTxt(fragment_calendar_base_day_index_7, MyConfig.custom.weekIndex[6]); 155 | } 156 | 157 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_1, MyConfig.custom.weekIndexSize); 158 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_2, MyConfig.custom.weekIndexSize); 159 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_3, MyConfig.custom.weekIndexSize); 160 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_4, MyConfig.custom.weekIndexSize); 161 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_5, MyConfig.custom.weekIndexSize); 162 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_6, MyConfig.custom.weekIndexSize); 163 | MyConfig.setTextViewSize(fragment_calendar_base_day_index_7, MyConfig.custom.weekIndexSize); 164 | 165 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_1, MyConfig.custom.weekIndexColor); 166 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_2, MyConfig.custom.weekIndexColor); 167 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_3, MyConfig.custom.weekIndexColor); 168 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_4, MyConfig.custom.weekIndexColor); 169 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_5, MyConfig.custom.weekIndexColor); 170 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_6, MyConfig.custom.weekIndexColor); 171 | MyConfig.setTextViewColor(fragment_calendar_base_day_index_7, MyConfig.custom.weekIndexColor); 172 | 173 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_1, MyConfig.custom.weekIndexBgColor); 174 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_2, MyConfig.custom.weekIndexBgColor); 175 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_3, MyConfig.custom.weekIndexBgColor); 176 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_4, MyConfig.custom.weekIndexBgColor); 177 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_5, MyConfig.custom.weekIndexBgColor); 178 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_6, MyConfig.custom.weekIndexBgColor); 179 | MyConfig.setTextViewBgColor(fragment_calendar_base_day_index_7, MyConfig.custom.weekIndexBgColor); 180 | } 181 | 182 | public static FragmentCalendarMonthBase newInstance(LocalDate localDate, CalendarDay daySelected, FragmentCalendarMonthBase.DayInMonthOnClickListener dayInMonthOnClickListener) { 183 | 184 | FragmentCalendarMonthBase f = new FragmentCalendarMonthBase(); 185 | f.calendarMonth = MyConfig.getMonthIncludeThisDay(localDate); 186 | f.daySelected.copy(daySelected); 187 | f.dayInMonthOnClickListener = dayInMonthOnClickListener; 188 | 189 | return f; 190 | } 191 | 192 | 193 | } 194 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Fragments/FragmentCalendarPicker.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Fragments; 2 | 3 | import android.app.FragmentTransaction; 4 | import android.content.pm.ActivityInfo; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.util.Log; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.FrameLayout; 12 | import android.widget.LinearLayout; 13 | import android.widget.TextView; 14 | 15 | import com.maxproj.calendarpicker.Builder; 16 | import com.maxproj.calendarpicker.Config.MyConfig; 17 | import com.maxproj.calendarpicker.Models.CalendarDay; 18 | import com.maxproj.calendarpicker.Models.EventCalendarSelectDay; 19 | import com.maxproj.calendarpicker.Models.YearMonthDay; 20 | import com.maxproj.calendarpicker.R; 21 | 22 | import de.greenrobot.event.EventBus; 23 | 24 | 25 | public class FragmentCalendarPicker extends FragmentBase { 26 | 27 | View calendar_time_chooser_mask; 28 | LinearLayout calendar_time_chooser_layout; 29 | LinearLayout calendar_time_chooser_title_layout; 30 | TextView calendar_time_chooser_title; 31 | TextView calendar_time_chooser_selected; 32 | TextView calendar_time_chooser_today; 33 | FrameLayout calendar_time_chooser_viewpager_container; 34 | LinearLayout calendar_time_chooser_panel_layout; 35 | TextView calendar_time_chooser_panel_cancel; 36 | TextView calendar_time_chooser_panel_confirm; 37 | 38 | final String FRAGMENT_VIEWPAGER_TAG = "com_maxproj_calendarpicker_fragment_calendar_picker"; 39 | 40 | FragmentCalendarViewpager calendar_time_chooser_viewpager; 41 | 42 | CalendarDay daySelected; 43 | YearMonthDay yearMonthDayPreset; 44 | YearMonthDay yearMonthDaySelected; 45 | 46 | int orientationSaved; 47 | 48 | public Builder.CalendarPickerOnConfirm calendarPickerOnConfirm; 49 | 50 | 51 | public static FragmentCalendarPicker newInstance(YearMonthDay yearMonthDay, Builder.CalendarPickerOnConfirm calendarPickerOnConfirm) { 52 | 53 | FragmentCalendarPicker f = new FragmentCalendarPicker(); 54 | f.yearMonthDayPreset = yearMonthDay; 55 | f.calendarPickerOnConfirm = calendarPickerOnConfirm; 56 | return f; 57 | } 58 | 59 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 60 | 61 | Log.d("", "FragmentCalendarChooserDialog: FragmentCalendarChooserDialog.onCreateView"); 62 | View v = inflater.inflate(R.layout.com_maxproj_calendarpicker_fragment_calendar_picker, null); 63 | 64 | findViews(v); 65 | 66 | initClickListener(); 67 | 68 | orientationSaved = getActivity().getRequestedOrientation(); 69 | Log.d("", "orientation ---- saved:" + orientationSaved); 70 | getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 71 | 72 | return v; 73 | } 74 | 75 | private void initMonth() { 76 | 77 | if (yearMonthDayPreset != null && yearMonthDayPreset.year != -1) { 78 | daySelected = new CalendarDay(yearMonthDayPreset.year, yearMonthDayPreset.month, yearMonthDayPreset.day); 79 | } 80 | 81 | if (daySelected != null) { 82 | 83 | new Handler().postDelayed(new Runnable() { 84 | /** 85 | * 由于viewpager的当前item未必已经构建,所以这里需要延迟发送 86 | */ 87 | @Override 88 | public void run() { 89 | EventBus.getDefault().post(new EventCalendarSelectDay(CalendarDay.clone(daySelected))); 90 | } 91 | }, 100); 92 | } 93 | 94 | if (daySelected != null && MyConfig.custom.jump2Preset) { 95 | 96 | calendar_time_chooser_viewpager.gotoDay(CalendarDay.clone(daySelected)); 97 | 98 | } else { 99 | 100 | calendar_time_chooser_viewpager.gotoTodayMonth(); 101 | } 102 | 103 | calendar_time_chooser_layout.setVisibility(View.VISIBLE); 104 | calendar_time_chooser_layout.setY(getActivity().findViewById(android.R.id.content).getHeight()); 105 | 106 | calendar_time_chooser_layout.animate().y(getActivity().findViewById(android.R.id.content).getHeight() 107 | - calendar_time_chooser_layout.getHeight()).setDuration(300); 108 | } 109 | 110 | 111 | private void closeFragment() { 112 | 113 | calendar_time_chooser_layout.animate().y(getActivity().findViewById(android.R.id.content).getHeight()).setDuration(300).withEndAction(new Runnable() { 114 | @Override 115 | public void run() { 116 | 117 | calendar_time_chooser_viewpager.closeFragment(); 118 | getActivity().getFragmentManager().beginTransaction().remove(FragmentCalendarPicker.this).commit(); 119 | } 120 | }); 121 | } 122 | 123 | private void initClickListener() { 124 | 125 | calendar_time_chooser_mask.setOnClickListener(new View.OnClickListener() { 126 | @Override 127 | public void onClick(View v) { 128 | 129 | closeFragment(); 130 | } 131 | }); 132 | 133 | calendar_time_chooser_panel_cancel.setOnClickListener(new View.OnClickListener() { 134 | @Override 135 | public void onClick(View v) { 136 | 137 | closeFragment(); 138 | } 139 | }); 140 | 141 | calendar_time_chooser_panel_confirm.setOnClickListener(new View.OnClickListener() { 142 | @Override 143 | public void onClick(View v) { 144 | 145 | // calendar_time_chooser_layout.animate().x(-MyConfig.screenWidth).setDuration(500); 146 | 147 | if (daySelected == null) { 148 | // MyConfig.MyToast(0, getActivity(), getActivity().getResources().getString(R.string.calendar_chooser_date_prompt)); 149 | return; 150 | } 151 | yearMonthDaySelected = new YearMonthDay( 152 | daySelected.day.getYearOfEra(), 153 | daySelected.day.getMonthOfYear(), 154 | daySelected.day.getDayOfMonth() 155 | ); 156 | 157 | if (calendarPickerOnConfirm != null) { 158 | calendarPickerOnConfirm.onComplete(yearMonthDaySelected); 159 | } 160 | 161 | closeFragment(); 162 | 163 | } 164 | }); 165 | 166 | calendar_time_chooser_selected.setOnClickListener(new View.OnClickListener() { 167 | @Override 168 | public void onClick(View v) { 169 | calendar_time_chooser_viewpager.gotoDay(CalendarDay.clone(daySelected)); 170 | } 171 | }); 172 | 173 | calendar_time_chooser_today.setOnClickListener(new View.OnClickListener() { 174 | @Override 175 | public void onClick(View v) { 176 | calendar_time_chooser_viewpager.gotoTodayMonth(); 177 | } 178 | }); 179 | } 180 | 181 | 182 | private void findViews(View v) { 183 | 184 | calendar_time_chooser_mask = (View) v.findViewById(R.id.calendar_time_chooser_mask); 185 | calendar_time_chooser_layout = (LinearLayout) v.findViewById(R.id.calendar_time_chooser_layout); 186 | calendar_time_chooser_title_layout = (LinearLayout) v.findViewById(R.id.calendar_time_chooser_title_layout); 187 | calendar_time_chooser_title = (TextView) v.findViewById(R.id.calendar_time_chooser_title); 188 | calendar_time_chooser_selected = (TextView) v.findViewById(R.id.calendar_time_chooser_selected); 189 | calendar_time_chooser_today = (TextView) v.findViewById(R.id.calendar_time_chooser_today); 190 | calendar_time_chooser_panel_layout = (LinearLayout) v.findViewById(R.id.calendar_time_chooser_panel_layout); 191 | calendar_time_chooser_panel_cancel = (TextView) v.findViewById(R.id.calendar_time_chooser_panel_cancel); 192 | calendar_time_chooser_panel_confirm = (TextView) v.findViewById(R.id.calendar_time_chooser_panel_confirm); 193 | calendar_time_chooser_viewpager_container = (FrameLayout) v.findViewById(R.id.calendar_time_chooser_viewpager_container); 194 | 195 | makeCustoms(); 196 | 197 | calendar_time_chooser_viewpager = new FragmentCalendarViewpager(); 198 | // calendar_time_chooser_blocks_calendar_viewpager.dayInViewPagerOnClickListener = new FragmentCalendarViewpager.DayInViewPagerOnClickListener() { 199 | // @Override 200 | // public void dayOnClicked(CalendarDay calendarDay) { 201 | // daySelected.copy(calendarDay); 202 | // } 203 | // }; 204 | FragmentTransaction ft = getFragmentManager().beginTransaction(); 205 | ft.replace(R.id.calendar_time_chooser_viewpager_container, calendar_time_chooser_viewpager, FRAGMENT_VIEWPAGER_TAG); 206 | // ft.addToBackStack(FRAGMENT_VIEWPAGER_TAG); 207 | ft.commit(); 208 | } 209 | 210 | private void makeCustoms() { 211 | 212 | MyConfig.setTextViewTxt(calendar_time_chooser_title, MyConfig.custom.promptText); 213 | MyConfig.setTextViewSize(calendar_time_chooser_title, MyConfig.custom.promptSize); 214 | MyConfig.setTextViewColor(calendar_time_chooser_title, MyConfig.custom.promptColor); 215 | MyConfig.setLayoutBgColor(calendar_time_chooser_title_layout, MyConfig.custom.promptBgColor); 216 | 217 | MyConfig.setTextViewTxt(calendar_time_chooser_today, MyConfig.custom.todayText); 218 | MyConfig.setTextViewSize(calendar_time_chooser_today, MyConfig.custom.todaySize); 219 | MyConfig.setTextViewColor(calendar_time_chooser_today, MyConfig.custom.todayColor); 220 | MyConfig.setDrawableColor(calendar_time_chooser_today.getBackground(), MyConfig.custom.todayBgColor); 221 | 222 | MyConfig.setTextViewTxt(calendar_time_chooser_selected, MyConfig.custom.selectedText); 223 | MyConfig.setTextViewSize(calendar_time_chooser_selected, MyConfig.custom.selectedSize); 224 | MyConfig.setTextViewColor(calendar_time_chooser_selected, MyConfig.custom.selectedColor); 225 | MyConfig.setDrawableColor(calendar_time_chooser_selected.getBackground(), MyConfig.custom.selectedBgColor); 226 | 227 | MyConfig.setTextViewTxt(calendar_time_chooser_panel_cancel, MyConfig.custom.cancelText); 228 | MyConfig.setTextViewSize(calendar_time_chooser_panel_cancel, MyConfig.custom.cancelSize); 229 | MyConfig.setTextViewColor(calendar_time_chooser_panel_cancel, MyConfig.custom.cancelColor); 230 | MyConfig.setTextViewBgColor(calendar_time_chooser_panel_cancel, MyConfig.custom.cancelBgColor); 231 | 232 | MyConfig.setTextViewTxt(calendar_time_chooser_panel_confirm, MyConfig.custom.confirmText); 233 | MyConfig.setTextViewSize(calendar_time_chooser_panel_confirm, MyConfig.custom.confirmSize); 234 | MyConfig.setTextViewColor(calendar_time_chooser_panel_confirm, MyConfig.custom.confirmColor); 235 | MyConfig.setTextViewBgColor(calendar_time_chooser_panel_confirm, MyConfig.custom.confirmBgColor); 236 | 237 | } 238 | 239 | @Override 240 | public void onResume() { 241 | super.onResume(); 242 | 243 | new Handler().postDelayed(new Runnable() { 244 | @Override 245 | public void run() { 246 | initMonth(); 247 | } 248 | }, 0); 249 | 250 | } 251 | 252 | @Override 253 | public void onDestroyView() { 254 | super.onDestroyView(); 255 | 256 | getActivity().setRequestedOrientation(orientationSaved); 257 | Log.d("", "orientation ---- after restore onDestroyView:" + getActivity().getRequestedOrientation()); 258 | } 259 | 260 | 261 | public void onEventMainThread(EventCalendarSelectDay eventCalendarSelectDay) { 262 | 263 | if (eventCalendarSelectDay != null && eventCalendarSelectDay.calendarDay != null) { 264 | 265 | daySelected = CalendarDay.clone(eventCalendarSelectDay.calendarDay); 266 | 267 | calendar_time_chooser_selected.setVisibility(View.VISIBLE); 268 | 269 | } else { 270 | 271 | } 272 | } 273 | 274 | } 275 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Fragments/FragmentCalendarViewpager.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Fragments; 2 | 3 | import android.app.FragmentManager; 4 | import android.os.Bundle; 5 | import android.support.v4.view.ViewPager; 6 | import android.util.Log; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import org.joda.time.LocalDate; 12 | 13 | import android.support.v13.app.FragmentStatePagerAdapter; 14 | 15 | 16 | import com.maxproj.calendarpicker.Models.CalendarDay; 17 | import com.maxproj.calendarpicker.Models.EventCalendarSelectDay; 18 | import com.maxproj.calendarpicker.R; 19 | 20 | 21 | public class FragmentCalendarViewpager extends FragmentBase { 22 | 23 | ViewPager viewPager; 24 | MonthPagerAdapter monthPagerAdapter; 25 | CalendarDay daySelected = new CalendarDay(null); 26 | 27 | public void onEventMainThread(EventCalendarSelectDay eventCalendarSelectDay) { 28 | 29 | if (eventCalendarSelectDay != null && eventCalendarSelectDay.calendarDay != null) { 30 | daySelected.copy(eventCalendarSelectDay.calendarDay); 31 | } else { 32 | daySelected.copy(null); 33 | } 34 | 35 | } 36 | 37 | public interface DayInViewPagerOnClickListener { 38 | void dayOnClicked(CalendarDay calendarDay); 39 | } 40 | 41 | public DayInViewPagerOnClickListener dayInViewPagerOnClickListener; 42 | 43 | public void setDayClickListener(DayInViewPagerOnClickListener dayInViewPagerOnClickListener) { 44 | this.dayInViewPagerOnClickListener = dayInViewPagerOnClickListener; 45 | } 46 | 47 | public void setSelectedDay(CalendarDay day) { 48 | 49 | daySelected.copy(day); 50 | } 51 | 52 | public void gotoTodayMonth() { 53 | 54 | viewPager.setCurrentItem(MonthPagerAdapter.CURRENT_MONTH_IN_SCROLL); 55 | } 56 | 57 | public void gotoDay(CalendarDay calendarDay) { 58 | if (calendarDay == null || calendarDay.day == null) { 59 | return; 60 | } 61 | 62 | LocalDate today = new LocalDate(); 63 | 64 | viewPager.setCurrentItem((calendarDay.day.getYear() * 12 + calendarDay.day.getMonthOfYear()) 65 | - (today.getYear() * 12 + today.getMonthOfYear()) 66 | + MonthPagerAdapter.CURRENT_MONTH_IN_SCROLL); 67 | 68 | } 69 | 70 | public void gotoSelectedDay() { 71 | if (daySelected == null || daySelected.day == null) { 72 | return; 73 | } 74 | 75 | LocalDate today = new LocalDate(); 76 | viewPager.setCurrentItem((daySelected.day.getYear() * 12 + daySelected.day.getMonthOfYear()) 77 | - (today.getYear() * 12 + today.getMonthOfYear()) 78 | + MonthPagerAdapter.CURRENT_MONTH_IN_SCROLL); 79 | } 80 | 81 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 82 | 83 | Log.d("", "FragmentCalendarChooserDialog: FragmentCalendarViewpager.onCreateView"); 84 | View v = inflater.inflate(R.layout.com_maxproj_calendarpicker_fragment_calendar_viewpager, null); 85 | 86 | viewPager = (ViewPager) v.findViewById(R.id.calendar_viewpager); 87 | monthPagerAdapter = new MonthPagerAdapter(getFragmentManager()); 88 | viewPager.setAdapter(monthPagerAdapter); 89 | viewPager.setCurrentItem(MonthPagerAdapter.CURRENT_MONTH_IN_SCROLL); 90 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 91 | @Override 92 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 93 | 94 | } 95 | 96 | @Override 97 | public void onPageSelected(int position) { 98 | 99 | } 100 | 101 | @Override 102 | public void onPageScrollStateChanged(int state) { 103 | 104 | } 105 | }); 106 | 107 | return v; 108 | } 109 | 110 | 111 | @Override 112 | public void onDestroy() { 113 | super.onDestroy(); 114 | } 115 | 116 | @Override 117 | public void onResume() { 118 | super.onResume(); 119 | } 120 | 121 | 122 | public static FragmentCalendarViewpager newInstance() { 123 | FragmentCalendarViewpager f = new FragmentCalendarViewpager(); 124 | 125 | return f; 126 | } 127 | 128 | public class MonthPagerAdapter extends FragmentStatePagerAdapter { 129 | 130 | /** 131 | * 从当前月开始,往前可以抹动1000个月,往后可以抹动1000个月 132 | */ 133 | public final static int PREVIOUS_MONTH_CAN_SCROLL = 1000; 134 | public final static int CURRENT_MONTH_IN_SCROLL = PREVIOUS_MONTH_CAN_SCROLL + 1; 135 | public final static int AFTER_MONTH_CAN_SCROLL = 1000; 136 | 137 | public MonthPagerAdapter(FragmentManager fm) { 138 | super(fm); 139 | } 140 | 141 | @Override 142 | public FragmentCalendarMonthBase getItem(int position) { 143 | 144 | FragmentCalendarMonthBase fragmentCalendarMonthBase = FragmentCalendarMonthBase.newInstance(new LocalDate().plusMonths(position - CURRENT_MONTH_IN_SCROLL), 145 | daySelected, 146 | new FragmentCalendarMonthBase.DayInMonthOnClickListener() {//尽量不用监听器,麻烦且容易遗漏 147 | @Override 148 | public void dayOnClicked(CalendarDay calendarDay) { 149 | if (dayInViewPagerOnClickListener != null) { 150 | dayInViewPagerOnClickListener.dayOnClicked(calendarDay); 151 | } 152 | } 153 | } 154 | ); 155 | return fragmentCalendarMonthBase; 156 | } 157 | 158 | @Override 159 | public int getCount() { 160 | return PREVIOUS_MONTH_CAN_SCROLL + 1 + AFTER_MONTH_CAN_SCROLL; 161 | } 162 | 163 | @Override 164 | public CharSequence getPageTitle(int position) { 165 | return "" + position; 166 | } 167 | } 168 | 169 | public void closeFragment() { 170 | getActivity().getFragmentManager().beginTransaction().remove(FragmentCalendarViewpager.this).commit(); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import com.maxproj.calendarpicker.Config.MyConfig; 10 | import com.maxproj.calendarpicker.Models.YearMonthDay; 11 | 12 | public class MainActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.com_maxproj_calendarpicker_activity_main); 18 | 19 | 20 | Button button_open = (Button) findViewById(R.id.button_open); 21 | button_open.setOnClickListener(new View.OnClickListener() { 22 | @Override 23 | public void onClick(View v) { 24 | Builder builder = new Builder(MainActivity.this, new Builder.CalendarPickerOnConfirm() { 25 | @Override 26 | public void onComplete(YearMonthDay yearMonthDay) { 27 | MyConfig.uiToast("You pick "+yearMonthDay.year+"-"+yearMonthDay.month+"-"+yearMonthDay.day); 28 | } 29 | }) 30 | .restoreDefault(); 31 | builder.show(); 32 | } 33 | }); 34 | 35 | Button button_preset = (Button) findViewById(R.id.button_preset); 36 | button_preset.setOnClickListener(new View.OnClickListener() { 37 | @Override 38 | public void onClick(View v) { 39 | 40 | Builder builder = new Builder(MainActivity.this, new Builder.CalendarPickerOnConfirm() { 41 | @Override 42 | public void onComplete(YearMonthDay yearMonthDay) { 43 | MyConfig.uiToast("You pick "+yearMonthDay.year+"-"+yearMonthDay.month+"-"+yearMonthDay.day); 44 | } 45 | }) 46 | .setPromptText("请选择日期") 47 | .setPromptSize(18) 48 | .setPromptColor(Color.RED) 49 | .setPromptBgColor(Color.YELLOW) 50 | 51 | .setSelectedText("已选") 52 | .setSelectedSize(16) 53 | .setSelectedColor(0xFF330DCE) 54 | .setSelectedBgColor(0xFF1E90FF) 55 | 56 | .setTodayText("今天") 57 | .setTodaySize(12) 58 | .setTodayColor(Color.RED) 59 | .setTodayBgColor(Color.GREEN) 60 | 61 | .setMonthTitle(new Builder.FormatMonthTitle() { 62 | @Override 63 | public String setMonthTitle(int year, int month) { 64 | return ""+year+"年"+month+"月"; 65 | } 66 | }) 67 | .setMonthTitleSize(16) 68 | .setMonthTitleColor(0xFFB22222) 69 | .setMonthTitleBgColor(0xFF93D353) 70 | 71 | .setWeekIndex(new String[]{"一", "二", "三", "四", "五", "六", "日"}) 72 | .setWeekIndexSize(16) 73 | .setWeekIndexColor(0xFFFF00FF) 74 | .setWeekIndexBgColor(0xFFADD8E6) 75 | 76 | .setCancelText("取消") 77 | .setCancelSize(12) 78 | .setCancelColor(Color.LTGRAY) 79 | .setCancelBgColor(0xFFA079BE) 80 | 81 | .setConfirmText("确定") 82 | .setConfirmSize(16) 83 | .setConfirmColor(Color.RED) 84 | .setConfirmBgColor(Color.GREEN) 85 | 86 | .setPreset(new YearMonthDay(2017, 11, 4)) 87 | .setDaySize(16) 88 | .setDayColor(Color.BLUE) 89 | .setDayOtherMonthColor(0xFF87CEFA) 90 | .setMonthBaseBgColor(0xFFE0FFFF) 91 | 92 | .setJump2Preset(true) 93 | // .restoreDefault() 94 | ; 95 | 96 | builder.show(); 97 | 98 | } 99 | }); 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Models/CalendarDay.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Models; 2 | 3 | import android.util.Log; 4 | 5 | import org.joda.time.LocalDate; 6 | 7 | 8 | 9 | 10 | public class CalendarDay { 11 | 12 | public org.joda.time.LocalDate day; 13 | public boolean have_activity = false; 14 | 15 | public CalendarDay(org.joda.time.LocalDate day, boolean have_activity) { 16 | this.day = day; 17 | this.have_activity = have_activity; 18 | } 19 | 20 | public CalendarDay(org.joda.time.LocalDate day) { 21 | 22 | this.day = day; 23 | this.have_activity = false; 24 | } 25 | 26 | public CalendarDay() { 27 | 28 | this.day = null; 29 | this.have_activity = false; 30 | } 31 | 32 | public CalendarDay(int year, int month, int day) { 33 | 34 | this.day = new LocalDate(year, month,day); 35 | this.have_activity = false; 36 | } 37 | 38 | public void copy(CalendarDay calendarDay){ 39 | 40 | if(calendarDay == null){ 41 | Log.d("","EventCalendarSelectDay: CalendarDay copy null "); 42 | this.day = null; 43 | this.have_activity = false; 44 | return; 45 | } 46 | 47 | if(calendarDay.day == null){ 48 | Log.d("", "EventCalendarSelectDay: CalendarDay copy null 2"); 49 | }else { 50 | Log.d("", "EventCalendarSelectDay: CalendarDay copy: " + calendarDay.day.toString()); 51 | } 52 | this.day = calendarDay.day; 53 | this.have_activity = calendarDay.have_activity; 54 | } 55 | 56 | public static CalendarDay clone(CalendarDay calendarDay){ 57 | 58 | //即便源是null,也clone一份实体,只是实体内容为未初始化 59 | CalendarDay calendarDay_clone = new CalendarDay(); 60 | calendarDay_clone.copy(calendarDay); 61 | return calendarDay_clone; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Models/CalendarMonth.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Models; 2 | 3 | import org.joda.time.LocalDate; 4 | 5 | import java.util.LinkedList; 6 | 7 | 8 | public class CalendarMonth { 9 | 10 | public LocalDate firstDayOfCurrentMonth; 11 | public LocalDate originDate; 12 | public LinkedList calendarWeeks = new LinkedList<>(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Models/CalendarWeek.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Models; 2 | 3 | import org.joda.time.LocalDate; 4 | 5 | import java.util.LinkedList; 6 | 7 | 8 | public class CalendarWeek { 9 | /** 10 | * 注意,week和年月日是不同的体系,往往跨越年和月,所以定义特殊 11 | * 上个月的最后一周和本月的第一周可能是一样的 12 | * 我们需要的是,根据月的第一天得到本月所有的week 13 | */ 14 | public LocalDate firstDayOfCurrentMonth; 15 | public LocalDate originDate; 16 | public LinkedList calendarDayList = new LinkedList<>(); 17 | 18 | public CalendarWeek(LinkedList calendarDayList){ 19 | this.calendarDayList = calendarDayList; 20 | } 21 | 22 | public CalendarWeek( 23 | LocalDate d1, 24 | LocalDate d2, 25 | LocalDate d3, 26 | LocalDate d4, 27 | LocalDate d5, 28 | LocalDate d6, 29 | LocalDate d7 30 | ){ 31 | calendarDayList.clear(); 32 | 33 | // calendarDayList.add(new CalendarDay(d1, false)); 34 | // calendarDayList.add(new CalendarDay(d2, false)); 35 | // calendarDayList.add(new CalendarDay(d3, false)); 36 | // calendarDayList.add(new CalendarDay(d4, false)); 37 | // calendarDayList.add(new CalendarDay(d5, false)); 38 | // calendarDayList.add(new CalendarDay(d6, false)); 39 | // calendarDayList.add(new CalendarDay(d7, false)); 40 | 41 | 42 | calendarDayList.add(new CalendarDay(d1)); 43 | calendarDayList.add(new CalendarDay(d2)); 44 | calendarDayList.add(new CalendarDay(d3)); 45 | calendarDayList.add(new CalendarDay(d4)); 46 | calendarDayList.add(new CalendarDay(d5)); 47 | calendarDayList.add(new CalendarDay(d6)); 48 | calendarDayList.add(new CalendarDay(d7)); 49 | } 50 | 51 | public CalendarWeek( 52 | CalendarDay d1, 53 | CalendarDay d2, 54 | CalendarDay d3, 55 | CalendarDay d4, 56 | CalendarDay d5, 57 | CalendarDay d6, 58 | CalendarDay d7 59 | ){ 60 | 61 | calendarDayList.clear(); 62 | calendarDayList.add(d1); 63 | calendarDayList.add(d2); 64 | calendarDayList.add(d3); 65 | calendarDayList.add(d4); 66 | calendarDayList.add(d5); 67 | calendarDayList.add(d6); 68 | calendarDayList.add(d7); 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Models/Custom.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Models; 2 | 3 | import com.maxproj.calendarpicker.Builder; 4 | 5 | /** 6 | * Created by youhy on 17/12/11. 7 | */ 8 | 9 | public class Custom { 10 | 11 | /** 12 | * Calendar Prompt部分 13 | */ 14 | public String promptText = "Please Pick a Day"; 15 | public Integer promptSize = 18; 16 | public Integer promptColor = 0xFF696969; 17 | public Integer promptBgColor = 0xFFFFFFFF; 18 | 19 | public String todayText = "Today"; 20 | public Integer todaySize = 12; 21 | public Integer todayColor = 0xFFFFFFFF;; 22 | public Integer todayBgColor = 0xFF1E90FF; 23 | 24 | public String selectedText = "Selected"; 25 | public Integer selectedSize = 12; 26 | public Integer selectedColor = 0xFFFFFFFF; 27 | public Integer selectedBgColor = 0xFF00BF00; 28 | 29 | /** 30 | * Month Title部分 31 | */ 32 | public Builder.FormatMonthTitle formatMonthTitle; 33 | // public String yearMonth; 34 | public Integer monthTitleSize = 18; 35 | public Integer monthTitleColor = 0xFF696969; 36 | public Integer monthTitleBgColor = 0x00000000; 37 | 38 | /** 39 | * Week Index部分 40 | */ 41 | public String weekIndex[] = new String[]{"M", "T", "W", "T", "F", "S", "S"}; 42 | public Integer weekIndexSize = 15; 43 | public Integer weekIndexColor = 0xFFD2691E; 44 | public Integer weekIndexBgColor = 0x00000000; 45 | 46 | 47 | /** 48 | * Day部分 49 | */ 50 | public YearMonthDay preset; 51 | 52 | public Integer daySize = 14; 53 | public Integer daySelectedSize = 16; 54 | public Integer dayTodaySize = 16; 55 | public Integer dayColor = 0xFF696969; 56 | // public Integer dayBgColor; 57 | public Integer dayOtherMonthColor = 0xFFD3D3D3; 58 | // public Integer dayOtherMonthBgColor; 59 | public Integer monthBaseBgColor = 0xFFFFEBCD; 60 | 61 | /** 62 | * Confirm部分 63 | */ 64 | public String cancelText = "Cancel"; 65 | public Integer cancelSize = 16; 66 | public Integer cancelColor = 0xFF696969;; 67 | public Integer cancelBgColor = 0xFFFFFFFF; 68 | public String confirmText = "Confirm"; 69 | public Integer confirmSize = 16; 70 | public Integer confirmColor = 0xFF696969; 71 | public Integer confirmBgColor = 0xFFFFFFFF; 72 | 73 | 74 | /** 75 | * jump to preset if have 76 | */ 77 | public boolean jump2Preset = true; 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Models/EventCalendarSelectDay.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Models; 2 | 3 | 4 | public class EventCalendarSelectDay { 5 | 6 | public CalendarDay calendarDay; 7 | 8 | public EventCalendarSelectDay(CalendarDay calendarDay){ 9 | 10 | this.calendarDay = calendarDay; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Models/YearMonthDay.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Models; 2 | 3 | 4 | 5 | public class YearMonthDay { 6 | 7 | public int year; 8 | public int month; 9 | public int day; 10 | 11 | public YearMonthDay(int year, int month, int day){ 12 | this.day = day; 13 | this.month = month; 14 | this.year = year; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Views/ViewCalendarDayWithActivity.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Views; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.util.AttributeSet; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.widget.ImageView; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | 12 | import com.maxproj.calendarpicker.Config.MyConfig; 13 | import com.maxproj.calendarpicker.Models.CalendarDay; 14 | import com.maxproj.calendarpicker.R; 15 | 16 | import org.joda.time.LocalDate; 17 | 18 | 19 | 20 | 21 | public class ViewCalendarDayWithActivity extends LinearLayout { 22 | 23 | CalendarDay mCalendarDay; 24 | 25 | public LinearLayout calendar_day_layout; 26 | public ImageView calendar_day_have_activity; 27 | public TextView calendar_day_in_month; 28 | 29 | 30 | public ViewCalendarDayWithActivity(Context context, AttributeSet attrs) { 31 | super(context, attrs); 32 | inflate(context); 33 | } 34 | 35 | public ViewCalendarDayWithActivity(Context context) { 36 | super(context); 37 | inflate(context); 38 | } 39 | 40 | private void inflate(Context context) { 41 | LayoutInflater inflater = LayoutInflater.from(context); 42 | View v = inflater.inflate(R.layout.com_maxproj_calendarpicker_calendar_day_with_activity, this, true); 43 | 44 | calendar_day_layout = (LinearLayout)v.findViewById(R.id.calendar_day_layout); 45 | calendar_day_have_activity = (ImageView) v.findViewById(R.id.calendar_day_have_activity); 46 | calendar_day_in_month = (TextView) v.findViewById(R.id.calendar_day_in_month); 47 | } 48 | 49 | public interface DayOnClickListener { 50 | void dayOnClicked(CalendarDay day); 51 | } 52 | public DayOnClickListener mDayOnClickListener; 53 | 54 | 55 | public void setViewCalendarDay(CalendarDay calendarDay, int highLightMonth, CalendarDay highLightDay, DayOnClickListener dayOnClickListener){ 56 | this.mCalendarDay = calendarDay; 57 | this.mDayOnClickListener = dayOnClickListener; 58 | 59 | // if(calendarDay == null){ 60 | // Log.d("","EventCalendarSelectDay: ViewCalendarDayWithActivity calendarDay == null"); 61 | // }else if(calendarDay.day == null){ 62 | // Log.d("","EventCalendarSelectDay: ViewCalendarDayWithActivity calendarDay.day == null"); 63 | // }else{ 64 | // Log.d("","EventCalendarSelectDay: ViewCalendarDayWithActivity calendarDay.day " + calendarDay.day.toString()); 65 | // } 66 | calendar_day_in_month.setText(""+calendarDay.day.getDayOfMonth()); 67 | 68 | if(calendarDay.have_activity){ 69 | calendar_day_have_activity.setVisibility(VISIBLE); 70 | }else{ 71 | calendar_day_have_activity.setVisibility(GONE); 72 | } 73 | 74 | 75 | 76 | if(highLightDay != null && calendarDay.day.equals(highLightDay.day)){ 77 | 78 | /** 79 | * 被选择 80 | */ 81 | 82 | MyConfig.setTextViewSize(calendar_day_in_month, MyConfig.custom.daySelectedSize); 83 | 84 | MyConfig.setTextViewColor(calendar_day_in_month, MyConfig.custom.selectedColor); 85 | 86 | calendar_day_layout.setBackground(getResources().getDrawable(R.drawable.com_maxproj_calendarpicker_calendar_selected_circle)); 87 | MyConfig.setDrawableColor(calendar_day_layout.getBackground(), MyConfig.custom.selectedBgColor); 88 | 89 | }else if(calendarDay.day.equals(new LocalDate())){ 90 | 91 | /** 92 | * 今天 93 | */ 94 | 95 | MyConfig.setTextViewSize(calendar_day_in_month, MyConfig.custom.dayTodaySize); 96 | 97 | MyConfig.setTextViewColor(calendar_day_in_month, MyConfig.custom.todayColor); 98 | 99 | calendar_day_layout.setBackground(getResources().getDrawable(R.drawable.com_maxproj_calendarpicker_calendar_today_circle)); 100 | MyConfig.setDrawableColor(calendar_day_layout.getBackground(), MyConfig.custom.todayBgColor); 101 | 102 | }else{ 103 | 104 | /** 105 | * 普通日 106 | */ 107 | 108 | MyConfig.setTextViewSize(calendar_day_in_month, MyConfig.custom.daySize); 109 | 110 | calendar_day_layout.setBackgroundColor(Color.TRANSPARENT); 111 | 112 | MyConfig.setTextViewSize(calendar_day_in_month, MyConfig.custom.daySize); 113 | 114 | if(calendarDay.day.getMonthOfYear() == highLightMonth){//当月 115 | MyConfig.setTextViewColor(calendar_day_in_month, MyConfig.custom.dayColor); 116 | }else{//前后月 117 | MyConfig.setTextViewColor(calendar_day_in_month, MyConfig.custom.dayOtherMonthColor); 118 | } 119 | } 120 | 121 | this.setOnClickListener(new OnClickListener() { 122 | @Override 123 | public void onClick(View v) { 124 | if(mDayOnClickListener != null){ 125 | mDayOnClickListener.dayOnClicked(CalendarDay.clone(mCalendarDay)); 126 | } 127 | } 128 | }); 129 | 130 | } 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /app/src/main/java/com/maxproj/calendarpicker/Views/ViewCalendarWeekWithActivity.java: -------------------------------------------------------------------------------- 1 | package com.maxproj.calendarpicker.Views; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.widget.LinearLayout; 8 | 9 | import com.maxproj.calendarpicker.Models.CalendarDay; 10 | import com.maxproj.calendarpicker.Models.CalendarWeek; 11 | import com.maxproj.calendarpicker.R; 12 | 13 | public class ViewCalendarWeekWithActivity extends LinearLayout { 14 | 15 | CalendarWeek calendarWeek; 16 | 17 | public LinearLayout calendar_week_day_layout; 18 | public ViewCalendarDayWithActivity calendar_day1; 19 | public ViewCalendarDayWithActivity calendar_day2; 20 | public ViewCalendarDayWithActivity calendar_day3; 21 | public ViewCalendarDayWithActivity calendar_day4; 22 | public ViewCalendarDayWithActivity calendar_day5; 23 | public ViewCalendarDayWithActivity calendar_day6; 24 | public ViewCalendarDayWithActivity calendar_day7; 25 | 26 | 27 | public interface DayInWeekOnClickListener { 28 | void dayOnClicked(CalendarDay day); //1~7 29 | } 30 | public DayInWeekOnClickListener dayInWeekOnClickListener;//以后不再使用这个监听器,而是透传dayOnClickListener 31 | 32 | 33 | public ViewCalendarWeekWithActivity(Context context, AttributeSet attrs) { 34 | super(context, attrs); 35 | 36 | inflate(context); 37 | } 38 | 39 | public ViewCalendarWeekWithActivity(Context context) { 40 | 41 | super(context); 42 | 43 | inflate(context); 44 | 45 | } 46 | 47 | 48 | private void inflate(Context context) { 49 | LayoutInflater inflater = LayoutInflater.from(context); 50 | View v = inflater.inflate(R.layout.com_maxproj_calendarpicker_calendar_week_with_activity, this, true); 51 | 52 | calendar_week_day_layout = (LinearLayout)v.findViewById(R.id.calendar_week_day_layout); 53 | 54 | calendar_day1 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day1); 55 | calendar_day2 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day2); 56 | calendar_day3 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day3); 57 | calendar_day4 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day4); 58 | calendar_day5 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day5); 59 | calendar_day6 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day6); 60 | calendar_day7 = (ViewCalendarDayWithActivity) v.findViewById(R.id.calendar_day7); 61 | 62 | } 63 | 64 | 65 | public void setViewCalendarWeek(CalendarWeek calendarWeek, int highLightMonth){ 66 | 67 | writeViewCalendarWeek(calendarWeek, highLightMonth, null, null); 68 | } 69 | 70 | public void setViewCalendarWeek(CalendarWeek calendarWeek, int highLightMonth, CalendarDay calendarDay, ViewCalendarDayWithActivity.DayOnClickListener dayOnClickListener){ 71 | 72 | writeViewCalendarWeek(calendarWeek, highLightMonth, calendarDay, dayOnClickListener); 73 | } 74 | 75 | private void writeViewCalendarWeek(CalendarWeek calendarWeek, int highLightMonth, CalendarDay calendarDay, ViewCalendarDayWithActivity.DayOnClickListener dayOnClickListener) { 76 | if(calendarWeek == null){ 77 | calendar_week_day_layout.setVisibility(INVISIBLE); 78 | return; 79 | } 80 | calendar_week_day_layout.setVisibility(VISIBLE); 81 | 82 | this.calendarWeek = calendarWeek; 83 | 84 | calendar_day1.setViewCalendarDay(calendarWeek.calendarDayList.get(0), highLightMonth, calendarDay, dayOnClickListener); 85 | calendar_day2.setViewCalendarDay(calendarWeek.calendarDayList.get(1), highLightMonth, calendarDay, dayOnClickListener); 86 | calendar_day3.setViewCalendarDay(calendarWeek.calendarDayList.get(2), highLightMonth, calendarDay, dayOnClickListener); 87 | calendar_day4.setViewCalendarDay(calendarWeek.calendarDayList.get(3), highLightMonth, calendarDay, dayOnClickListener); 88 | calendar_day5.setViewCalendarDay(calendarWeek.calendarDayList.get(4), highLightMonth, calendarDay, dayOnClickListener); 89 | calendar_day6.setViewCalendarDay(calendarWeek.calendarDayList.get(5), highLightMonth, calendarDay, dayOnClickListener); 90 | calendar_day7.setViewCalendarDay(calendarWeek.calendarDayList.get(6), highLightMonth, calendarDay, dayOnClickListener); 91 | 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/com_maxproj_calendarpicker_audio_unread_dot_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxyou/CalendarPicker/4dc848c43da03b05c7a1463655722eed6fdc124a/app/src/main/res/drawable/com_maxproj_calendarpicker_audio_unread_dot_3x.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/com_maxproj_calendarpicker_calendar_selected_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/com_maxproj_calendarpicker_calendar_today_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/com_maxproj_calendarpicker_shape_button_bg_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/com_maxproj_calendarpicker_shape_button_bg_today.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/com_maxproj_calendarpicker_activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |