├── MyCalendar
├── .idea
│ ├── .name
│ ├── copyright
│ │ └── profiles_settings.xml
│ ├── encodings.xml
│ ├── modules.xml
│ ├── runConfigurations.xml
│ ├── compiler.xml
│ ├── gradle.xml
│ └── misc.xml
├── app
│ ├── .gitignore
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── drawable
│ │ │ │ │ ├── no_data.png
│ │ │ │ │ ├── calendar_background.png
│ │ │ │ │ ├── calendar_item_point.xml
│ │ │ │ │ ├── bottom_gray.xml
│ │ │ │ │ ├── yuan.xml
│ │ │ │ │ └── white.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── layout
│ │ │ │ │ ├── my_calender_title.xml
│ │ │ │ │ ├── content_main.xml
│ │ │ │ │ ├── mouth.xml
│ │ │ │ │ ├── week.xml
│ │ │ │ │ ├── activity_main.xml
│ │ │ │ │ ├── day_of_week.xml
│ │ │ │ │ ├── fragment_my_calender.xml
│ │ │ │ │ └── calender_week_layout.xml
│ │ │ │ ├── values-v21
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-w820dp
│ │ │ │ │ └── dimens.xml
│ │ │ │ ├── menu
│ │ │ │ │ └── menu_main.xml
│ │ │ │ ├── values
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ └── anim
│ │ │ │ │ └── soufang.xml
│ │ │ ├── java
│ │ │ │ └── choosetime
│ │ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── chen
│ │ │ │ │ └── mycalendar
│ │ │ │ │ ├── calendar
│ │ │ │ │ ├── abs
│ │ │ │ │ │ └── RefreshListener.java
│ │ │ │ │ ├── adpter
│ │ │ │ │ │ ├── CalendarBaseAdpter.java
│ │ │ │ │ │ ├── WeekCalendarAdpter.java
│ │ │ │ │ │ └── MonthCalendarAdpter.java
│ │ │ │ │ ├── utils
│ │ │ │ │ │ ├── MomentsUtils.java
│ │ │ │ │ │ └── DateUtils.java
│ │ │ │ │ ├── fragment
│ │ │ │ │ │ ├── widget
│ │ │ │ │ │ │ ├── HasTwoAdapterViewpager.java
│ │ │ │ │ │ │ └── HandMoveLayout.java
│ │ │ │ │ │ └── MyCalendarFragment.java
│ │ │ │ │ └── CalendarUtil.java
│ │ │ │ │ └── MainActivity.java
│ │ │ └── AndroidManifest.xml
│ │ ├── test
│ │ │ └── java
│ │ │ │ └── choosetime
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── chen
│ │ │ │ └── mycalendar
│ │ │ │ └── ExampleUnitTest.java
│ │ └── androidTest
│ │ │ └── java
│ │ │ └── choosetime
│ │ │ └── com
│ │ │ └── example
│ │ │ └── chen
│ │ │ └── mycalendar
│ │ │ └── ApplicationTest.java
│ ├── proguard-rules.pro
│ └── build.gradle
├── settings.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── .gitignore
├── build.gradle
├── gradle.properties
├── gradlew.bat
└── gradlew
├── calendar.gif
└── README.md
/MyCalendar/.idea/.name:
--------------------------------------------------------------------------------
1 | MyCalendar
--------------------------------------------------------------------------------
/MyCalendar/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/MyCalendar/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/calendar.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/calendar.gif
--------------------------------------------------------------------------------
/MyCalendar/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/MyCalendar/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/drawable/no_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/drawable/no_data.png
--------------------------------------------------------------------------------
/MyCalendar/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/drawable/calendar_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguozhi/calendar/HEAD/MyCalendar/app/src/main/res/drawable/calendar_background.png
--------------------------------------------------------------------------------
/MyCalendar/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #android-calendar
2 | 仿小米日历,支持周视图 月视图
3 | 按周平滑滑动,按月平滑滑动,支持农历公历显示等[我的哥,用了代码的顺便给个星星好不好]
4 | 效果图如下
5 |
6 | 
7 | 有小伙伴新写的demo,比这个好用,大家去copy这个吧;
8 | https://github.com/xiaojianglaile/Calendar
9 |
--------------------------------------------------------------------------------
/MyCalendar/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
7 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/drawable/calendar_item_point.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/abs/RefreshListener.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.abs;
2 |
3 | import android.support.v4.view.ViewPager;
4 |
5 | /**
6 | * Created by Administrator on 2016/6/15 0015.
7 | */
8 | public interface RefreshListener {
9 | public void refreshListener(ViewPager viewPager);
10 | }
11 |
--------------------------------------------------------------------------------
/MyCalendar/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/my_calender_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/drawable/bottom_gray.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/test/java/choosetime/com/example/chen/mycalendar/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/drawable/yuan.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
12 |
14 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/androidTest/java/choosetime/com/example/chen/mycalendar/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 14sp
7 | 50dp
8 | 20sp
9 | 50dp
10 |
11 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/drawable/white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
12 |
13 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MyCalendar
3 | Settings
4 | 三
5 | 今天
6 | 六
7 | 五
8 | 四
9 | 二
10 | 一
11 | 访问失败
12 |
13 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/anim/soufang.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/mouth.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/MyCalendar/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/MyCalendar/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #FF000000
8 | #848484
9 | #ffaaaaaa
10 | #ffffffff
11 | #ffff0101
12 | #EBEBEB
13 | #666667
14 | #9a9a9a
15 |
16 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/week.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/MyCalendar/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 E:\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 |
--------------------------------------------------------------------------------
/MyCalendar/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/MyCalendar/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MyCalendar/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | applicationId "choosetime.com.example.chen.mycalendar"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.4.0'
26 | compile 'com.android.support:design:23.4.0'
27 | }
28 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/adpter/CalendarBaseAdpter.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.adpter;
2 |
3 | import android.support.v4.view.PagerAdapter;
4 | import android.view.View;
5 |
6 | /**
7 | * Created by Administrator on 2016/6/13 0013.
8 | */
9 | public class CalendarBaseAdpter extends PagerAdapter {
10 |
11 | /**
12 | * 选中时间:xx-xx-xx
13 | * */
14 | public static String selectTime = "";
15 | /**
16 | * 是否拦截事件
17 | * */
18 | public static boolean is=false;
19 |
20 | public static boolean is() {
21 | return is;
22 | }
23 |
24 | @Override
25 | public int getCount() {//无所谓
26 | return 0;
27 | }
28 |
29 | @Override
30 | public boolean isViewFromObject(View view, Object object) {//无所谓
31 | return false;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/MyCalendar/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/utils/MomentsUtils.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.utils;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | /**
8 | * Created by qhdhiman on 2015/3/18.
9 | *
10 | */
11 | public class MomentsUtils {
12 | private static final String TAG = "MomentsUtils";
13 | /**
14 | * 取得特定ID的父VIew对象
15 | * @param resourceId 引用ID
16 | * @param child 当前View对象
17 | * @return 取得特定ID的父VIew对象
18 | */
19 | public static View getParent(int resourceId, View child) {
20 | if (child == null) {
21 | return null;
22 | }
23 |
24 | if (child.getId() == resourceId) {
25 | return child;
26 | } else {
27 | return getParent(resourceId, (ViewGroup)child.getParent());
28 | }
29 | }
30 |
31 |
32 | /**
33 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
34 | */
35 | public static int dip2px(Context context, float dpValue) {
36 | final float scale = context.getResources().getDisplayMetrics().density;
37 | return (int) (dpValue * scale + 0.5f);
38 | }
39 |
40 | /**
41 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
42 | */
43 | public static int px2dip(Context context, float pxValue) {
44 | final float scale = context.getResources().getDisplayMetrics().density;
45 | return (int) (pxValue / scale + 0.5f);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/day_of_week.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
30 |
31 |
39 |
40 |
47 |
48 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/MainActivity.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.Message;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.Toolbar;
8 | import android.view.Menu;
9 | import android.view.MenuItem;
10 |
11 | import choosetime.com.example.chen.mycalendar.calendar.fragment.MyCalendarFragment;
12 |
13 | public class MainActivity extends AppCompatActivity {
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_main);
19 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
20 | setSupportActionBar(toolbar);
21 |
22 |
23 | MyCalendarFragment myCalenderFragment=new MyCalendarFragment(new Handler(){
24 | @Override
25 | public void handleMessage(Message msg) {
26 | super.handleMessage(msg);
27 | }
28 | });
29 | //re_cotent
30 | getSupportFragmentManager().beginTransaction().add(R.id.re_cotent, myCalenderFragment)
31 | .show(myCalenderFragment).commit();
32 | }
33 |
34 | @Override
35 | public boolean onCreateOptionsMenu(Menu menu) {
36 | // Inflate the menu; this adds items to the action bar if it is present.
37 | getMenuInflater().inflate(R.menu.menu_main, menu);
38 | return true;
39 | }
40 |
41 | @Override
42 | public boolean onOptionsItemSelected(MenuItem item) {
43 | // Handle action bar item clicks here. The action bar will
44 | // automatically handle clicks on the Home/Up button, so long
45 | // as you specify a parent activity in AndroidManifest.xml.
46 | int id = item.getItemId();
47 |
48 | //noinspection SimplifiableIfStatement
49 | if (id == R.id.action_settings) {
50 | return true;
51 | }
52 |
53 | return super.onOptionsItemSelected(item);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/MyCalendar/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/MyCalendar/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
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 | 1.7
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/fragment/widget/HasTwoAdapterViewpager.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.fragment.widget;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.ViewPager;
5 | import android.util.AttributeSet;
6 | import android.view.animation.Interpolator;
7 | import android.widget.Scroller;
8 |
9 | import java.lang.reflect.Field;
10 |
11 | import choosetime.com.example.chen.mycalendar.calendar.abs.RefreshListener;
12 |
13 | /**
14 | * Created by Administrator on 2016/6/13 0013.
15 | */
16 | public class HasTwoAdapterViewpager extends ViewPager {
17 | public HasTwoAdapterViewpager(Context context) {
18 | super(context);
19 | // setViewPagerScrollSpeed( );
20 | }
21 |
22 | public HasTwoAdapterViewpager(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | // setViewPagerScrollSpeed( );
25 | }
26 |
27 | private RefreshListener listener;
28 |
29 | public void setListener(RefreshListener listener) {
30 | this.listener = listener;
31 | }
32 |
33 | @Override
34 | public void setVisibility(int visibility) {
35 | super.setVisibility(visibility);
36 | //刷新,滚动到相应的位置
37 | if (visibility==VISIBLE){//在viewpager显示前,刷新
38 | if (listener!=null){
39 | listener.refreshListener(HasTwoAdapterViewpager.this);
40 | }
41 | }
42 | }
43 | /**
44 | * 设置ViewPager的滑动速度
45 | *
46 | * */
47 | private void setViewPagerScrollSpeed( ){
48 | try {
49 | Field mScroller = null;
50 | mScroller = ViewPager.class.getDeclaredField("mScroller");
51 | mScroller.setAccessible(true);
52 | FixedSpeedScroller scroller = new FixedSpeedScroller( HasTwoAdapterViewpager.this.getContext( ) );
53 | mScroller.set( HasTwoAdapterViewpager.this, scroller);
54 | }catch(NoSuchFieldException e){
55 |
56 | }catch (IllegalArgumentException e){
57 |
58 | }catch (IllegalAccessException e){
59 |
60 | }
61 | }
62 | public class FixedSpeedScroller extends Scroller {
63 | private int mDuration = 0;
64 |
65 | public FixedSpeedScroller(Context context) {
66 | super(context);
67 | }
68 |
69 | public FixedSpeedScroller(Context context, Interpolator interpolator) {
70 | super(context, interpolator);
71 | }
72 |
73 | public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {
74 | super(context, interpolator, flywheel);
75 | }
76 |
77 |
78 | @Override
79 | public void startScroll(int startX, int startY, int dx, int dy, int duration) {
80 | super.startScroll(startX, startY, dx, dy, mDuration);
81 | }
82 |
83 | @Override
84 | public void startScroll(int startX, int startY, int dx, int dy) {
85 | super.startScroll(startX, startY, dx, dy, mDuration);
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/fragment_my_calender.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
37 |
38 |
49 |
50 |
55 |
56 |
63 |
64 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/res/layout/calender_week_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
21 |
22 |
29 |
30 |
37 |
38 |
45 |
46 |
53 |
54 |
61 |
62 |
69 |
70 |
71 |
77 |
82 |
83 |
84 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/MyCalendar/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/utils/DateUtils.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.utils;
2 |
3 | import android.text.TextUtils;
4 |
5 | import java.text.ParseException;
6 | import java.text.SimpleDateFormat;
7 | import java.util.Calendar;
8 | import java.util.Date;
9 | import java.util.GregorianCalendar;
10 |
11 | public class DateUtils {
12 | private static final long INTERVAL_IN_MILLISECONDS = 30000L;
13 |
14 | public static final String FORMAT_DATETIME_MS = "yyyy-MM-dd HH:mm:ss:SSS";
15 |
16 | public static final String FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";
17 |
18 | public static final String FORMAT_DATE = "yyyy-MM-dd";
19 |
20 | public static final String FORMAT_DATEHR = "yyyy-MM-dd HH:mm";
21 |
22 | public static final String FORMAT_DATE_YEAR = "yyyy-MM-dd";
23 |
24 | public static final String FORMAT_TIME = "HH:mm";
25 |
26 | public static final String FORMAT_MIN_SCE = "mm:ss";
27 |
28 |
29 |
30 |
31 |
32 | public static boolean isCloseEnough(long paramLong1, long paramLong2) {
33 | long l = paramLong1 - paramLong2;
34 | if (l < 0L)
35 | l = -l;
36 | return (l < 5 * 60 * 1000);
37 | }
38 |
39 | public static boolean isThisWeek(Date date) {
40 | Calendar monday = new GregorianCalendar();
41 | monday.setTimeInMillis(System.currentTimeMillis());
42 | int day_of_week = monday.get(Calendar.DAY_OF_WEEK) - 1;
43 | if (day_of_week == 0)
44 | day_of_week = 7;
45 | monday.add(Calendar.DATE, -day_of_week + 1);
46 |
47 | Calendar calendar = new GregorianCalendar();
48 | calendar.setTime(date);
49 | int cha = calendar.get(Calendar.DAY_OF_YEAR) - monday.get(Calendar.DAY_OF_YEAR);
50 | if (cha > 0 && cha < 7) {
51 | return true;
52 | }
53 | return false;
54 | }
55 |
56 | public static boolean isSameDay(long start, long end) {
57 | Date startDay = new Date(start);
58 | Date endDay = new Date(end);
59 | return startDay.getYear() == endDay.getYear()
60 | && startDay.getMonth() == endDay.getMonth()
61 | && startDay.getDate() == endDay.getDate();
62 | }
63 |
64 | /**
65 | * 得到calendar的日期:xxxx-xx-xx
66 | */
67 | public static String getTagTimeStr(Calendar calendar) {
68 | String ss = "";
69 | if (calendar != null) {
70 | ss = DateUtils.longToStr(calendar.getTimeInMillis(), DateUtils.FORMAT_DATE);
71 | }
72 | return ss;
73 | }
74 |
75 | /**
76 | * 得到calendar的日期:xx月xx日
77 | */
78 | public static String getTagTimeStrByMouthandDay(Calendar calendar) {
79 | String ss = "";
80 | if (calendar != null) {
81 | ss = DateUtils.longToStr(calendar.getTimeInMillis(), "MM月dd日");
82 | }
83 | return ss;
84 | }
85 |
86 | /**
87 | * 取得两个时间相差的毫秒数
88 | */
89 | public static long diff(String dateStr1, String dateStr2) {
90 | long diff = 0;
91 | Date date1 = stringToDate(dateStr1);
92 | Date date2 = stringToDate(dateStr2);
93 |
94 | if (date1 != null && date2 != null) {
95 | diff = Math.abs(date1.getTime() - date2.getTime());
96 | }
97 |
98 | return diff;
99 | }
100 |
101 | /**
102 | * 取得特定时间与当前时间之间相差的毫秒数
103 | */
104 | public static long diffCurrentTime(String dateStr) {
105 | long diff = 0;
106 |
107 | Date date = stringToDate(dateStr);
108 | if (date != null) {
109 | diff = Math.abs(date.getTime() - System.currentTimeMillis());
110 | }
111 |
112 | return diff;
113 | }
114 |
115 | public static Date stringToDate(String dateStr) {
116 | if (dateStr == null) {
117 | return null;
118 | }
119 | int len = dateStr.length();
120 | if (len == 10) {
121 | return StringToDate(dateStr, FORMAT_DATE);
122 | } else if (len == 16) {
123 | return StringToDate(dateStr, DateUtils.FORMAT_DATEHR);
124 | } else if (len == 19) {
125 | return StringToDate(dateStr, DateUtils.FORMAT_DATETIME);
126 | } else if (len == 23) {
127 | return StringToDate(dateStr, DateUtils.FORMAT_DATETIME_MS);
128 | }
129 | return null;
130 | }
131 |
132 | public static Date StringToDate(String dateStr, String format) {
133 | SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat(
134 | format);
135 | Date localDate = null;
136 | try {
137 | localDate = localSimpleDateFormat.parse(dateStr);
138 | } catch (ParseException localParseException) {
139 | localParseException.printStackTrace();
140 | }
141 | return localDate;
142 | }
143 |
144 | public static String longToStr(long time, String format) {
145 | SimpleDateFormat dataFormat = new SimpleDateFormat(
146 | format);
147 | Date date = new Date();
148 | date.setTime(time);
149 | return dataFormat.format(date);
150 | }
151 |
152 | public static String getCurrentTime(String format) {
153 | if (TextUtils.isEmpty(format)) {
154 | format = FORMAT_DATETIME;
155 | }
156 | return longToStr(System.currentTimeMillis(), format);
157 | }
158 |
159 | public static String toTime(int paramInt) {
160 | paramInt /= 1000;
161 | int i = paramInt / 60;
162 | int j = 0;
163 | if (i >= 60) {
164 | j = i / 60;
165 | i %= 60;
166 | }
167 | int k = paramInt % 60;
168 | return String.format("%02d:%02d", new Object[]{Integer.valueOf(i),
169 | Integer.valueOf(k)});
170 | }
171 |
172 | public static String toTimeBySecond(int paramInt) {
173 | int i = paramInt / 60;
174 | int j = 0;
175 | if (i >= 60) {
176 | j = i / 60;
177 | i %= 60;
178 | }
179 | int k = paramInt % 60;
180 | return String.format("%02d:%02d", new Object[]{Integer.valueOf(i),
181 | Integer.valueOf(k)});
182 | }
183 |
184 | /**
185 | * 根据一个日期,返回是星期几的字符串
186 | *
187 | * @param date
188 | * @return
189 | */
190 | public static String getWeek(Date date) {
191 | // 再转换为时间
192 | Calendar c = Calendar.getInstance();
193 | c.setTime(date);
194 | // int hour=c.get(Calendar.DAY_OF_WEEK);
195 | // hour中存的就是星期几了,其范围 1~7
196 | // 1=星期日 7=星期六,其他类推
197 | return new SimpleDateFormat("EEEE").format(c.getTime());
198 | }
199 |
200 | public static String getWeekStr(Date date) {
201 | String str = "";
202 | str = getWeek(date);
203 | if ("1".equals(str)) {
204 | str = "星期日";
205 | } else if ("2".equals(str)) {
206 | str = "星期一";
207 | } else if ("3".equals(str)) {
208 | str = "星期二";
209 | } else if ("4".equals(str)) {
210 | str = "星期三";
211 | } else if ("5".equals(str)) {
212 | str = "星期四";
213 | } else if ("6".equals(str)) {
214 | str = "星期五";
215 | } else if ("7".equals(str)) {
216 | str = "星期六";
217 | }
218 | return str;
219 | }
220 |
221 | public static String getTimestampStr() {
222 | return Long.toString(System.currentTimeMillis());
223 | }
224 |
225 |
226 |
227 | public static boolean isCanBack(long millis) {
228 | long diff = (new Date().getTime()) - millis;
229 | double seconds = Math.abs(diff) / 1000;
230 | double minutes = seconds / 60;
231 | if (minutes < 2) {
232 | return true;
233 | } else {
234 | return false;
235 | }
236 | }
237 |
238 |
239 | }
240 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/adpter/WeekCalendarAdpter.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.adpter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorInflater;
5 | import android.content.Context;
6 | import android.graphics.drawable.Drawable;
7 | import android.os.Handler;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 |
13 | import java.util.ArrayList;
14 | import java.util.Calendar;
15 | import java.util.GregorianCalendar;
16 | import java.util.List;
17 |
18 | import choosetime.com.example.chen.mycalendar.R;
19 | import choosetime.com.example.chen.mycalendar.calendar.CalendarUtil;
20 | import choosetime.com.example.chen.mycalendar.calendar.fragment.MyCalendarFragment;
21 | import choosetime.com.example.chen.mycalendar.calendar.utils.DateUtils;
22 |
23 | /**
24 | * Created by Administrator on 2016/1/16 0016.
25 | */
26 | public class WeekCalendarAdpter extends CalendarBaseAdpter {
27 | private List views;
28 | private Context context;
29 |
30 | private Handler os = null;
31 |
32 | private Drawable yuanOfRed;
33 | private Drawable white;
34 | private int text_black;
35 | private int last_msg_tv_color;
36 | private int text_white;
37 | private final Drawable yuanOfBlack;
38 | private ArrayList list = new ArrayList<>();
39 | private String strToday = "";
40 |
41 | public WeekCalendarAdpter(List views, Context context, ArrayList list) {
42 | this.list = list;
43 | this.views = views;
44 | this.context = context;
45 | //选中今天
46 | Calendar today = new GregorianCalendar();
47 | today.setTimeInMillis(System.currentTimeMillis());
48 |
49 | strToday = DateUtils.getTagTimeStr(today);
50 |
51 | selectTime = DateUtils.getTagTimeStr(today);
52 | last_msg_tv_color = context.getResources().getColor(R.color.last_msg_tv_color);
53 | text_black = context.getResources().getColor(R.color.black_deep);
54 | text_white = context.getResources().getColor(R.color.white);
55 | yuanOfRed = context.getResources().getDrawable(R.drawable.yuan);
56 | yuanOfBlack = context.getResources().getDrawable(R.drawable.calendar_background);
57 | white = context.getResources().getDrawable(R.drawable.white);
58 | }
59 |
60 | public void setHandler(Handler os) {
61 | this.os = os;
62 | }
63 |
64 | @Override
65 | public int getCount() {
66 | return 9600;
67 | }
68 |
69 | @Override
70 | public boolean isViewFromObject(View view, Object object) {
71 | return view == object;
72 | }
73 |
74 | @Override
75 | public void destroyItem(ViewGroup container, int position, Object object) {
76 | // container.removeView(views.get(position % views.size()));
77 | }
78 |
79 | public void getTimeList(ArrayList list) {
80 | this.list = list;
81 | }
82 |
83 | @Override
84 | public Object instantiateItem(ViewGroup container, final int position) {
85 | ViewGroup view = (ViewGroup) views.get(position % views.size());
86 | int index = container.indexOfChild(view);
87 | if (index != -1) {
88 | container.removeView(view);
89 | }
90 | try {
91 | container.addView(view);
92 | } catch (Exception e) {
93 |
94 | }
95 |
96 | //给view 填充内容
97 |
98 | //设置开始时间为本周日
99 | Calendar today = new GregorianCalendar();
100 | today.setTimeInMillis(System.currentTimeMillis());
101 | int day_of_week = today.get(Calendar.DAY_OF_WEEK) - 1;
102 | if (day_of_week == 0) {
103 | day_of_week = 7;
104 | }
105 | today.add(Calendar.DATE, -day_of_week);
106 | //距离当前时间的周数
107 | int week = getCount() / 2 - position;
108 | today.add(Calendar.DATE, -week * 7);
109 |
110 | render(view, today);
111 | return view;
112 | }
113 |
114 | /**
115 | * 渲染page中的view:7天
116 | */
117 | private void render(final ViewGroup view, final Calendar today) {
118 | for (int a = 0; a < 7; a++) {
119 | final int dayOfMonth = today.get(Calendar.DAY_OF_MONTH);
120 | // int day_of_year=today.get(Calendar.DAY_OF_YEAR);
121 | final ViewGroup dayOfWeek = (ViewGroup) view.getChildAt(a);
122 | //((TextView) dayOfWeek.getChildAt(0)).setText(getStr(today.get(Calendar.DAY_OF_WEEK)));
123 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setText(dayOfMonth + "");
124 | String str = "";
125 | try {
126 | str = new CalendarUtil().getChineseDay(today.get(Calendar.YEAR),
127 | today.get(Calendar.MONTH) + 1, today.get(Calendar.DAY_OF_MONTH));
128 | } catch (Exception e) {
129 |
130 | }
131 |
132 | if (str.equals("初一")) {//如果是初一,显示月份
133 | str = new CalendarUtil().getChineseMonth(today.get(Calendar.YEAR),
134 | today.get(Calendar.MONTH) + 1, today.get(Calendar.DAY_OF_MONTH));
135 | }
136 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setText(str);
137 |
138 | dayOfWeek.setTag(DateUtils.getTagTimeStr(today));
139 |
140 | dayOfWeek.setOnClickListener(new View.OnClickListener() {
141 | @Override
142 | public void onClick(View v) {
143 | is = true;
144 | //TODO:发消息,告诉Activity我改变选中的日期了
145 | if (WeekCalendarAdpter.this.os != null) {
146 | os.sendEmptyMessage(MyCalendarFragment.change);
147 | }
148 | selectTime = dayOfWeek.getTag().toString();
149 | today.add(Calendar.DATE, -7);//因为已经渲染过7天,所以today往前推7天, 代表当前page重绘;
150 |
151 | //界面特效:变为红色,执行动画
152 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfRed);
153 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_white);
154 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(text_white);
155 |
156 | Animator anim = AnimatorInflater.loadAnimator(context, R.anim.soufang);
157 |
158 | //显示的调用invalidate
159 | dayOfWeek.invalidate();
160 | anim.setTarget(dayOfWeek);
161 | anim.start();
162 | //添加监听:动画开始时,恢复上个选中的day的状态,结束时执行刷新方法;
163 |
164 | //将上一个选中的day的状态恢复
165 | if (day != null) {
166 | day.findViewById(R.id.cal_container).setBackgroundDrawable(white);
167 | ((TextView) day.findViewById(R.id.gongli)).setTextColor(text_black);
168 | ((TextView) day.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
169 | //特殊情况:上个选中的day今天
170 | if (strToday.equals(tag)) {
171 | day.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfBlack);
172 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
173 | ((TextView) day.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
174 | } else {
175 | day.findViewById(R.id.cal_container).setBackgroundDrawable(white);
176 | ((TextView) day.findViewById(R.id.gongli)).setTextColor(text_black);
177 | ((TextView) day.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
178 | }
179 | }
180 |
181 | anim.addListener(new Animator.AnimatorListener() {
182 | @Override
183 | public void onAnimationStart(Animator animation) {
184 |
185 | }
186 |
187 | @Override
188 | public void onAnimationEnd(Animator animation) {
189 | render(view, today);
190 | is = false;
191 | }
192 |
193 | @Override
194 | public void onAnimationCancel(Animator animation) {
195 |
196 | }
197 |
198 | @Override
199 | public void onAnimationRepeat(Animator animation) {
200 |
201 | }
202 | });
203 |
204 | }
205 | });
206 | if (strToday.equals(DateUtils.getTagTimeStr(today))) {
207 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfBlack);
208 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
209 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
210 | if (!selectTime.equals(strToday)) {
211 | today.add(Calendar.DATE, 1);
212 | continue;
213 | }
214 | } else {
215 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(white);
216 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
217 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
218 | }
219 | if (selectTime.equals(DateUtils.getTagTimeStr(today))) {
220 |
221 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfRed);
222 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_white);
223 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(text_white);
224 |
225 |
226 | day = dayOfWeek;
227 | tag = selectTime;
228 | } else {
229 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(white);
230 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
231 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
232 | }
233 | if (list.contains(DateUtils.getTagTimeStr(today))) {
234 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setVisibility(View.VISIBLE);
235 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setImageResource(R.drawable.calendar_item_point);
236 | } else {
237 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setVisibility(View.INVISIBLE);
238 | }
239 |
240 | today.add(Calendar.DATE, 1);
241 | }
242 | }
243 |
244 | private ViewGroup day = null;
245 | private String tag = "";
246 |
247 | public String getSelectTime() {
248 | return selectTime;
249 | }
250 |
251 | public void setSelectTime(String selectTime) {
252 | this.selectTime = selectTime;
253 | }
254 |
255 | }
256 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/fragment/MyCalendarFragment.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.fragment;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Message;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.app.Fragment;
9 | import android.support.v4.view.ViewPager;
10 | import android.util.Log;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.LinearLayout;
15 |
16 | import java.util.ArrayList;
17 | import java.util.Calendar;
18 | import java.util.Date;
19 | import java.util.GregorianCalendar;
20 | import java.util.List;
21 |
22 | import choosetime.com.example.chen.mycalendar.R;
23 | import choosetime.com.example.chen.mycalendar.calendar.abs.RefreshListener;
24 | import choosetime.com.example.chen.mycalendar.calendar.adpter.MonthCalendarAdpter;
25 | import choosetime.com.example.chen.mycalendar.calendar.adpter.WeekCalendarAdpter;
26 | import choosetime.com.example.chen.mycalendar.calendar.fragment.widget.HandMoveLayout;
27 | import choosetime.com.example.chen.mycalendar.calendar.fragment.widget.HasTwoAdapterViewpager;
28 | import choosetime.com.example.chen.mycalendar.calendar.utils.DateUtils;
29 |
30 | /**
31 | * 我的日程
32 | */
33 | public class MyCalendarFragment extends Fragment implements RefreshListener {
34 | public static final int back_code = 121;
35 |
36 | public MyCalendarFragment() {
37 | super();
38 | }
39 |
40 | private HandMoveLayout handMoveLayout;
41 |
42 | @SuppressLint("ValidFragment")
43 | public MyCalendarFragment(Handler os) {
44 | super();
45 | }
46 |
47 | @Override
48 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
49 | Bundle savedInstanceState) {
50 | // Inflate the layout for this fragment
51 | return inflater.inflate(R.layout.fragment_my_calender, container, false);
52 | }
53 | /**
54 | * 调整到下个月
55 | * */
56 | public void pagerNext(){
57 | if (viewPager!=null){
58 | viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
59 | }
60 | }
61 | /**
62 | * 调整到上个月
63 | * */
64 | public void pagerLast(){
65 | if (viewPager!=null){
66 | viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
67 | }
68 | }
69 |
70 | @Override
71 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
72 | super.onActivityCreated(savedInstanceState);
73 |
74 | handMoveLayout = (HandMoveLayout) getView().findViewById(R.id.handmovelayout);
75 |
76 | initCalendar();
77 |
78 |
79 | }
80 | private HasTwoAdapterViewpager viewPager;
81 | private HasTwoAdapterViewpager viewpagerWeek;
82 | private List views;
83 | private WeekCalendarAdpter weekCalendarAdpter;
84 | private ArrayList timeList = new ArrayList<>();
85 | public void initCalendar() {
86 | viewPager = (HasTwoAdapterViewpager) getView().findViewById(R.id.calendar_viewpager);
87 | viewpagerWeek = (HasTwoAdapterViewpager) getView().findViewById(R.id.calendar_viewpager_week);
88 |
89 | viewPager.setListener(this);
90 | viewpagerWeek.setListener(this);
91 |
92 | //制造月视图所需view
93 | views = new ArrayList<>();
94 | LinearLayout layout = (LinearLayout) View.inflate(getActivity(), R.layout.mouth, null);
95 | LinearLayout layout1 = (LinearLayout) View.inflate(getActivity(), R.layout.mouth, null);
96 | LinearLayout layout2 = (LinearLayout) View.inflate(getActivity(), R.layout.mouth, null);
97 | LinearLayout layout3 = (LinearLayout) View.inflate(getActivity(), R.layout.mouth, null);
98 | views.add(layout);
99 | views.add(layout1);
100 | views.add(layout2);
101 | views.add(layout3);
102 |
103 | adpter = new MonthCalendarAdpter(views, getActivity(), timeList);
104 | adpter.setHandler(os);
105 |
106 | //制造日试图所需view
107 | List viewss = new ArrayList();
108 | LinearLayout layoutri = (LinearLayout) View.inflate(getActivity(), R.layout.week, null);
109 | LinearLayout layout1ri = (LinearLayout) View.inflate(getActivity(), R.layout.week, null);
110 | LinearLayout layout2ri = (LinearLayout) View.inflate(getActivity(), R.layout.week, null);
111 | LinearLayout layout3ri = (LinearLayout) View.inflate(getActivity(), R.layout.week, null);
112 | viewss.add(layoutri);
113 | viewss.add(layout1ri);
114 | viewss.add(layout2ri);
115 | viewss.add(layout3ri);
116 | weekCalendarAdpter = new WeekCalendarAdpter(viewss, getActivity(), timeList);
117 | weekCalendarAdpter.setHandler(os);
118 | viewPager.setAdapter(adpter);
119 | viewPager.setCurrentItem(1200, true);
120 | viewpagerWeek.setAdapter(weekCalendarAdpter);
121 | viewpagerWeek.setCurrentItem(weekCalendarAdpter.getCount() / 2);
122 |
123 | //如果是周日,就翻到下一页
124 | Calendar today = new GregorianCalendar();
125 | today.setTimeInMillis(System.currentTimeMillis());
126 |
127 | viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
128 | @Override
129 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
130 | Log.d("position", Integer.toString(position));
131 |
132 | }
133 |
134 | @Override
135 | public void onPageSelected(int position) {
136 | Calendar today = new GregorianCalendar();
137 | today.setTimeInMillis(System.currentTimeMillis());
138 | //距离当前时间的月数(按月算)
139 | int month = adpter.getCount() / 2 - position;
140 | today.add(Calendar.MONTH, -month);
141 |
142 | // setBarTitle(getTopTitleTime(today));
143 | //更新currentItem
144 | // viewPager.setTag(R.id.month_current,position);
145 |
146 | }
147 |
148 | @Override
149 | public void onPageScrollStateChanged(int state) {
150 |
151 | }
152 | });
153 | viewpagerWeek.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
154 | @Override
155 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
156 |
157 | }
158 |
159 | @Override
160 | public void onPageSelected(int position) {
161 | Calendar today = new GregorianCalendar();
162 | today.setTimeInMillis(System.currentTimeMillis());
163 |
164 | int day_of_week = today.get(Calendar.DAY_OF_WEEK) - 1;
165 | if (day_of_week == 0) {
166 | day_of_week = 7;
167 | }
168 | today.add(Calendar.DATE, -day_of_week);
169 | //距离当前时间的周数(按周算)
170 | int week = weekCalendarAdpter.getCount() / 2 - position;
171 | today.add(Calendar.DATE, -week * 7);
172 | // setBarTitle(getTopTitleTime(today));
173 | //刷新本页
174 | }
175 |
176 | @Override
177 | public void onPageScrollStateChanged(int state) {
178 |
179 | }
180 | });
181 | }
182 |
183 | private MonthCalendarAdpter adpter;
184 | /**
185 | * 用于接收上面日期改变的消息
186 | */
187 | public static final int change = 90;
188 | public static final int change2=91;
189 |
190 | public static final int pagerNext=101;
191 | public static final int pagerLast=102;
192 | Handler os = new Handler() {
193 | @Override
194 | public void handleMessage(Message msg) {
195 | super.handleMessage(msg);
196 | if (msg.what == 90) {
197 | //do same thing
198 | }else if(msg.what==change2){
199 | handMoveLayout.setRowNum((Integer) msg.obj);
200 | }else if(msg.what==pagerNext){
201 | pagerNext();
202 | }else if(msg.what==pagerLast){
203 | pagerLast();
204 | }
205 | }
206 | };
207 |
208 | int currentItem = 0;
209 | @Override
210 | public void refreshListener(final ViewPager viewPager) {
211 | // ToastUtils.shortMsg("刷新");
212 | //得到这个selecttime对应的currentItem
213 | currentItem = 0;
214 | if (viewPager.getAdapter() instanceof MonthCalendarAdpter) {
215 | adpter.getTimeList(timeList);
216 | //月视图
217 | currentItem = getMonthCurrentItem();
218 | int odl = viewPager.getCurrentItem();
219 | viewPager.setCurrentItem(currentItem, false);
220 | //刷新已经存在的3个视图view
221 | if (Math.abs(odl - currentItem) <= 1) {
222 | adpter.instantiateItem(viewPager, viewPager.getCurrentItem() - 1);
223 |
224 | adpter.instantiateItem(viewPager, viewPager.getCurrentItem());
225 |
226 | adpter.instantiateItem(viewPager, viewPager.getCurrentItem() + 1);
227 | }
228 | adpter.notifyDataSetChanged();
229 | } else {
230 | //周视图
231 | currentItem = getWeekCurrentItem();
232 | //如果是周日,就是下一周,+1
233 | if (DateUtils.getWeekStr(DateUtils.stringToDate(adpter.getSelectTime())).equals("星期日")) {
234 | currentItem++;
235 | }
236 | weekCalendarAdpter.getTimeList(timeList);
237 | int odl = viewPager.getCurrentItem();
238 | viewPager.setCurrentItem(currentItem, false);
239 | //刷新已经存在的3个视图view
240 | if (Math.abs(odl - currentItem) <= 1) {
241 | weekCalendarAdpter.instantiateItem(viewPager, viewPager.getCurrentItem() - 1);
242 |
243 | weekCalendarAdpter.instantiateItem(viewPager, viewPager.getCurrentItem());
244 |
245 | weekCalendarAdpter.instantiateItem(viewPager, viewPager.getCurrentItem() + 1);
246 | }
247 | weekCalendarAdpter.notifyDataSetChanged();
248 | }
249 |
250 | }
251 |
252 | //得到月视图选中日期后的CurrentItem
253 | private int getMonthCurrentItem() {
254 | //此刻
255 | Calendar today = new GregorianCalendar();
256 | today.setTimeInMillis(System.currentTimeMillis());
257 | //选中时间
258 | String time = adpter.getSelectTime();
259 | Date date = DateUtils.stringToDate(time);
260 | Calendar sele = new GregorianCalendar();
261 | sele.setTimeInMillis(date.getTime());
262 |
263 | //选中时间的(MONTH)-此刻(MONTH)=月数
264 | int aa = sele.get(Calendar.MONTH) - today.get(Calendar.MONTH);
265 |
266 | return adpter.getCount() / 2 + aa;
267 | }
268 |
269 | //得到周视图选中日期后的CurrentItem
270 | public int getWeekCurrentItem() {
271 | //此刻
272 | Calendar today = new GregorianCalendar();
273 | today.setTimeInMillis(System.currentTimeMillis());
274 | //转为本周一
275 | int day_of_week = today.get(Calendar.DAY_OF_WEEK) - 1;
276 | if (day_of_week == 0) {
277 | day_of_week = 7;
278 | }
279 | today.add(Calendar.DATE, -day_of_week);
280 | //选中时间
281 | String time = weekCalendarAdpter.getSelectTime();
282 | Date date = DateUtils.stringToDate(time);
283 | Calendar sele = new GregorianCalendar();
284 | sele.setTimeInMillis(date.getTime());
285 |
286 | //选中时间的(day of yeay)-此刻(day of yeay)=天数
287 | int aa = ((int) (sele.getTime().getTime() / 1000) - (int) (today.getTime().getTime() / 1000)) / 3600 / 24;
288 | int aa2 = 0;
289 | if (Math.abs(aa) % 7 == 0) {
290 | aa2 = Math.abs(aa) / 7;
291 | } else {
292 | aa2 = Math.abs(aa) / 7;
293 | }
294 | if (aa >= 0) {
295 | return weekCalendarAdpter.getCount() / 2 + aa2;
296 | } else {
297 | return weekCalendarAdpter.getCount() / 2 - aa2 - 1;
298 | }
299 | }
300 | }
301 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/adpter/MonthCalendarAdpter.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.adpter;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorInflater;
5 | import android.content.Context;
6 | import android.graphics.drawable.Drawable;
7 | import android.os.Handler;
8 | import android.os.Message;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ImageView;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Calendar;
16 | import java.util.GregorianCalendar;
17 | import java.util.List;
18 |
19 | import choosetime.com.example.chen.mycalendar.R;
20 | import choosetime.com.example.chen.mycalendar.calendar.CalendarUtil;
21 | import choosetime.com.example.chen.mycalendar.calendar.fragment.MyCalendarFragment;
22 | import choosetime.com.example.chen.mycalendar.calendar.utils.DateUtils;
23 |
24 | /**
25 | * Created by Administrator on 2016/5/19 0019.
26 | */
27 | public class MonthCalendarAdpter extends CalendarBaseAdpter {
28 | private List views;
29 | private Context context;
30 |
31 | private Handler os = null;
32 | private int last_msg_tv_color;
33 | private Drawable yuanOfRed;
34 | private Drawable white;
35 | private int text_black;
36 | private int text_white;
37 | private final Drawable yuanOfBlack;
38 |
39 | private String strToDay = "";
40 | private ArrayList list = new ArrayList<>();
41 |
42 | public MonthCalendarAdpter(List views, Context context, ArrayList list) {
43 | this.views = views;
44 | this.context = context;
45 | this.list = list;
46 | //选中今天
47 | Calendar today = new GregorianCalendar();
48 | today.setTimeInMillis(System.currentTimeMillis());
49 |
50 | strToDay = DateUtils.getTagTimeStr(today);
51 |
52 | selectTime = DateUtils.getTagTimeStr(today);
53 | text_black = context.getResources().getColor(R.color.black_deep);
54 | last_msg_tv_color = context.getResources().getColor(R.color.last_msg_tv_color);
55 | text_white = context.getResources().getColor(R.color.white);
56 | yuanOfRed = context.getResources().getDrawable(R.drawable.yuan);
57 | yuanOfBlack = context.getResources().getDrawable(R.drawable.calendar_background);
58 | white = context.getResources().getDrawable(R.drawable.white);
59 | }
60 |
61 | public void setHandler(Handler os) {
62 | this.os = os;
63 | }
64 |
65 | @Override
66 | public int getCount() {
67 | return 2400;
68 | }
69 |
70 | @Override
71 | public boolean isViewFromObject(View view, Object object) {
72 | return view == object;
73 | }
74 |
75 | @Override
76 | public void destroyItem(ViewGroup container, int position, Object object) {
77 | }
78 |
79 |
80 | @Override
81 | public Object instantiateItem(ViewGroup container, final int position) {
82 | ViewGroup view = (ViewGroup) views.get(position % views.size());
83 | int index = container.indexOfChild(view);
84 | if (index != -1) {
85 | container.removeView(view);
86 | }
87 | try {
88 | container.addView(view);
89 | } catch (Exception e) {
90 |
91 | }
92 | refresh(view, position, list);
93 | return view;
94 | }
95 |
96 | public void getTimeList(ArrayList list) {
97 | this.list = list;
98 | }
99 |
100 | /**
101 | * 提供对外的刷新接口
102 | */
103 | public void refresh(ViewGroup view, int position, ArrayList list) {
104 | //给view 填充内容
105 |
106 | //设置开始时间为本周日
107 | Calendar today = new GregorianCalendar();
108 | today.setTimeInMillis(System.currentTimeMillis());
109 | //距离当前时间的月数
110 | int month = 1200 - position;
111 | today.add(Calendar.MONTH, -month);
112 | view.setTag(today.get(Calendar.MONTH) + "");
113 | //找到这个月的第一天所在星期的周日
114 | today.add(Calendar.DAY_OF_MONTH, -(today.get(Calendar.DAY_OF_MONTH) - 1));
115 |
116 |
117 | int day_of_week = today.get(Calendar.DAY_OF_WEEK) - 1;
118 | if (day_of_week == 0) {
119 | day_of_week = 7;
120 | }
121 | today.add(Calendar.DATE, -day_of_week);
122 |
123 | render(view, today);
124 | }
125 |
126 | /**
127 | * 渲染page中的view:7天
128 | */
129 | private void render(final ViewGroup view1, final Calendar today) {
130 | //一页显示一个月+7天,为42;
131 | for (int b = 0; b < 6; b++) {
132 | final ViewGroup view = (ViewGroup) view1.getChildAt(b);
133 | for (int a = 0; a < 7; a++) {
134 | final int dayOfMonth = today.get(Calendar.DAY_OF_MONTH);
135 | // int day_of_year=today.get(Calendar.DAY_OF_YEAR);
136 | final ViewGroup dayOfWeek = (ViewGroup) view.getChildAt(a);
137 | //((TextView) dayOfWeek.getChildAt(0)).setText(getStr(today.get(Calendar.DAY_OF_WEEK)));
138 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setText(dayOfMonth + "");
139 | String str = "";
140 | try {
141 | str = new CalendarUtil().getChineseDay(today.get(Calendar.YEAR),
142 | today.get(Calendar.MONTH) + 1, today.get(Calendar.DAY_OF_MONTH));
143 | } catch (Exception e) {
144 |
145 | }
146 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setVisibility(View.INVISIBLE);
147 | // String str =
148 | if (str.equals("初一")) {//如果是初一,显示月份
149 | str = new CalendarUtil().getChineseMonth(today.get(Calendar.YEAR),
150 | today.get(Calendar.MONTH) + 1, today.get(Calendar.DAY_OF_MONTH));
151 | }
152 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setText(str);
153 | if (list.contains(DateUtils.getTagTimeStr(today))) {
154 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setVisibility(View.VISIBLE);
155 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setImageResource(R.drawable.calendar_item_point);
156 | } else {
157 | ((ImageView) dayOfWeek.findViewById(R.id.imv_point)).setVisibility(View.INVISIBLE);
158 | }
159 | dayOfWeek.setTag(DateUtils.getTagTimeStr(today));
160 |
161 | dayOfWeek.setOnClickListener(new View.OnClickListener() {
162 | @Override
163 | public void onClick(View v) {
164 | is = true;
165 | //TODO:发消息,告诉Activity我改变选中的日期了
166 | if (MonthCalendarAdpter.this.os != null) {
167 | os.sendEmptyMessage(MyCalendarFragment.change);
168 | }
169 |
170 | selectTime = dayOfWeek.getTag().toString();
171 | today.add(Calendar.DATE, -42);//因为已经渲染过42天,所以today往前推42天, 代表当前page重绘;
172 |
173 | //
174 | //恢复上个选中的day的状态
175 | if (day != null) {
176 | day.findViewById(R.id.cal_container).setBackgroundDrawable(white);
177 | ((TextView) day.findViewById(R.id.gongli)).setTextColor(text_black);
178 | //特殊情况
179 | if (strToDay.equals(tag)) {
180 | day.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfBlack);
181 | ((TextView) day.findViewById(R.id.gongli)).setTextColor(text_black);
182 | ((TextView) day.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
183 |
184 | } else {
185 | day.findViewById(R.id.cal_container).setBackgroundDrawable(white);
186 | ((TextView) day.findViewById(R.id.gongli)).setTextColor(text_black);
187 | ((TextView) day.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
188 | }
189 | }
190 | //变为红色
191 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfRed);
192 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_white);
193 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(text_white);
194 |
195 | Animator anim = AnimatorInflater.loadAnimator(context, R.anim.soufang);
196 | //显示的调用invalidate
197 | dayOfWeek.invalidate();
198 | anim.setTarget(dayOfWeek);
199 | anim.start();
200 | // 添加监听:动画结束时执行刷新方法;
201 |
202 | anim.addListener(new Animator.AnimatorListener() {
203 | @Override
204 | public void onAnimationStart(Animator animation) {
205 |
206 | }
207 |
208 | @Override
209 | public void onAnimationEnd(Animator animation) {
210 | render(view1, today);
211 | is = false;
212 | }
213 |
214 | @Override
215 | public void onAnimationCancel(Animator animation) {
216 |
217 | }
218 |
219 | @Override
220 | public void onAnimationRepeat(Animator animation) {
221 |
222 | }
223 | });
224 |
225 | }
226 | });
227 | if (strToDay.equals(DateUtils.getTagTimeStr(today))) {
228 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfBlack);
229 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
230 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
231 | if (!selectTime.equals(strToDay)) {
232 | today.add(Calendar.DATE, 1);
233 | continue;
234 | }
235 | } else {
236 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(white);
237 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
238 | }
239 | //不是当前月的显示为灰色
240 | if ((Integer.parseInt((String) view1.getTag())) != today.get(Calendar.MONTH)) {
241 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(last_msg_tv_color);
242 | if ((Integer.parseInt((String) view1.getTag())) > today.get(Calendar.MONTH)) {
243 | //下个月
244 | dayOfWeek.setOnClickListener(lastLister);
245 | } else {
246 | //上个月
247 | dayOfWeek.setOnClickListener(nextLister);
248 | }
249 | today.add(Calendar.DATE, 1);
250 | continue;
251 | } else {
252 | dayOfWeek.setAlpha(1.0f);
253 | }
254 | //如果是选中天的话显示为红色
255 | if (selectTime.equals(DateUtils.getTagTimeStr(today))) {
256 |
257 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfRed);
258 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_white);
259 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(text_white);
260 |
261 | if (strToDay.equals(DateUtils.getTagTimeStr(today))) {
262 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(yuanOfRed);
263 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_white);
264 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(text_white);
265 | }
266 |
267 | day = dayOfWeek;
268 | if (MonthCalendarAdpter.this.os != null) {
269 | Message message = os.obtainMessage();
270 | message.obj = b;
271 | message.what = MyCalendarFragment.change2;
272 | os.sendMessage(message);
273 | }
274 | tag = selectTime;
275 | } else {
276 | dayOfWeek.findViewById(R.id.cal_container).setBackgroundDrawable(white);
277 | ((TextView) dayOfWeek.findViewById(R.id.gongli)).setTextColor(text_black);
278 | ((TextView) dayOfWeek.findViewById(R.id.nongli)).setTextColor(last_msg_tv_color);
279 | }
280 | today.add(Calendar.DATE, 1);
281 | }
282 | }
283 |
284 | }
285 |
286 | View.OnClickListener nextLister = new View.OnClickListener() {
287 | @Override
288 | public void onClick(View v) {
289 | if (MonthCalendarAdpter.this.os != null) {
290 | Message message = os.obtainMessage();
291 | message.what = MyCalendarFragment.pagerNext;
292 | os.sendMessage(message);
293 | }
294 | }
295 | };
296 | View.OnClickListener lastLister = new View.OnClickListener() {
297 | @Override
298 | public void onClick(View v) {
299 | if (MonthCalendarAdpter.this.os != null) {
300 | Message message = os.obtainMessage();
301 | message.what = MyCalendarFragment.pagerLast;
302 | os.sendMessage(message);
303 | }
304 | }
305 | };
306 |
307 | private ViewGroup day = null;
308 |
309 | public ViewGroup getDay() {
310 | return day;
311 | }
312 |
313 | private String tag = "";
314 |
315 | public String getSelectTime() {
316 | return selectTime;
317 | }
318 |
319 | public void setSelectTime(String selectTime) {
320 | this.selectTime = selectTime;
321 | }
322 |
323 | }
324 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/fragment/widget/HandMoveLayout.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar.fragment.widget;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.os.Handler;
7 | import android.os.Message;
8 | import android.support.v4.view.ViewPager;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.AbsListView;
15 | import android.widget.LinearLayout;
16 | import android.widget.ListView;
17 |
18 | import choosetime.com.example.chen.mycalendar.R;
19 | import choosetime.com.example.chen.mycalendar.calendar.adpter.CalendarBaseAdpter;
20 | import choosetime.com.example.chen.mycalendar.calendar.utils.MomentsUtils;
21 |
22 |
23 | /**
24 | * Created by chen on 2016/5/19 0019.
25 | */
26 | public class HandMoveLayout extends LinearLayout {
27 |
28 | /**
29 | * 日历控件,viewpager
30 | */
31 | private ViewPager monthViewpager;
32 | private ViewPager weekviewpager;
33 |
34 |
35 | private ViewPager mHeader;
36 |
37 | /**
38 | * scrollview内容
39 | */
40 | private ViewGroup mContent;
41 | /**
42 | * 子布局中的listview布局
43 | */
44 |
45 | private ListView listView;
46 |
47 |
48 | /**
49 | * 日历原始高度
50 | */
51 | private int headerOriginalHeight;
52 | /**
53 | * 滚动距离
54 | */
55 | private int scrollCountY;
56 |
57 | /**
58 | * 日历控件顶部隐藏的高度
59 | */
60 | private int hideTop = 0;
61 | /**
62 | * 日历控件底部隐藏的高度
63 | */
64 | private int hideBottom = 0;
65 |
66 | /**
67 | * 最小的滑动距离, 小于该值认为没有滑动
68 | */
69 | private int minDistance;
70 |
71 | /**
72 | * onInterceptTouchEvent最后坐标
73 | */
74 | private int mLastXIntercept;
75 | private int mLastYIntercept;
76 |
77 | /**
78 | * onTouchEvent的最后坐标
79 | */
80 | private int mLastX;
81 | private int mLastY;
82 | /**
83 | * onTouchEvent每次move产生的距离
84 | */
85 | private int deltaY;
86 |
87 | /**
88 | * 是否还在动画过渡中,为true时不分发touch事件
89 | */
90 | private boolean isInAnimation = false;
91 |
92 | private Handler handler;
93 |
94 | public HandMoveLayout(Context context) {
95 | super(context);
96 | }
97 |
98 | public HandMoveLayout(Context context, AttributeSet attrs) {
99 | super(context, attrs);
100 | }
101 |
102 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
103 | public HandMoveLayout(Context context, AttributeSet attrs, int defStyleAttr) {
104 | super(context, attrs, defStyleAttr);
105 | }
106 |
107 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
108 | public HandMoveLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
109 | super(context, attrs, defStyleAttr, defStyleRes);
110 | }
111 |
112 | public void setHandler(Handler handler){
113 | this.handler=handler;
114 | }
115 | @Override
116 | public void onWindowFocusChanged(boolean hasWindowFocus) {
117 | super.onWindowFocusChanged(hasWindowFocus);
118 | if (hasWindowFocus) {
119 | init();
120 | }
121 | }
122 |
123 |
124 | private void init() {
125 | if (mHeader == null && mContent == null) {
126 | minDistance = getResources().getDimensionPixelOffset(R.dimen.app_size_20);
127 | int headerId = getResources().getIdentifier("ll_calendar_viewpager", "id", getContext().getPackageName());
128 | int contentId = getResources().getIdentifier("handmove", "id", getContext().getPackageName());
129 | int listViewId = getResources().getIdentifier("list", "id", getContext().getPackageName());
130 | if (headerId != 0 && contentId != 0 & listViewId != 0) {
131 | // mHeader = (LinearLayout) findViewById(headerId);
132 | mContent = (ViewGroup) findViewById(contentId);
133 | listView = (ListView) findViewById(listViewId);
134 | monthViewpager = (ViewPager) findViewById(R.id.calendar_viewpager);
135 | monthViewpager.setVisibility(GONE);//初始化隐藏,这是最佳时机
136 | weekviewpager = (ViewPager) findViewById(R.id.calendar_viewpager_week);
137 | ViewGroup group = (ViewGroup) findViewById(R.id.ll_no_data);
138 | mHeader = monthViewpager;
139 | group.setOnClickListener(new OnClickListener() {
140 | @Override
141 | public void onClick(View v) {
142 | }
143 | });
144 | if (mHeader != null) {
145 | // headerOriginalHeight = mHeader.getMeasuredHeight();
146 | headerOriginalHeight = MomentsUtils.dip2px(getContext(), 300);//此处由于娶不到高度,所以写死
147 | scrollCountY = -getResources().getDimensionPixelSize(R.dimen.calendat_height);
148 | }
149 | // collapse();
150 | }
151 | }
152 | // //测试
153 | // setRowNum(0);
154 | }
155 |
156 |
157 | @Override
158 | public boolean dispatchTouchEvent(MotionEvent ev) {
159 | Log.w("sunzn", "TouchEventActivity | dispatchTouchEvent --> " + getTouchAction(ev.getAction()) + "isInAnimation" + isInAnimation);
160 | if (isInAnimation) {
161 | //如果还在动画过程中则不变
162 | return false;
163 | }
164 |
165 | return super.dispatchTouchEvent(ev);
166 | }
167 |
168 | public static String getTouchAction(int actionId) {
169 | String actionName = "Unknow:id=" + actionId;
170 | switch (actionId) {
171 | case MotionEvent.ACTION_DOWN:
172 | actionName = "ACTION_DOWN";
173 | break;
174 | case MotionEvent.ACTION_MOVE:
175 | actionName = "ACTION_MOVE";
176 | break;
177 | case MotionEvent.ACTION_UP:
178 | actionName = "ACTION_UP";
179 | break;
180 | case MotionEvent.ACTION_CANCEL:
181 | actionName = "ACTION_CANCEL";
182 | break;
183 | case MotionEvent.ACTION_OUTSIDE:
184 | actionName = "ACTION_OUTSIDE";
185 | break;
186 | }
187 | return actionName;
188 | }
189 |
190 | @Override
191 | public boolean onInterceptTouchEvent(MotionEvent event) {
192 | if ((CalendarBaseAdpter.is())) {
193 | return true;
194 | }
195 | boolean intercepted = false;
196 | int x = (int) event.getX();
197 | int y = (int) event.getY();
198 | switch (event.getAction()) {
199 | case MotionEvent.ACTION_DOWN:
200 | mLastXIntercept = x;
201 | mLastYIntercept = y;
202 | //@TODO 这里看看是不是还能优化,因为还要处理日历等子view的点击事件,必须不拦截,否则点击传不下去
203 | intercepted = false;
204 | onTouchEvent(event);
205 | break;
206 | case MotionEvent.ACTION_MOVE:
207 | int deltaY = y - mLastYIntercept;
208 | int deltaX = x - mLastXIntercept;
209 | if (Math.abs(deltaX) < 20 && Math.abs(deltaY) < 20) {
210 | intercepted = false;
211 | } else if (Math.abs(deltaX) > Math.abs(deltaY)) {
212 | //横向移动的时候不拦截touch事件,让viewpager处理
213 | intercepted = false;
214 | } else {
215 | if (mContent.getTop() == mHeader.getBottom()) {
216 | //如果头部完全展开则直接拦截
217 | intercepted = true;
218 | } else {
219 | if (weekviewpager.getVisibility()== View.VISIBLE) {
220 | //头部完全收缩
221 | if (canChildScrollDown(listView)) {
222 | //底部还可以继续往下滚动
223 | intercepted = false;
224 | } else {
225 | //底部已经滚动到了最顶,不能滚动了
226 | if (deltaY > 0) {
227 | //从上向下滚动拦截
228 | intercepted = true;
229 | } else {
230 | //从下向上滚动不拦截
231 | intercepted = false;
232 | }
233 | }
234 | } else {
235 | intercepted = true;
236 | }
237 | }
238 | }
239 | break;
240 | case MotionEvent.ACTION_UP:
241 | intercepted = false;
242 | mLastYIntercept = 0;
243 | mLastXIntercept = 0;
244 | break;
245 | }
246 | if (event.getAction() == MotionEvent.ACTION_MOVE && intercepted) {
247 | //切换为月视图
248 | if (monthViewpager.getVisibility() != VISIBLE) {
249 | if (true) {
250 | monthViewpager.setVisibility(VISIBLE);
251 | weekviewpager.setVisibility(GONE);
252 | if(handler!=null){
253 | Message msg=new Message();
254 | msg.what=10;
255 | handler.sendMessage(msg);
256 | }
257 | // mHeader.setAdapter(monthCalendarAdpter);
258 | // //设置高度
259 | // ViewGroup.LayoutParams params = mHeader.getLayoutParams();
260 | // params.height = getContext().getResources()
261 | // .getDimensionPixelOffset(R.dimen.viewpager_month);//下次如果改了的话需要动态设置高度--月视图的情况为300dp
262 | // mHeader.setLayoutParams(params);
263 |
264 | //让viewpager滚动到相应的位置
265 | mHeader.scrollTo(mHeader.getScrollX(), hideTop);
266 | //给内容体设置相应的margintop[解决上下跳的问题]
267 | scrollCountY = headerOriginalHeight - hideBottom + hideTop;
268 | LayoutParams params2 = (LayoutParams) mContent.getLayoutParams();
269 | params2.setMargins(0, -MomentsUtils.dip2px(getContext(), 250), 0, 0);//月视图-周视图的高度
270 | mContent.setLayoutParams(params2);
271 |
272 | }
273 | }
274 | }
275 | return intercepted;
276 | }
277 |
278 | private int downY = 0;
279 |
280 | @Override
281 | public boolean onTouchEvent(MotionEvent event) {
282 | boolean canTouched = false;
283 | int x = (int) event.getX();
284 | int y = (int) event.getY();
285 | switch (event.getAction()) {
286 | case MotionEvent.ACTION_DOWN:
287 | mLastX = x;
288 | mLastY = y;
289 | break;
290 | case MotionEvent.ACTION_MOVE:
291 | if (mLastX != 0 && mLastY != 0) {
292 | //因为 ACTION_DOWN拦截不到,所以通过mLastX,mLastY是否有值来完成
293 | int deltaX = x - mLastX;
294 | deltaY = y - mLastY;
295 | if (Math.abs(deltaY) > Math.abs(deltaX)) {
296 | moveToScroll(-deltaY);
297 | canTouched = true;
298 | } else {
299 | canTouched = false;
300 | }
301 | }
302 | mLastX = x;
303 | mLastY = y;
304 | Log.i(getClass().getName(), " MotionEvent.ACTION_MOVE");
305 |
306 | break;
307 | case MotionEvent.ACTION_UP:
308 | if (deltaY > 0) {
309 | Log.i(getClass().getName(), "MotionEvent.ACTION_UP+(mContent.getTop() - mHeader.getTop()):" + (mContent.getTop() - mHeader.getTop()));
310 | Log.i(getClass().getName(), "MotionEvent.ACTION_UP+(hideBottom - hideTop):" + (hideBottom - hideTop));
311 | Log.i(getClass().getName(), "MotionEvent.ACTION_UP+deltaY" + deltaY);
312 | Log.i(getClass().getName(), "MotionEvent.ACTION_UP+minDistance:" + (minDistance));
313 | //从上向下滚动,判断一下最终距离
314 | if (mContent.getTop() - mHeader.getTop() >= (hideBottom - hideTop) || deltaY > minDistance) {
315 | //拉伸的长度足够,可以展开,如果还没有完全展开则使用动画
316 | //向下拉伸长度够了,可以展开
317 | smoothExpand(-deltaY);
318 | } else {
319 | //拉伸的长度不够,还是要恢复刚才的状态
320 | smoothCollapse(-minDistance);
321 | }
322 |
323 | } else {
324 | //从下向上滚动不拦截
325 | if (mHeader.getScrollY() >= hideBottom - hideTop || (scrollCountY >= hideBottom - hideTop && mHeader.getScrollY() == 0) || deltaY < -minDistance) {
326 | //拉伸的长度足够,可以展开,如果还没有完全展开则使用动画
327 | smoothCollapse(-deltaY);
328 | } else {
329 | //拉伸的长度不够,还是要恢复刚才的状态
330 | smoothExpand(minDistance);
331 | }
332 | }
333 |
334 |
335 | mLastX = 0;
336 | mLastY = 0;
337 | canTouched = false;
338 |
339 | break;
340 | }
341 | return canTouched;
342 | }
343 |
344 |
345 | /**
346 | * 判断scrollview / listview是否能滑动
347 | *
348 | * @param view
349 | * @return
350 | */
351 | public boolean canChildScrollDown(View view) {
352 | if (Build.VERSION.SDK_INT < 14) {
353 | if (view instanceof AbsListView) {
354 | final AbsListView absListView = (AbsListView) view;
355 | return absListView.getChildCount() > 0
356 | && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
357 | .getTop() < absListView.getPaddingTop());
358 | } else {
359 | return view.getScrollY() > 0;
360 | }
361 | } else {
362 | boolean canScrollVertically = view.canScrollVertically(-1);
363 | return canScrollVertically;
364 | }
365 | }
366 |
367 |
368 | /**
369 | * 设置当前选中日期所属行
370 | *
371 | * @param rowNum
372 | */
373 | public void setRowNum(int rowNum) {
374 | int dimensionPixelSize = getResources().getDimensionPixelSize(R.dimen.calendat_height);
375 | hideTop = rowNum * dimensionPixelSize;
376 | hideBottom = (rowNum + 1) * dimensionPixelSize;
377 | }
378 |
379 |
380 | /**
381 | * 惯性展开
382 | *
383 | * @param deltaY
384 | */
385 | private void smoothExpand(int deltaY) {
386 | final int distanceY = Math.min(-Math.abs(deltaY), -minDistance);
387 | new Thread("Thread#smoothCollapse") {
388 | @Override
389 | public void run() {
390 | while (scrollCountY + distanceY >= 0) {
391 | isInAnimation = true;
392 | scrollCountY += distanceY;
393 | post(new Runnable() {
394 | public void run() {
395 | Log.e("dd", "scrollCountY ==" + scrollCountY);
396 | if (scrollCountY >= 0 && scrollCountY <= hideTop) {
397 | mHeader.scrollTo(mHeader.getScrollX(), scrollCountY);
398 | } else {
399 | mHeader.scrollTo(mHeader.getScrollX(), hideTop);
400 | }
401 | LayoutParams params2 = (LayoutParams) mContent.getLayoutParams();
402 | params2.setMargins(0, -scrollCountY, 0, 0);
403 | mContent.setLayoutParams(params2);
404 |
405 | }
406 | });
407 | try {
408 | Thread.sleep(20);
409 | } catch (InterruptedException e) {
410 | e.printStackTrace();
411 | }
412 | }
413 | post(new Runnable() {
414 | public void run() {
415 | mHeader.scrollTo(mHeader.getScrollX(), 0);
416 | scrollCountY = 0;
417 | LayoutParams params = (LayoutParams) mContent.getLayoutParams();
418 | params.setMargins(0, 0, 0, 0);
419 | mContent.setLayoutParams(params);
420 | isInAnimation = false;
421 | }
422 | });
423 | }
424 | }.start();
425 | }
426 |
427 |
428 | /**
429 | * 惯性收缩
430 | *
431 | * @param deltaY
432 | */
433 | public void smoothCollapse(int deltaY) {
434 | final int distanceY = Math.max(Math.abs(deltaY), minDistance);
435 | new Thread("Thread#smoothCollapse") {
436 | @Override
437 | public void run() {
438 | while (Math.abs(scrollCountY + distanceY) <= Math.abs(headerOriginalHeight - hideBottom + hideTop)) {
439 | isInAnimation = true;
440 | scrollCountY += distanceY;
441 | post(new Runnable() {
442 | public void run() {
443 | if (scrollCountY >= 0 && scrollCountY <= hideTop) {
444 | mHeader.scrollTo(mHeader.getScrollX(), scrollCountY);
445 | } else {
446 | mHeader.scrollTo(mHeader.getScrollX(), hideTop);
447 | }
448 | LayoutParams params2 = (LayoutParams) mContent.getLayoutParams();
449 | params2.setMargins(0, -scrollCountY, 0, 0);
450 | mContent.setLayoutParams(params2);
451 |
452 | }
453 | });
454 | try {
455 | Thread.sleep(20);
456 | } catch (InterruptedException e) {
457 | e.printStackTrace();
458 | }
459 | }
460 | collapse();
461 | }
462 | }.start();
463 | }
464 |
465 | public void collapse() {
466 | post(new Runnable() {
467 | public void run() {
468 | mHeader.scrollTo(mHeader.getScrollX(), hideTop);
469 | scrollCountY = headerOriginalHeight - hideBottom + hideTop;
470 | LayoutParams params2 = (LayoutParams) mContent.getLayoutParams();
471 | params2.setMargins(0, -(headerOriginalHeight - hideBottom + hideTop), 0, 0);
472 | mContent.setLayoutParams(params2);
473 | isInAnimation = false;
474 | //切换为周视图
475 | if (weekviewpager.getVisibility() != VISIBLE) {
476 | if (true) {
477 | if(handler!=null){
478 | Message msg=new Message();
479 | msg.what=10;
480 | handler.sendMessage(msg);
481 | }
482 | monthViewpager.setVisibility(GONE);
483 | weekviewpager.setVisibility(VISIBLE);
484 | // //设置高度
485 | // ViewGroup.LayoutParams params = mHeader.getLayoutParams();
486 | // params.height = getContext().getResources()
487 | // .getDimensionPixelOffset(R.dimen.viewpager_week);
488 | // //下次如果改了的话需要动态设置高度--周视图的高度为50dp
489 | // mHeader.setLayoutParams(params);
490 |
491 | scrollCountY = headerOriginalHeight - hideBottom + hideTop;
492 | LayoutParams params3 = (LayoutParams) mContent.getLayoutParams();
493 | params3.setMargins(0, 0, 0, 0);
494 | mContent.setLayoutParams(params3);
495 | }
496 |
497 | }
498 | }
499 | });
500 | }
501 |
502 | /**
503 | * 手指移动时的
504 | *
505 | * @param distanceY
506 | */
507 | private void moveToScroll(float distanceY) {
508 | scrollCountY = scrollCountY + (int) distanceY;
509 | if ((scrollCountY >= 0 && scrollCountY <= hideTop)) {
510 | //判断顶部是否还能往上顶
511 | mHeader.scrollTo(mHeader.getScrollX(), scrollCountY);
512 | LayoutParams params = (LayoutParams) mContent.getLayoutParams();
513 | params.setMargins(0, -scrollCountY, 0, 0);
514 | mContent.setLayoutParams(params);
515 | } else {
516 | if (scrollCountY <= 0) {
517 | //滑动到了底部
518 | //重新设值是因为float转int会有精度丢失的问题
519 | mHeader.scrollTo(mHeader.getScrollX(), 0);
520 | scrollCountY = 0;
521 |
522 | LayoutParams params = (LayoutParams) mContent.getLayoutParams();
523 | params.setMargins(0, 0, 0, 0);
524 | mContent.setLayoutParams(params);
525 |
526 | } else if (scrollCountY > hideTop) {
527 | //日历头滑动到了顶部
528 | mHeader.scrollTo(mHeader.getScrollX(), hideTop);
529 |
530 | if (scrollCountY <= headerOriginalHeight - hideBottom + hideTop + distanceY) {
531 | if (scrollCountY <= headerOriginalHeight - hideBottom + hideTop) {
532 | LayoutParams params2 = (LayoutParams) mContent.getLayoutParams();
533 | params2.setMargins(0, -scrollCountY, 0, 0);
534 | mContent.setLayoutParams(params2);
535 | } else {
536 | LayoutParams params2 = (LayoutParams) mContent.getLayoutParams();
537 | params2.setMargins(0, -(headerOriginalHeight - hideBottom + hideTop), 0, 0);
538 | mContent.setLayoutParams(params2);
539 | }
540 | }
541 |
542 | }
543 | }
544 | }
545 |
546 | }
547 |
--------------------------------------------------------------------------------
/MyCalendar/app/src/main/java/choosetime/com/example/chen/mycalendar/calendar/CalendarUtil.java:
--------------------------------------------------------------------------------
1 | package choosetime.com.example.chen.mycalendar.calendar;
2 |
3 | /**
4 | * Created by Administrator on 2016/1/16 0016.
5 | */
6 | public class CalendarUtil {
7 | private int gregorianYear;
8 | private int gregorianMonth;
9 | private int gregorianDate;
10 | private boolean isGregorianLeap;
11 | private int dayOfYear;
12 | private int dayOfWeek; // 周日一星期的第一天
13 | private int chineseYear;
14 | private int chineseMonth; // 负数表示闰月
15 | private int chineseDate;
16 | private int sectionalTerm;
17 | private int principleTerm;
18 | private static char[] daysInGregorianMonth = { 31, 28, 31, 30, 31, 30, 31,
19 | 31, 30, 31, 30, 31 };
20 | private static String[] stemNames = { "甲", "乙", "丙", "丁", "戊", "己", "庚",
21 | "辛", "壬", "癸" };
22 | private static String[] branchNames = { "子", "丑", "寅", "卯", "辰", "巳", "午",
23 | "未", "申", "酉", "戌", "亥" };
24 | private static String[] animalNames = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马",
25 | "羊", "猴", "鸡", "狗", "猪" };
26 |
27 |
28 | public static final String[] daysOfMonth = { "1", "2", "3", "4", "5", "6",
29 | "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17",
30 | "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28",
31 | "29", "30", "31" };
32 |
33 |
34 | private String monthOfAlmanac[] = {"正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","冬月","腊月"};
35 | private String daysOfAlmanac[] = { "初一", "初二", "初三", "初四", "初五", "初六",
36 | "初七", "初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七",
37 | "十八", "十九", "二十", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八",
38 | "廿九", "三十" }; // 农历的天数
39 |
40 |
41 | public CalendarUtil() {
42 | setGregorian(1901, 1, 1);
43 | }
44 |
45 |
46 | /**
47 | * 得到对应天的农历 要判断闰月 月初 月末 *
48 | * @param y
49 | * @param m
50 | * @param d
51 | * @return String
52 | */
53 | public String getChineseDay(int y, int m, int d) {
54 |
55 |
56 | CalendarUtil c = new CalendarUtil();
57 |
58 |
59 | c.setGregorian(y, m, d);
60 | c.computeChineseFields();
61 | c.computeSolarTerms();
62 |
63 |
64 | int cd = c.getChineseDate();
65 |
66 |
67 | return daysOfAlmanac[cd - 1];
68 | }
69 |
70 |
71 | /**
72 | * 得到对应天的农历
73 | * 要判断闰月 月初 月末
74 | * @param y
75 | * @param m
76 | * @param d
77 | * @return
78 | */
79 | public String getChineseMonth(int y, int m, int d) {
80 | setGregorian(y,m,d);
81 | computeChineseFields();
82 | computeSolarTerms();
83 |
84 | int cd = getChineseMonth();
85 | if(cd < 1 || cd > 29)
86 | cd = 1;
87 | return monthOfAlmanac[cd -1];
88 | }
89 |
90 | public void setGregorian(int y, int m, int d) {
91 | gregorianYear = y;
92 | gregorianMonth = m;
93 | gregorianDate = d;
94 | isGregorianLeap = isGregorianLeapYear(y);
95 | dayOfYear = dayOfYear(y, m, d);
96 | dayOfWeek = dayOfWeek(y, m, d);
97 | chineseYear = 0;
98 | chineseMonth = 0;
99 | chineseDate = 0;
100 | sectionalTerm = 0;
101 | principleTerm = 0;
102 | }
103 |
104 |
105 | // 判断是否是闰年
106 | public static boolean isGregorianLeapYear(int year) {
107 | boolean isLeap = false;
108 | if (year % 4 == 0)
109 | isLeap = true;
110 | if (year % 100 == 0)
111 | isLeap = false;
112 | if (year % 400 == 0)
113 | isLeap = true;
114 | return isLeap;
115 | }
116 |
117 |
118 | // 返回一个月有几天
119 | public static int daysInGregorianMonth(int y, int m) {
120 | int d = daysInGregorianMonth[m - 1];
121 | if (m == 2 && isGregorianLeapYear(y))
122 | d++; // 公历闰年二月多一天
123 | return d;
124 | }
125 |
126 |
127 | // 计算当前天在本年中是第几天
128 | public static int dayOfYear(int y, int m, int d) {
129 | int c = 0;
130 | for (int i = 1; i < m; i++) {
131 | c = c + daysInGregorianMonth(y, i);
132 | }
133 | c = c + d;
134 | return c;
135 | }
136 |
137 |
138 | // 当前天是本周的第几天 , 从星期天开始算
139 | public static int dayOfWeek(int y, int m, int d) {
140 | int w = 1; // 公历一年一月一日是星期一,所以起始值为星期日
141 | y = (y - 1) % 400 + 1; // 公历星期值分部 400 年循环一次
142 | int ly = (y - 1) / 4; // 闰年次数
143 | ly = ly - (y - 1) / 100;
144 | ly = ly + (y - 1) / 400;
145 | int ry = y - 1 - ly; // 常年次数
146 | w = w + ry; // 常年星期值增一
147 | w = w + 2 * ly; // 闰年星期值增二
148 | w = w + dayOfYear(y, m, d);
149 | w = (w - 1) % 7 + 1;
150 | return w;
151 | }
152 |
153 |
154 | // 农历月份大小压缩表,两个字节表示一年。两个字节共十六个二进制位数,
155 | // 前四个位数表示闰月月份,后十二个位数表示十二个农历月份的大小。
156 | private static char[] chineseMonths = { 0x00, 0x04, 0xad, 0x08, 0x5a, 0x01,
157 | 0xd5, 0x54, 0xb4, 0x09, 0x64, 0x05, 0x59, 0x45, 0x95, 0x0a, 0xa6,
158 | 0x04, 0x55, 0x24, 0xad, 0x08, 0x5a, 0x62, 0xda, 0x04, 0xb4, 0x05,
159 | 0xb4, 0x55, 0x52, 0x0d, 0x94, 0x0a, 0x4a, 0x2a, 0x56, 0x02, 0x6d,
160 | 0x71, 0x6d, 0x01, 0xda, 0x02, 0xd2, 0x52, 0xa9, 0x05, 0x49, 0x0d,
161 | 0x2a, 0x45, 0x2b, 0x09, 0x56, 0x01, 0xb5, 0x20, 0x6d, 0x01, 0x59,
162 | 0x69, 0xd4, 0x0a, 0xa8, 0x05, 0xa9, 0x56, 0xa5, 0x04, 0x2b, 0x09,
163 | 0x9e, 0x38, 0xb6, 0x08, 0xec, 0x74, 0x6c, 0x05, 0xd4, 0x0a, 0xe4,
164 | 0x6a, 0x52, 0x05, 0x95, 0x0a, 0x5a, 0x42, 0x5b, 0x04, 0xb6, 0x04,
165 | 0xb4, 0x22, 0x6a, 0x05, 0x52, 0x75, 0xc9, 0x0a, 0x52, 0x05, 0x35,
166 | 0x55, 0x4d, 0x0a, 0x5a, 0x02, 0x5d, 0x31, 0xb5, 0x02, 0x6a, 0x8a,
167 | 0x68, 0x05, 0xa9, 0x0a, 0x8a, 0x6a, 0x2a, 0x05, 0x2d, 0x09, 0xaa,
168 | 0x48, 0x5a, 0x01, 0xb5, 0x09, 0xb0, 0x39, 0x64, 0x05, 0x25, 0x75,
169 | 0x95, 0x0a, 0x96, 0x04, 0x4d, 0x54, 0xad, 0x04, 0xda, 0x04, 0xd4,
170 | 0x44, 0xb4, 0x05, 0x54, 0x85, 0x52, 0x0d, 0x92, 0x0a, 0x56, 0x6a,
171 | 0x56, 0x02, 0x6d, 0x02, 0x6a, 0x41, 0xda, 0x02, 0xb2, 0xa1, 0xa9,
172 | 0x05, 0x49, 0x0d, 0x0a, 0x6d, 0x2a, 0x09, 0x56, 0x01, 0xad, 0x50,
173 | 0x6d, 0x01, 0xd9, 0x02, 0xd1, 0x3a, 0xa8, 0x05, 0x29, 0x85, 0xa5,
174 | 0x0c, 0x2a, 0x09, 0x96, 0x54, 0xb6, 0x08, 0x6c, 0x09, 0x64, 0x45,
175 | 0xd4, 0x0a, 0xa4, 0x05, 0x51, 0x25, 0x95, 0x0a, 0x2a, 0x72, 0x5b,
176 | 0x04, 0xb6, 0x04, 0xac, 0x52, 0x6a, 0x05, 0xd2, 0x0a, 0xa2, 0x4a,
177 | 0x4a, 0x05, 0x55, 0x94, 0x2d, 0x0a, 0x5a, 0x02, 0x75, 0x61, 0xb5,
178 | 0x02, 0x6a, 0x03, 0x61, 0x45, 0xa9, 0x0a, 0x4a, 0x05, 0x25, 0x25,
179 | 0x2d, 0x09, 0x9a, 0x68, 0xda, 0x08, 0xb4, 0x09, 0xa8, 0x59, 0x54,
180 | 0x03, 0xa5, 0x0a, 0x91, 0x3a, 0x96, 0x04, 0xad, 0xb0, 0xad, 0x04,
181 | 0xda, 0x04, 0xf4, 0x62, 0xb4, 0x05, 0x54, 0x0b, 0x44, 0x5d, 0x52,
182 | 0x0a, 0x95, 0x04, 0x55, 0x22, 0x6d, 0x02, 0x5a, 0x71, 0xda, 0x02,
183 | 0xaa, 0x05, 0xb2, 0x55, 0x49, 0x0b, 0x4a, 0x0a, 0x2d, 0x39, 0x36,
184 | 0x01, 0x6d, 0x80, 0x6d, 0x01, 0xd9, 0x02, 0xe9, 0x6a, 0xa8, 0x05,
185 | 0x29, 0x0b, 0x9a, 0x4c, 0xaa, 0x08, 0xb6, 0x08, 0xb4, 0x38, 0x6c,
186 | 0x09, 0x54, 0x75, 0xd4, 0x0a, 0xa4, 0x05, 0x45, 0x55, 0x95, 0x0a,
187 | 0x9a, 0x04, 0x55, 0x44, 0xb5, 0x04, 0x6a, 0x82, 0x6a, 0x05, 0xd2,
188 | 0x0a, 0x92, 0x6a, 0x4a, 0x05, 0x55, 0x0a, 0x2a, 0x4a, 0x5a, 0x02,
189 | 0xb5, 0x02, 0xb2, 0x31, 0x69, 0x03, 0x31, 0x73, 0xa9, 0x0a, 0x4a,
190 | 0x05, 0x2d, 0x55, 0x2d, 0x09, 0x5a, 0x01, 0xd5, 0x48, 0xb4, 0x09,
191 | 0x68, 0x89, 0x54, 0x0b, 0xa4, 0x0a, 0xa5, 0x6a, 0x95, 0x04, 0xad,
192 | 0x08, 0x6a, 0x44, 0xda, 0x04, 0x74, 0x05, 0xb0, 0x25, 0x54, 0x03 };
193 |
194 |
195 | // 初始日,公历农历对应日期:
196 | // 公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日
197 | private static int baseYear = 1901;
198 | private static int baseMonth = 1;
199 | private static int baseDate = 1;
200 | private static int baseIndex = 0;
201 | private static int baseChineseYear = 4598 - 1;
202 | private static int baseChineseMonth = 11;
203 | private static int baseChineseDate = 11;
204 |
205 |
206 | public int computeChineseFields() {
207 | if (gregorianYear < 1901 || gregorianYear > 2100)
208 | return 1;
209 | int startYear = baseYear;
210 | int startMonth = baseMonth;
211 | int startDate = baseDate;
212 | chineseYear = baseChineseYear;
213 | chineseMonth = baseChineseMonth;
214 | chineseDate = baseChineseDate;
215 | // 第二个对应日,用以提高计算效率
216 | // 公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日
217 | if (gregorianYear >= 2000) {
218 | startYear = baseYear + 99;
219 | startMonth = 1;
220 | startDate = 1;
221 | chineseYear = baseChineseYear + 99;
222 | chineseMonth = 11;
223 | chineseDate = 25;
224 | }
225 | int daysDiff = 0;
226 | for (int i = startYear; i < gregorianYear; i++) {
227 | daysDiff += 365;
228 | if (isGregorianLeapYear(i))
229 | daysDiff += 1; // leap year
230 | }
231 | for (int i = startMonth; i < gregorianMonth; i++) {
232 | daysDiff += daysInGregorianMonth(gregorianYear, i);
233 | }
234 | daysDiff += gregorianDate - startDate;
235 |
236 |
237 | chineseDate += daysDiff;
238 | int lastDate = daysInChineseMonth(chineseYear, chineseMonth);
239 | int nextMonth = nextChineseMonth(chineseYear, chineseMonth);
240 | while (chineseDate > lastDate) {
241 | if (Math.abs(nextMonth) < Math.abs(chineseMonth))
242 | chineseYear++;
243 | chineseMonth = nextMonth;
244 | chineseDate -= lastDate;
245 | lastDate = daysInChineseMonth(chineseYear, chineseMonth);
246 | nextMonth = nextChineseMonth(chineseYear, chineseMonth);
247 | }
248 | return 0;
249 | }
250 |
251 |
252 | private static int[] bigLeapMonthYears = {
253 | // 大闰月的闰年年份
254 | 6, 14, 19, 25, 33, 36, 38, 41, 44, 52, 55, 79, 117, 136, 147, 150,
255 | 155, 158, 185, 193 };
256 |
257 |
258 | public static int daysInChineseMonth(int y, int m) {
259 | // 注意:闰月 m < 0
260 | int index = y - baseChineseYear + baseIndex;
261 | int v = 0;
262 | int l = 0;
263 | int d = 30;
264 | if (1 <= m && m <= 8) {
265 | v = chineseMonths[2 * index];
266 | l = m - 1;
267 | if (((v >> l) & 0x01) == 1)
268 | d = 29;
269 | } else if (9 <= m && m <= 12) {
270 | v = chineseMonths[2 * index + 1];
271 | l = m - 9;
272 | if (((v >> l) & 0x01) == 1)
273 | d = 29;
274 | } else {
275 | v = chineseMonths[2 * index + 1];
276 | v = (v >> 4) & 0x0F;
277 | if (v != Math.abs(m)) {
278 | d = 0;
279 | } else {
280 | d = 29;
281 | for (int i = 0; i < bigLeapMonthYears.length; i++) {
282 | if (bigLeapMonthYears[i] == index) {
283 | d = 30;
284 | break;
285 | }
286 | }
287 | }
288 | }
289 | return d;
290 | }
291 |
292 |
293 | public static int nextChineseMonth(int y, int m) {
294 | int n = Math.abs(m) + 1;
295 | if (m > 0) {
296 | int index = y - baseChineseYear + baseIndex;
297 | int v = chineseMonths[2 * index + 1];
298 | v = (v >> 4) & 0x0F;
299 | if (v == m)
300 | n = -m;
301 | }
302 | if (n == 13)
303 | n = 1;
304 | return n;
305 | }
306 |
307 |
308 | private static char[][] sectionalTermMap = {
309 | { 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5,
310 | 5, 5, 5, 4, 5, 5 },
311 | { 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3,
312 | 3, 4, 4, 3, 3, 3 },
313 | { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,
314 | 5, 5, 4, 5, 5, 5, 5 },
315 | { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4,
316 | 4, 5, 4, 4, 4, 4, 5 },
317 | { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,
318 | 5, 5, 4, 5, 5, 5, 5 },
319 | { 6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5,
320 | 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 },
321 | { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,
322 | 7, 7, 6, 6, 6, 7, 7 },
323 | { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,
324 | 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7 },
325 | { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,
326 | 7, 7, 6, 7, 7, 7, 7 },
327 | { 9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8,
328 | 8, 8, 7, 7, 8, 8, 8 },
329 | { 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7,
330 | 7, 7, 6, 6, 7, 7, 7 },
331 | { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,
332 | 7, 7, 6, 6, 6, 7, 7 } };
333 | private static char[][] sectionalTermYear = {
334 | { 13, 49, 85, 117, 149, 185, 201, 250, 250 },
335 | { 13, 45, 81, 117, 149, 185, 201, 250, 250 },
336 | { 13, 48, 84, 112, 148, 184, 200, 201, 250 },
337 | { 13, 45, 76, 108, 140, 172, 200, 201, 250 },
338 | { 13, 44, 72, 104, 132, 168, 200, 201, 250 },
339 | { 5, 33, 68, 96, 124, 152, 188, 200, 201 },
340 | { 29, 57, 85, 120, 148, 176, 200, 201, 250 },
341 | { 13, 48, 76, 104, 132, 168, 196, 200, 201 },
342 | { 25, 60, 88, 120, 148, 184, 200, 201, 250 },
343 | { 16, 44, 76, 108, 144, 172, 200, 201, 250 },
344 | { 28, 60, 92, 124, 160, 192, 200, 201, 250 },
345 | { 17, 53, 85, 124, 156, 188, 200, 201, 250 } };
346 | private static char[][] principleTermMap = {
347 | { 21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20,
348 | 20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20 },
349 | { 20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19,
350 | 19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18 },
351 | { 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21,
352 | 20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20 },
353 | { 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20,
354 | 19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20 },
355 | { 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21,
356 | 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21 },
357 | { 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22,
358 | 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21 },
359 | { 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23,
360 | 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23 },
361 | { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,
362 | 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 },
363 | { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,
364 | 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 },
365 | { 24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24,
366 | 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23 },
367 | { 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23,
368 | 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22 },
369 | { 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22,
370 | 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22 } };
371 | private static char[][] principleTermYear = {
372 | { 13, 45, 81, 113, 149, 185, 201 },
373 | { 21, 57, 93, 125, 161, 193, 201 },
374 | { 21, 56, 88, 120, 152, 188, 200, 201 },
375 | { 21, 49, 81, 116, 144, 176, 200, 201 },
376 | { 17, 49, 77, 112, 140, 168, 200, 201 },
377 | { 28, 60, 88, 116, 148, 180, 200, 201 },
378 | { 25, 53, 84, 112, 144, 172, 200, 201 },
379 | { 29, 57, 89, 120, 148, 180, 200, 201 },
380 | { 17, 45, 73, 108, 140, 168, 200, 201 },
381 | { 28, 60, 92, 124, 160, 192, 200, 201 },
382 | { 16, 44, 80, 112, 148, 180, 200, 201 },
383 | { 17, 53, 88, 120, 156, 188, 200, 201 } };
384 |
385 |
386 | public int computeSolarTerms() {
387 | if (gregorianYear < 1901 || gregorianYear > 2100)
388 | return 1;
389 | sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth);
390 | principleTerm = principleTerm(gregorianYear, gregorianMonth);
391 | return 0;
392 | }
393 |
394 |
395 | public static int sectionalTerm(int y, int m) {
396 | if (y < 1901 || y > 2100)
397 | return 0;
398 | int index = 0;
399 | int ry = y - baseYear + 1;
400 | while (ry >= sectionalTermYear[m - 1][index])
401 | index++;
402 | int term = sectionalTermMap[m - 1][4 * index + ry % 4];
403 | if ((ry == 121) && (m == 4))
404 | term = 5;
405 | if ((ry == 132) && (m == 4))
406 | term = 5;
407 | if ((ry == 194) && (m == 6))
408 | term = 6;
409 | return term;
410 | }
411 |
412 |
413 | public static int principleTerm(int y, int m) {
414 | if (y < 1901 || y > 2100)
415 | return 0;
416 | int index = 0;
417 | int ry = y - baseYear + 1;
418 | while (ry >= principleTermYear[m - 1][index])
419 | index++;
420 | int term = principleTermMap[m - 1][4 * index + ry % 4];
421 | if ((ry == 171) && (m == 3))
422 | term = 21;
423 | if ((ry == 181) && (m == 5))
424 | term = 21;
425 | return term;
426 | }
427 |
428 |
429 | public String toString() {
430 | StringBuffer buf = new StringBuffer();
431 | buf.append("Gregorian Year: " + gregorianYear + "\n");
432 | buf.append("Gregorian Month: " + gregorianMonth + "\n");
433 | buf.append("Gregorian Date: " + gregorianDate + "\n");
434 | buf.append("Is Leap Year: " + isGregorianLeap + "\n");
435 | buf.append("Day of Year: " + dayOfYear + "\n");
436 | buf.append("Day of Week: " + dayOfWeek + "\n");
437 | buf.append("Chinese Year: " + chineseYear + "\n");
438 | buf.append("Heavenly Stem: " + ((chineseYear - 1) % 10) + "\n");
439 | buf.append("Earthly Branch: " + ((chineseYear - 1) % 12) + "\n");
440 | buf.append("Chinese Month: " + chineseMonth + "\n");
441 | buf.append("Chinese Date: " + chineseDate + "\n");
442 | buf.append("Sectional Term: " + sectionalTerm + "\n");
443 | buf.append("Principle Term: " + principleTerm + "\n");
444 | return buf.toString();
445 | }
446 |
447 |
448 | public String[] getYearTable() {
449 | setGregorian(gregorianYear, 1, 1);
450 | computeChineseFields();
451 | computeSolarTerms();
452 | String[] table = new String[58]; // 6*9 + 4
453 | table[0] = getTextLine(27, "公历年历:" + gregorianYear);
454 | table[1] = getTextLine(27, "农历年历:" + (chineseYear + 1) + " ("
455 | + stemNames[(chineseYear + 1 - 1) % 10]
456 | + branchNames[(chineseYear + 1 - 1) % 12] + " - "
457 | + animalNames[(chineseYear + 1 - 1) % 12] + "年)");
458 | int ln = 2;
459 | String blank = " " + " "
460 | + " ";
461 | String[] mLeft = null;
462 | String[] mRight = null;
463 | for (int i = 1; i <= 6; i++) {
464 | table[ln] = blank;
465 | ln++;
466 | mLeft = getMonthTable();
467 | mRight = getMonthTable();
468 | for (int j = 0; j < mLeft.length; j++) {
469 | String line = mLeft[j] + " " + mRight[j];
470 | table[ln] = line;
471 | ln++;
472 | }
473 | }
474 | table[ln] = blank;
475 | ln++;
476 | table[ln] = getTextLine(0, "##/## - 公历日期/农历日期,(*)#月 - (闰)农历月第一天");
477 | ln++;
478 | return table;
479 | }
480 |
481 |
482 | public static String getTextLine(int s, String t) {
483 | String str = " " + " "
484 | + " ";
485 | if (t != null && s < str.length() && s + t.length() < str.length())
486 | str = str.substring(0, s) + t + str.substring(s + t.length());
487 | return str;
488 | }
489 |
490 |
491 | private static String[] monthNames = { "一", "二", "三", "四", "五", "六", "七",
492 | "八", "九", "十", "十一", "十二" };
493 |
494 |
495 | public String[] getMonthTable() {
496 | setGregorian(gregorianYear, gregorianMonth, 1);
497 | computeChineseFields();
498 | computeSolarTerms();
499 | String[] table = new String[8];
500 | String title = null;
501 | if (gregorianMonth < 11)
502 | title = " ";
503 | else
504 | title = " ";
505 | title = title + monthNames[gregorianMonth - 1] + "月"
506 | + " ";
507 | String header = " 日 一 二 三 四 五 六 ";
508 | String blank = " ";
509 | table[0] = title;
510 | table[1] = header;
511 | int wk = 2;
512 | String line = "";
513 | for (int i = 1; i < dayOfWeek; i++) {
514 | line += " " + ' ';
515 | }
516 | int days = daysInGregorianMonth(gregorianYear, gregorianMonth);
517 | for (int i = gregorianDate; i <= days; i++) {
518 | line += getDateString() + ' ';
519 | rollUpOneDay();
520 | if (dayOfWeek == 1) {
521 | table[wk] = line;
522 | line = "";
523 | wk++;
524 | }
525 | }
526 | for (int i = dayOfWeek; i <= 7; i++) {
527 | line += " " + ' ';
528 | }
529 | table[wk] = line;
530 | for (int i = wk + 1; i < table.length; i++) {
531 | table[i] = blank;
532 | }
533 | for (int i = 0; i < table.length; i++) {
534 | table[i] = table[i].substring(0, table[i].length() - 1);
535 | }
536 |
537 |
538 | return table;
539 | }
540 |
541 |
542 | private static String[] chineseMonthNames = { "正", "二", "三", "四", "五", "六",
543 | "七", "八", "九", "十", "冬", "腊" };
544 | private static String[] principleTermNames = { "雨水", "春分", "谷雨", "夏满",
545 | "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至", "大寒" };
546 | private static String[] sectionalTermNames = { "立春", "惊蛰", "清明", "立夏",
547 | "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪", "小寒" };
548 |
549 |
550 | public String getDateString() {
551 | String str = "* / ";
552 | String gm = String.valueOf(gregorianMonth);
553 | if (gm.length() == 1)
554 | gm = ' ' + gm;
555 | String cm = String.valueOf(Math.abs(chineseMonth));
556 | if (cm.length() == 1)
557 | cm = ' ' + cm;
558 | String gd = String.valueOf(gregorianDate);
559 | if (gd.length() == 1)
560 | gd = ' ' + gd;
561 | String cd = String.valueOf(chineseDate);
562 | if (cd.length() == 1)
563 | cd = ' ' + cd;
564 | if (gregorianDate == sectionalTerm) {
565 | str = " " + sectionalTermNames[gregorianMonth - 1];
566 | } else if (gregorianDate == principleTerm) {
567 | str = " " + principleTermNames[gregorianMonth - 1];
568 | } else if (chineseDate == 1 && chineseMonth > 0) {
569 | str = " " + chineseMonthNames[chineseMonth - 1] + "月";
570 | } else if (chineseDate == 1 && chineseMonth < 0) {
571 | str = "*" + chineseMonthNames[-chineseMonth - 1] + "月";
572 | } else {
573 | str = gd + '/' + cd;
574 | }
575 | return str;
576 | }
577 |
578 |
579 | public int rollUpOneDay() {
580 | dayOfWeek = dayOfWeek % 7 + 1;
581 | dayOfYear++;
582 | gregorianDate++;
583 | int days = daysInGregorianMonth(gregorianYear, gregorianMonth);
584 | if (gregorianDate > days) {
585 | gregorianDate = 1;
586 | gregorianMonth++;
587 | if (gregorianMonth > 12) {
588 | gregorianMonth = 1;
589 | gregorianYear++;
590 | dayOfYear = 1;
591 | isGregorianLeap = isGregorianLeapYear(gregorianYear);
592 | }
593 | sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth);
594 | principleTerm = principleTerm(gregorianYear, gregorianMonth);
595 | }
596 | chineseDate++;
597 | days = daysInChineseMonth(chineseYear, chineseMonth);
598 | if (chineseDate > days) {
599 | chineseDate = 1;
600 | chineseMonth = nextChineseMonth(chineseYear, chineseMonth);
601 | if (chineseMonth == 1)
602 | chineseYear++;
603 | }
604 | return 0;
605 | }
606 |
607 |
608 | public int getGregorianYear() {
609 | return gregorianYear;
610 | }
611 |
612 |
613 | public void setGregorianYear(int gregorianYear) {
614 | this.gregorianYear = gregorianYear;
615 | }
616 |
617 |
618 | public int getGregorianMonth() {
619 | return gregorianMonth;
620 | }
621 |
622 |
623 | public void setGregorianMonth(int gregorianMonth) {
624 | this.gregorianMonth = gregorianMonth;
625 | }
626 |
627 |
628 | public int getGregorianDate() {
629 | return gregorianDate;
630 | }
631 |
632 |
633 | public void setGregorianDate(int gregorianDate) {
634 | this.gregorianDate = gregorianDate;
635 | }
636 |
637 |
638 | public boolean isGregorianLeap() {
639 | return isGregorianLeap;
640 | }
641 |
642 |
643 | public void setGregorianLeap(boolean isGregorianLeap) {
644 | this.isGregorianLeap = isGregorianLeap;
645 | }
646 |
647 |
648 | public int getDayOfYear() {
649 | return dayOfYear;
650 | }
651 |
652 |
653 | public void setDayOfYear(int dayOfYear) {
654 | this.dayOfYear = dayOfYear;
655 | }
656 |
657 |
658 | public int getDayOfWeek() {
659 | return dayOfWeek;
660 | }
661 |
662 |
663 | public void setDayOfWeek(int dayOfWeek) {
664 | this.dayOfWeek = dayOfWeek;
665 | }
666 |
667 |
668 | public int getChineseYear() {
669 | return chineseYear;
670 | }
671 |
672 |
673 | public void setChineseYear(int chineseYear) {
674 | this.chineseYear = chineseYear;
675 | }
676 |
677 |
678 | public int getChineseMonth() {
679 | return chineseMonth;
680 | }
681 |
682 |
683 | public void setChineseMonth(int chineseMonth) {
684 | this.chineseMonth = chineseMonth;
685 | }
686 |
687 |
688 | public int getChineseDate() {
689 | return chineseDate;
690 | }
691 |
692 |
693 | public void setChineseDate(int chineseDate) {
694 | this.chineseDate = chineseDate;
695 | }
696 |
697 |
698 | public int getSectionalTerm() {
699 | return sectionalTerm;
700 | }
701 |
702 |
703 | public void setSectionalTerm(int sectionalTerm) {
704 | this.sectionalTerm = sectionalTerm;
705 | }
706 |
707 |
708 | public int getPrincipleTerm() {
709 | return principleTerm;
710 | }
711 |
712 |
713 | public void setPrincipleTerm(int principleTerm) {
714 | this.principleTerm = principleTerm;
715 | }
716 |
717 |
718 | public static char[] getDaysInGregorianMonth() {
719 | return daysInGregorianMonth;
720 | }
721 |
722 |
723 | public static void setDaysInGregorianMonth(char[] daysInGregorianMonth) {
724 | CalendarUtil.daysInGregorianMonth = daysInGregorianMonth;
725 | }
726 |
727 |
728 | public static String[] getStemNames() {
729 | return stemNames;
730 | }
731 |
732 |
733 | public static void setStemNames(String[] stemNames) {
734 | CalendarUtil.stemNames = stemNames;
735 | }
736 |
737 |
738 | public static String[] getBranchNames() {
739 | return branchNames;
740 | }
741 |
742 |
743 | public static void setBranchNames(String[] branchNames) {
744 | CalendarUtil.branchNames = branchNames;
745 | }
746 |
747 |
748 | public static String[] getAnimalNames() {
749 | return animalNames;
750 | }
751 |
752 |
753 | public static void setAnimalNames(String[] animalNames) {
754 | CalendarUtil.animalNames = animalNames;
755 | }
756 |
757 |
758 | public static char[] getChineseMonths() {
759 | return chineseMonths;
760 | }
761 |
762 |
763 | public static void setChineseMonths(char[] chineseMonths) {
764 | CalendarUtil.chineseMonths = chineseMonths;
765 | }
766 |
767 |
768 | public static int getBaseYear() {
769 | return baseYear;
770 | }
771 |
772 |
773 | public static void setBaseYear(int baseYear) {
774 | CalendarUtil.baseYear = baseYear;
775 | }
776 |
777 |
778 | public static int getBaseMonth() {
779 | return baseMonth;
780 | }
781 |
782 |
783 | public static void setBaseMonth(int baseMonth) {
784 | CalendarUtil.baseMonth = baseMonth;
785 | }
786 |
787 |
788 | public static int getBaseDate() {
789 | return baseDate;
790 | }
791 |
792 |
793 | public static void setBaseDate(int baseDate) {
794 | CalendarUtil.baseDate = baseDate;
795 | }
796 |
797 |
798 | public static int getBaseIndex() {
799 | return baseIndex;
800 | }
801 |
802 |
803 | public static void setBaseIndex(int baseIndex) {
804 | CalendarUtil.baseIndex = baseIndex;
805 | }
806 |
807 |
808 | public static int getBaseChineseYear() {
809 | return baseChineseYear;
810 | }
811 |
812 |
813 | public static void setBaseChineseYear(int baseChineseYear) {
814 | CalendarUtil.baseChineseYear = baseChineseYear;
815 | }
816 |
817 |
818 | public static int getBaseChineseMonth() {
819 | return baseChineseMonth;
820 | }
821 |
822 |
823 | public static void setBaseChineseMonth(int baseChineseMonth) {
824 | CalendarUtil.baseChineseMonth = baseChineseMonth;
825 | }
826 |
827 |
828 | public static int getBaseChineseDate() {
829 | return baseChineseDate;
830 | }
831 |
832 |
833 | public static void setBaseChineseDate(int baseChineseDate) {
834 | CalendarUtil.baseChineseDate = baseChineseDate;
835 | }
836 |
837 |
838 | public static int[] getBigLeapMonthYears() {
839 | return bigLeapMonthYears;
840 | }
841 |
842 |
843 | public static void setBigLeapMonthYears(int[] bigLeapMonthYears) {
844 | CalendarUtil.bigLeapMonthYears = bigLeapMonthYears;
845 | }
846 |
847 |
848 | public static char[][] getSectionalTermMap() {
849 | return sectionalTermMap;
850 | }
851 |
852 |
853 | public static void setSectionalTermMap(char[][] sectionalTermMap) {
854 | CalendarUtil.sectionalTermMap = sectionalTermMap;
855 | }
856 |
857 |
858 | public static char[][] getSectionalTermYear() {
859 | return sectionalTermYear;
860 | }
861 |
862 |
863 | public static void setSectionalTermYear(char[][] sectionalTermYear) {
864 | CalendarUtil.sectionalTermYear = sectionalTermYear;
865 | }
866 |
867 |
868 | public static char[][] getPrincipleTermMap() {
869 | return principleTermMap;
870 | }
871 |
872 |
873 | public static void setPrincipleTermMap(char[][] principleTermMap) {
874 | CalendarUtil.principleTermMap = principleTermMap;
875 | }
876 |
877 |
878 | public static char[][] getPrincipleTermYear() {
879 | return principleTermYear;
880 | }
881 |
882 |
883 | public static void setPrincipleTermYear(char[][] principleTermYear) {
884 | CalendarUtil.principleTermYear = principleTermYear;
885 | }
886 |
887 |
888 | public static String[] getMonthNames() {
889 | return monthNames;
890 | }
891 |
892 |
893 | public static void setMonthNames(String[] monthNames) {
894 | CalendarUtil.monthNames = monthNames;
895 | }
896 |
897 |
898 | public static String[] getChineseMonthNames() {
899 | return chineseMonthNames;
900 | }
901 |
902 |
903 | public static void setChineseMonthNames(String[] chineseMonthNames) {
904 | CalendarUtil.chineseMonthNames = chineseMonthNames;
905 | }
906 |
907 |
908 | public static String[] getPrincipleTermNames() {
909 | return principleTermNames;
910 | }
911 |
912 |
913 | public static void setPrincipleTermNames(String[] principleTermNames) {
914 | CalendarUtil.principleTermNames = principleTermNames;
915 | }
916 |
917 |
918 | public static String[] getSectionalTermNames() {
919 | return sectionalTermNames;
920 | }
921 |
922 |
923 | public static void setSectionalTermNames(String[] sectionalTermNames) {
924 | CalendarUtil.sectionalTermNames = sectionalTermNames;
925 | }
926 |
927 |
928 | public static void main(String[] arg) {
929 | CalendarUtil c = new CalendarUtil();
930 | String cmd = "day";
931 | int y = 2010;
932 | int m = 8;
933 | int d = 11;
934 |
935 |
936 | c.setGregorian(y, m, d);
937 | c.computeChineseFields();
938 | c.computeSolarTerms();
939 |
940 |
941 | if (cmd.equalsIgnoreCase("year")) {
942 | String[] t = c.getYearTable();
943 | for (int i = 0; i < t.length; i++)
944 | System.out.println(t[i]);
945 | } else if (cmd.equalsIgnoreCase("month")) {
946 | String[] t = c.getMonthTable();
947 | for (int i = 0; i < t.length; i++)
948 | System.out.println(t[i]);
949 | } else {
950 | System.out.println(c.toString());
951 | }
952 | System.out.println(c.getDateString());
953 |
954 |
955 | }
956 |
957 | }
958 |
--------------------------------------------------------------------------------