Browse Source

对 https://github.com/AigeStudio/WheelPicker 进行的修改,并上传到我们自己的私有maven库

houjie 4 years ago
commit
71905b1761
43 changed files with 3618 additions and 0 deletions
  1. 2 0
      Demo/.gitignore
  2. 20 0
      Demo/build.gradle
  3. 17 0
      Demo/proguard-rules.pro
  4. 17 0
      Demo/src/main/AndroidManifest.xml
  5. BIN
      Demo/src/main/assets/yyg.ttf
  6. 75 0
      Demo/src/main/java/com/aigestudio/wheelpicker/demo/PreviewActivity.java
  7. 47 0
      Demo/src/main/res/layout/ac_area_picker.xml
  8. 68 0
      Demo/src/main/res/layout/ac_preview.xml
  9. BIN
      Demo/src/main/res/mipmap-mdpi/ic_launcher.png
  10. BIN
      Demo/src/main/res/mipmap-xhdpi/ic_launcher.png
  11. BIN
      Demo/src/main/res/mipmap-xxhdpi/ic_launcher.png
  12. 2 0
      WheelPicker/.gitignore
  13. 47 0
      WheelPicker/build.gradle
  14. 17 0
      WheelPicker/proguard-rules.pro
  15. 1 0
      WheelPicker/src/main/AndroidManifest.xml
  16. 17 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/IDebug.java
  17. 527 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/IWheelPicker.java
  18. 1225 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/WheelPicker.java
  19. 28 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/model/City.java
  20. 29 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/model/Province.java
  21. 15 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelAreaPicker.java
  22. 35 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelDatePicker.java
  23. 68 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelDayPicker.java
  24. 32 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelMonthPicker.java
  25. 68 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelYearPicker.java
  26. 172 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelAreaPicker.java
  27. 592 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelDatePicker.java
  28. 117 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelDayPicker.java
  29. 63 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelMonthPicker.java
  30. 100 0
      WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelYearPicker.java
  31. 48 0
      WheelPicker/src/main/res/layout-v17/view_wheel_date_picker.xml
  32. 48 0
      WheelPicker/src/main/res/layout/view_wheel_date_picker.xml
  33. 6 0
      WheelPicker/src/main/res/values-zh/strings.xml
  34. 38 0
      WheelPicker/src/main/res/values/arrays.xml
  35. 29 0
      WheelPicker/src/main/res/values/attrs.xml
  36. 7 0
      WheelPicker/src/main/res/values/dimens.xml
  37. 6 0
      WheelPicker/src/main/res/values/strings.xml
  38. 21 0
      build.gradle
  39. 0 0
      gradle.properties
  40. BIN
      gradle/wrapper/gradle-wrapper.jar
  41. 5 0
      gradle/wrapper/gradle-wrapper.properties
  42. 8 0
      local.properties
  43. 1 0
      settings.gradle

+ 2 - 0
Demo/.gitignore

@@ -0,0 +1,2 @@
+build
+*.iml

+ 20 - 0
Demo/build.gradle

@@ -0,0 +1,20 @@
+apply plugin: 'com.android.application'
+android {
+    compileSdkVersion 28
+    defaultConfig {
+        applicationId "com.aigestudio.wheelpicker.demo"
+        minSdkVersion 14
+        targetSdkVersion 28
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+dependencies {
+    implementation project(':WheelPicker')
+}

+ 17 - 0
Demo/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in J:\SDK\Android\Win/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 17 - 0
Demo/src/main/AndroidManifest.xml

@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.aigestudio.wheelpicker.demo">
+
+    <application
+        android:icon="@mipmap/ic_launcher"
+        android:label="WheelPickerDemo"
+        android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">
+        <activity
+            android:name=".PreviewActivity"
+            android:screenOrientation="portrait">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>

BIN
Demo/src/main/assets/yyg.ttf


+ 75 - 0
Demo/src/main/java/com/aigestudio/wheelpicker/demo/PreviewActivity.java

@@ -0,0 +1,75 @@
+package com.aigestudio.wheelpicker.demo;
+
+import android.app.Activity;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+
+import com.aigestudio.wheelpicker.WheelPicker;
+
+/**
+ * @author AigeStudio 2015-12-06
+ * @author AigeStudio 2016-07-08
+ */
+public class PreviewActivity extends Activity implements WheelPicker.OnItemSelectedListener, View.OnClickListener {
+
+    private WheelPicker wheelLeft;
+    private WheelPicker wheelCenter;
+    private WheelPicker wheelRight;
+
+    private Button gotoBtn;
+    private Integer gotoBtnItemIndex;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.ac_preview);
+
+        wheelLeft = (WheelPicker) findViewById(R.id.main_wheel_left);
+        wheelLeft.setOnItemSelectedListener(this);
+        wheelLeft.setSelectedItemTypeface(Typeface.DEFAULT_BOLD);
+
+        wheelCenter = (WheelPicker) findViewById(R.id.main_wheel_center);
+        wheelCenter.setOnItemSelectedListener(this);
+        wheelCenter.setSelectedItemTypeface(Typeface.DEFAULT_BOLD);
+
+        wheelRight = (WheelPicker) findViewById(R.id.main_wheel_right);
+        wheelRight.setOnItemSelectedListener(this);
+        wheelRight.setSelectedItemTypeface(Typeface.DEFAULT_BOLD);
+
+        gotoBtn = (Button) findViewById(R.id.goto_btn);
+        randomlySetGotoBtnIndex();
+        gotoBtn.setOnClickListener(this);
+    }
+
+    private void randomlySetGotoBtnIndex() {
+        gotoBtnItemIndex = (int) (Math.random() * wheelCenter.getData().size());
+        gotoBtn.setText("Goto '" + wheelCenter.getData().get(gotoBtnItemIndex) + "'");
+    }
+
+    @Override
+    public void onItemSelected(WheelPicker picker, Object data, int position) {
+        String text = "";
+        switch (picker.getId()) {
+            case R.id.main_wheel_left:
+                text = "Left:";
+                break;
+            case R.id.main_wheel_center:
+                text = "Center:";
+                break;
+            case R.id.main_wheel_right:
+                text = "Right:";
+                break;
+        }
+        Toast.makeText(this, text + String.valueOf(data), Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    public void onClick(View v) {
+        wheelCenter.setSelectedItemPosition(gotoBtnItemIndex);
+        randomlySetGotoBtnIndex();
+    }
+
+}

+ 47 - 0
Demo/src/main/res/layout/ac_area_picker.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aigestudio="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#FFFFFF"
+    android:gravity="center"
+    android:orientation="horizontal">
+
+    <com.aigestudio.wheelpicker.WheelPicker
+        android:id="@+id/main_wheel_left"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#E5DEEB"
+        aigestudio:wheel_atmospheric="true"
+        aigestudio:wheel_curved="true"
+        aigestudio:wheel_cyclic="true"
+        aigestudio:wheel_item_align="right"
+        aigestudio:wheel_item_text_color="#A7A7DB"
+        aigestudio:wheel_item_text_size="24sp"
+        aigestudio:wheel_selected_item_text_color="#536D8A" />
+
+    <com.aigestudio.wheelpicker.WheelPicker
+        android:id="@+id/main_wheel_center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#E5DEEB"
+        aigestudio:wheel_atmospheric="true"
+        aigestudio:wheel_curved="true"
+        aigestudio:wheel_cyclic="true"
+        aigestudio:wheel_item_text_color="#A7A7DB"
+        aigestudio:wheel_item_text_size="24sp"
+        aigestudio:wheel_selected_item_text_color="#536D8A" />
+
+    <com.aigestudio.wheelpicker.WheelPicker
+        android:id="@+id/main_wheel_right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#E5DEEB"
+        aigestudio:wheel_atmospheric="true"
+        aigestudio:wheel_curved="true"
+        aigestudio:wheel_cyclic="true"
+        aigestudio:wheel_item_align="left"
+        aigestudio:wheel_item_text_color="#A7A7DB"
+        aigestudio:wheel_item_text_size="24sp"
+        aigestudio:wheel_selected_item_text_color="#536D8A" />
+</LinearLayout>

+ 68 - 0
Demo/src/main/res/layout/ac_preview.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aigestudio="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#FFFFFF"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <LinearLayout android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:orientation="horizontal"
+                  android:layout_marginTop="10dp">
+
+        <Button android:id="@+id/goto_btn"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Goto '?'" />
+
+    </LinearLayout>
+
+    <LinearLayout android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:orientation="horizontal">
+
+    <com.aigestudio.wheelpicker.WheelPicker
+        android:id="@+id/main_wheel_left"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#E5DEEB"
+        aigestudio:wheel_atmospheric="true"
+        aigestudio:wheel_curved="true"
+        aigestudio:wheel_cyclic="true"
+        aigestudio:wheel_item_align="right"
+        aigestudio:wheel_item_text_color="#A7A7DB"
+        aigestudio:wheel_item_text_size="24sp"
+        aigestudio:wheel_selected_item_text_color="#536D8A" />
+
+    <com.aigestudio.wheelpicker.WheelPicker
+        android:id="@+id/main_wheel_center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#E5DEEB"
+        aigestudio:wheel_atmospheric="true"
+        aigestudio:wheel_curved="true"
+        aigestudio:wheel_cyclic="true"
+        aigestudio:wheel_item_text_color="#A7A7DB"
+        aigestudio:wheel_item_text_size="24sp"
+        aigestudio:wheel_selected_item_text_color="#536D8A" />
+
+    <com.aigestudio.wheelpicker.WheelPicker
+        android:id="@+id/main_wheel_right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#E5DEEB"
+        aigestudio:wheel_atmospheric="true"
+        aigestudio:wheel_curved="true"
+        aigestudio:wheel_cyclic="true"
+        aigestudio:wheel_item_align="left"
+        aigestudio:wheel_item_text_color="#A7A7DB"
+        aigestudio:wheel_item_text_size="24sp"
+        aigestudio:wheel_selected_item_text_color="#536D8A" />
+
+    </LinearLayout>
+
+</LinearLayout>

BIN
Demo/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
Demo/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
Demo/src/main/res/mipmap-xxhdpi/ic_launcher.png


+ 2 - 0
WheelPicker/.gitignore

@@ -0,0 +1,2 @@
+build
+*.iml

+ 47 - 0
WheelPicker/build.gradle

@@ -0,0 +1,47 @@
+apply plugin: 'com.android.library'
+//apply plugin: 'com.novoda.bintray-release'
+apply plugin: 'maven'
+def version = '1.1.0'
+android {
+    compileSdkVersion 27
+    defaultConfig {
+        minSdkVersion 14
+        targetSdkVersion 27
+        versionCode 8
+        versionName version
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+    //sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } }
+}
+
+uploadArchives {
+    repositories{
+        mavenDeployer {
+            //url 'https://repo.rdc.aliyun.com/repository/84103-release-wrxD8V/'
+            repository(url:"https://repo.rdc.aliyun.com/repository/84521-release-D7jNC2/") {
+                authentication(userName:"icYZUR", password:"Xgk5Pc7PcV")
+            }
+            // 以com.android.support:appcompat-v7:25.1.0为对比
+            pom.version="1.0.0" // 对应版本号 25.1.0
+            pom.artifactId="wheelpicker" // 对应 appcompat-v7
+            pom.groupId="com.airsmart.lib" // com.android.support
+        }
+    }
+}
+
+/*publish {
+    userOrg = 'aigestudio'
+    groupId = 'cn.aigestudio.wheelpicker'
+    artifactId = "WheelPicker"
+    publishVersion = "${version}"
+    desc = 'Simple and fantastic wheel view in realistic effect for android.'
+    website = 'https://github.com/AigeStudio/WheelPicker'
+}*/
+dependencies {
+    //implementation 'com.google.code.gson:gson:2.8.2'
+}

+ 17 - 0
WheelPicker/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in J:\SDK\Android\Win/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 1 - 0
WheelPicker/src/main/AndroidManifest.xml

@@ -0,0 +1 @@
+<manifest package="com.aigestudio.wheelpicker" />

+ 17 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/IDebug.java

@@ -0,0 +1,17 @@
+package com.aigestudio.wheelpicker;
+
+/**
+ * 调试模式方法接口
+ *
+ * @author AigeStudio
+ * @since 2011-04-11
+ */
+public interface IDebug {
+    /**
+     * 设置调试模式
+     * 开启调试模式有可能在一定程度上降低代码执行效率,请务必在正式发布时关闭调试模式
+     *
+     * @param isDebug 是否为调试模式
+     */
+    void setDebug(boolean isDebug);
+}

+ 527 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/IWheelPicker.java

@@ -0,0 +1,527 @@
+package com.aigestudio.wheelpicker;
+
+import android.graphics.Typeface;
+
+import java.util.List;
+
+/**
+ * 滚轮选择器方法接口
+ * <p>
+ * Interface of WheelPicker
+ *
+ * @author AigeStudio 2015-12-03
+ * @author AigeStudio 2015-12-08
+ * @author AigeStudio 2015-12-12
+ * @author AigeStudio 2016-06-17
+ *         更新项目结构
+ *         <p>
+ *         New project structure
+ * @version 1.1.0
+ */
+public interface IWheelPicker {
+
+    /**
+     * 获取滚轮选择器可见数据项的数量
+     * <p>
+     * Get the count of current visible items in WheelPicker
+     *
+     * @return 滚轮选择器可见数据项的数量
+     */
+    int getVisibleItemCount();
+
+    /**
+     * 设置滚轮选择器可见数据项数量
+     * 滚轮选择器的可见数据项数量必须为大于1的整数
+     * 这里需要注意的是,滚轮选择器会始终显示奇数个数据项,即便你为其设置偶数个数据项,最终也会被转换为奇数
+     * 默认情况下滚轮选择器可见数据项数量为7
+     * <p>
+     * Set the count of current visible items in WheelPicker
+     * The count of current visible items in WheelPicker must greater than 1
+     * Notice:count of current visible items in WheelPicker will always is an odd number, even you
+     * can set an even number for it, it will be change to an odd number eventually
+     * By default, the count of current visible items in WheelPicker is 7
+     *
+     * @param count 滚轮选择器可见数据项数量
+     */
+    void setVisibleItemCount(int count);
+
+    /**
+     * 滚轮选择器数据项是否为循环状态
+     * <p>
+     * Whether WheelPicker is cyclic or not
+     *
+     * @return 是否为循环状态
+     */
+    boolean isCyclic();
+
+    /**
+     * 设置滚轮选择器数据项是否为循环状态
+     * 开启数据循环会使滚轮选择器上下滚动不再有边界,会呈现数据首尾相接无限循环的效果
+     * <p>
+     * Set whether WheelPicker is cyclic or not
+     * WheelPicker's items will be end to end and in an infinite loop if setCyclic true, and there
+     * is no border whit scroll when WheelPicker in cyclic state
+     *
+     * @param isCyclic 是否为循环状态
+     */
+    void setCyclic(boolean isCyclic);
+
+    /**
+     * 设置滚轮Item选中监听器
+     *
+     * @param listener 滚轮Item选中监听器{@link WheelPicker.OnItemSelectedListener}
+     */
+    void setOnItemSelectedListener(WheelPicker.OnItemSelectedListener listener);
+
+    /**
+     * 获取当前被选中的数据项所显示的数据在数据源中的位置
+     * 需要注意的是,当滚轮选择器滚动时并不会改变该方法的返回值,该方法会始终返回
+     * {@link #setSelectedItemPosition(int)}所设置的值,当且仅当调用
+     * {@link #setSelectedItemPosition(int)}设置新值后,该方法所返回的值才会改变
+     * 如果你只是想获取滚轮静止时当前被选中的数据项所显示的数据在数据源中的位置,你可以通过
+     * {@link com.aigestudio.wheelpicker.WheelPicker.OnItemSelectedListener}回调监听或调用
+     * {@link #getCurrentItemPosition()}
+     * <p>
+     * Get the position of current selected item in data source
+     * Notice:The value by return will not change when WheelPicker scroll, this method will always
+     * return the value which {@link #setSelectedItemPosition(int)} set, the value this method
+     * return will be changed if and only if call the
+     * {@link #setSelectedItemPosition(int)}
+     * set a new value
+     * If you only want to get the position of current selected item in data source, you can get it
+     * through {@link com.aigestudio.wheelpicker.WheelPicker.OnItemSelectedListener} or call
+     * {@link #getCurrentItemPosition()} directly
+     *
+     * @return 当前被选中的数据项所显示的数据在数据源中的位置
+     */
+    int getSelectedItemPosition();
+
+    /**
+     * 设置当前被选中的数据项所显示的数据在数据源中的位置
+     * 调用该方法会导致滚动选择器的位置被重新初始化,什么意思呢?假如你滑动选择到第五个数据项的时候调用该方
+     * 法重新将当前被选中的数据项所显示的数据在数据源中的位置设置为第三个,那么滚轮选择器会清除掉上一次滚动
+     * 的相关数据参数,并将重置一系列的数据,重新将第三个数据作为滚轮选择器的起点,这个行为很可能会影响你之
+     * 前所根据这些参数改变的一些属性,比如
+     * {@link com.aigestudio.wheelpicker.WheelPicker.OnWheelChangeListener}和
+     * {@link com.aigestudio.wheelpicker.WheelPicker.OnItemSelectedListener}监听器中方法参数的值,因
+     * 此你总该在调用该方法后考虑到相关影响
+     * 你总该为该方法传入一个大于等于0小于数据源{@link #getData()}长度
+     * 的值,否则会抛出异常
+     * 默认情况下,当前被选中的数据项所显示的数据在数据源中的位置为0
+     * <p>
+     * Set the position of current selected item in data source
+     * Call this method and set a new value may be reinitialize the location of WheelPicker. For
+     * example, you call this method after scroll the WheelPicker and set selected item position
+     * with a new value, WheelPicker will clear the related parameters last scroll set and reset
+     * series of data, and make the position 3 as a new starting point of WheelPicker, this behavior
+     * maybe influenced some attribute you set last time, such as parameters of method in
+     * {@link com.aigestudio.wheelpicker.WheelPicker.OnWheelChangeListener} and
+     * {@link com.aigestudio.wheelpicker.WheelPicker.OnItemSelectedListener}, so you must always
+     * consider the influence when you call this method set a new value
+     * You should always set a value which greater than or equal to 0 and less than data source's
+     * length
+     * By default, position of current selected item in data source is 0
+     *
+     * @param position 当前被选中的数据项所显示的数据在数据源中的位置
+     */
+    void setSelectedItemPosition(int position);
+
+    /**
+     * 获取当前被选中的数据项所显示的数据在数据源中的位置
+     * 与{@link #getSelectedItemPosition()}不同的是,该方法所返回的结果会因为滚轮选择器的改变而改变
+     * <p>
+     * Get the position of current selected item in data source
+     * The difference between {@link #getSelectedItemPosition()}, the value this method return will
+     * change by WheelPicker scrolled
+     *
+     * @return 当前被选中的数据项所显示的数据在数据源中的位置
+     */
+    int getCurrentItemPosition();
+
+    /**
+     * 获取数据列表
+     * <p>
+     * Get data source of WheelPicker
+     *
+     * @return 数据列表
+     */
+    List getData();
+
+    /**
+     * 设置数据列表
+     * 数据源可以是任意类型,但是需要注意的是WheelPicker在绘制数据的时候会将数据转换成String类型
+     * 在没有设置数据源的情况下滚轮选择器会设置一个默认的数据源作为展示
+     * 为滚轮选择器设置数据源会重置滚轮选择器的各项状态,具体行为参考
+     * {@link #setSelectedItemPosition(int)}
+     * <p>
+     * Set data source of WheelPicker
+     * The data source can be any type, WheelPicker will change the data to string when it draw the
+     * item.
+     * There is a default data source when you not set the data source for WheelPicker.
+     * Set data source for WheelPicker will reset state of it, you can refer to
+     * {@link #setSelectedItemPosition(int)} for more details.
+     *
+     * @param data 数据列表
+     */
+    void setData(List data);
+
+    /**
+     * 设置数据项是否有相同的宽度
+     * 滚轮选择器在确定尺寸大小时会通过遍历数据源来计算每一条数据文本的宽度以找到最宽的文本作为滚轮选择器的
+     * 最终宽度,当数据源的数据非常多时,这个过程可能会消耗大量的时间导致效率降低,而且在大部分数据量多情况
+     * 下,数据文本大都有相同的宽度,这种情况下调用该方法告诉滚轮选择器数据宽度相同则可以免去上述计算时间,
+     * 提升效率
+     * 有些时候,你所加载的数据源确实是每条数据文本的宽度都不同,但是你知道最宽的数据文本在数据源中的位置,
+     * 这时你可以调用{@link #setMaximumWidthTextPosition(int)}方法告诉滚轮选择器最宽的这条数据文本在数据
+     * 源的什么位置,滚轮选择器则会根据该位置找到该条数据文本并将其宽度作为滚轮选择器的宽度。如果你不知道位
+     * 置,但是知道最宽的数据文本,那么你也可以直接通过调用{@link #setMaximumWidthText(String)}告诉滚轮选
+     * 择器最宽的文本是什么,滚轮选择器会根据这条文本计算宽度并将其作为滚轮选择器的宽度
+     * <p>
+     * Set items of WheelPicker if has same width
+     * WheelPicker will traverse the data source to calculate each data text width to find out the
+     * maximum text width for the final view width, this process maybe spends a lot of time and
+     * reduce efficiency when data source has large amount data, in most large amount data case,
+     * data text always has same width, you can call this method tell to WheelPicker your data
+     * source has same width to save time and improve efficiency.
+     * Sometimes the data source you set is positively has different text width, but maybe you know
+     * the maximum width text's position in data source, then you can call
+     * {@link #setMaximumWidthTextPosition(int)} tell to WheelPicker where is the maximum width text
+     * in data source, WheelPicker will calculate its width base on this text which found by
+     * position. If you don't know the position of maximum width text in data source, but you have
+     * maximum width text, you can call {@link #setMaximumWidthText(String)} tell to WheelPicker
+     * what maximum width text is directly, WheelPicker will calculate its width base on this text.
+     *
+     * @param hasSameSize 是否有相同的宽度
+     */
+    void setSameWidth(boolean hasSameSize);
+
+    /**
+     * 数据项是否有相同宽度
+     * <p>
+     * Whether items has same width or not
+     *
+     * @return 是否有相同宽度
+     */
+    boolean hasSameWidth();
+
+    /**
+     * 设置滚轮滚动状态改变监听器
+     *
+     * @param listener 滚轮滚动状态改变监听器
+     * @see com.aigestudio.wheelpicker.WheelPicker.OnWheelChangeListener
+     */
+    void setOnWheelChangeListener(WheelPicker.OnWheelChangeListener listener);
+
+    /**
+     * 获取最宽的文本
+     * <p>
+     * Get maximum width text
+     *
+     * @return 最宽的文本
+     */
+    String getMaximumWidthText();
+
+    /**
+     * 设置最宽的文本
+     * <p>
+     * Set maximum width text
+     *
+     * @param text 最宽的文本
+     * @see #setSameWidth(boolean)
+     */
+    void setMaximumWidthText(String text);
+
+    /**
+     * 获取最宽的文本在数据源中的位置
+     * <p>
+     * Get the position of maximum width text in data source
+     *
+     * @return 最宽的文本在数据源中的位置
+     */
+    int getMaximumWidthTextPosition();
+
+    /**
+     * 设置最宽的文本在数据源中的位置
+     * <p>
+     * Set the position of maximum width text in data source
+     *
+     * @param position 最宽的文本在数据源中的位置
+     * @see #setSameWidth(boolean)
+     */
+    void setMaximumWidthTextPosition(int position);
+
+    /**
+     * 获取当前选中的数据项文本颜色
+     * <p>
+     * Get text color of current selected item
+     * For example 0xFF123456
+     *
+     * @return 当前选中的数据项文本颜色
+     */
+    int getSelectedItemTextColor();
+
+    /**
+     * 设置当前选中的数据项文本颜色
+     * <p>
+     * Set text color of current selected item
+     * For example 0xFF123456
+     *
+     * @param color 当前选中的数据项文本颜色,16位颜色值
+     */
+    void setSelectedItemTextColor(int color);
+
+    /**
+     * 获取数据项文本颜色
+     * <p>
+     * Get text color of items
+     * For example 0xFF123456
+     *
+     * @return 数据项文本颜色
+     */
+    int getItemTextColor();
+
+    /**
+     * 设置数据项文本颜色
+     * <p>
+     * Set text color of items
+     * For example 0xFF123456
+     *
+     * @param color 数据项文本颜色,16位颜色值
+     */
+    void setItemTextColor(int color);
+
+    /**
+     * 获取数据项文本尺寸大小
+     * <p>
+     * Get text size of items
+     * Unit in px
+     *
+     * @return 数据项文本尺寸大小
+     */
+    int getItemTextSize();
+
+    /**
+     * 设置数据项文本尺寸大小
+     * <p>
+     * Set text size of items
+     * Unit in px
+     *
+     * @param size 设置数据项文本尺寸大小,单位:px
+     */
+    void setItemTextSize(int size);
+
+    /**
+     * 获取滚轮选择器数据项之间间距
+     * <p>
+     * Get space between items
+     * Unit in px
+     *
+     * @return 滚轮选择器数据项之间间距
+     */
+    int getItemSpace();
+
+    /**
+     * 设置滚轮选择器数据项之间间距
+     * <p>
+     * Set space between items
+     * Unit in px
+     *
+     * @param space 滚轮选择器数据项之间间距,单位:px
+     */
+    void setItemSpace(int space);
+
+    /**
+     * 设置滚轮选择器是否显示指示器
+     * 如果设置滚轮选择器显示指示器,那么将会在滚轮选择器的当前选中数据项上下显示两根分割线
+     * 需要注意的是指示器的尺寸并不参与滚轮选择器的尺寸计算,其会绘制在滚轮选择器的上方
+     * <p>
+     * Set whether WheelPicker display indicator or not
+     * WheelPicker will draw two lines above an below current selected item if display indicator
+     * Notice:Indicator's size will not participate in WheelPicker's size calculation, it will drawn
+     * above the content
+     *
+     * @param hasIndicator 是否有指示器
+     */
+    void setIndicator(boolean hasIndicator);
+
+    /**
+     * 滚轮选择器是否有指示器
+     * <p>
+     * Whether WheelPicker display indicator or not
+     *
+     * @return 滚轮选择器是否有指示器
+     */
+    boolean hasIndicator();
+
+    /**
+     * 获取滚轮选择器指示器尺寸
+     * <p>
+     * Get size of indicator
+     * Unit in px
+     *
+     * @return 滚轮选择器指示器尺寸
+     */
+    int getIndicatorSize();
+
+    /**
+     * 设置滚轮选择器指示器尺寸
+     * <p>
+     * Set size of indicator
+     * Unit in px
+     *
+     * @param size 滚轮选择器指示器尺寸,单位:px
+     */
+    void setIndicatorSize(int size);
+
+    /**
+     * 获取滚轮选择器指示器颜色
+     * <p>
+     * Get color of indicator
+     * For example 0xFF123456
+     *
+     * @return 滚轮选择器指示器颜色,16位颜色值
+     */
+    int getIndicatorColor();
+
+    /**
+     * 设置滚轮选择器指示器颜色
+     * <p>
+     * Set color of indicator
+     * For example 0xFF123456
+     *
+     * @param color 滚轮选择器指示器颜色,16位颜色值
+     */
+    void setIndicatorColor(int color);
+
+    /**
+     * 设置滚轮选择器是否显示幕布
+     * 设置滚轮选择器显示幕布的话将会在当前选中的项上方绘制一个与当前数据项大小一致的矩形区域并填充指定颜色
+     * <p>
+     * Set whether WheelPicker display curtain or not
+     * WheelPicker will draw a rectangle as big as current selected item and fill specify color
+     * above content if curtain display
+     *
+     * @param hasCurtain 滚轮选择器是否显示幕布
+     */
+    void setCurtain(boolean hasCurtain);
+
+    /**
+     * 滚轮选择器是否显示幕布
+     * <p>
+     * Whether WheelPicker display curtain or not
+     *
+     * @return 滚轮选择器是否显示幕布
+     */
+    boolean hasCurtain();
+
+    /**
+     * 获取滚轮选择器幕布颜色
+     * <p>
+     * Get color of curtain
+     * For example 0xFF123456
+     *
+     * @return 滚轮选择器幕布颜色,16位颜色值
+     */
+    int getCurtainColor();
+
+    /**
+     * 设置滚轮选择器幕布颜色
+     * <p>
+     * Set color of curtain
+     * For example 0xFF123456
+     *
+     * @param color 滚轮选择器幕布颜色,16位颜色值
+     */
+    void setCurtainColor(int color);
+
+    /**
+     * 设置滚轮选择器是否有空气感
+     * 开启空气感的滚轮选择器将呈现中间不透明逐渐向两端透明过度的渐变效果
+     * <p>
+     * Set whether WheelPicker has atmospheric or not
+     * WheelPicker's items will be transparent from center to ends if atmospheric display
+     *
+     * @param hasAtmospheric 滚轮选择器是否有空气感
+     */
+    void setAtmospheric(boolean hasAtmospheric);
+
+    /**
+     * 滚轮选择器是否有空气感
+     * <p>
+     * Whether WheelPicker has atmospheric or not
+     *
+     * @return 滚轮选择器是否有空气感
+     */
+    boolean hasAtmospheric();
+
+    /**
+     * 滚轮选择器是否开启卷曲效果
+     * <p>
+     * Whether WheelPicker enable curved effect or not
+     *
+     * @return 滚轮选择器是否开启卷曲效果
+     */
+    boolean isCurved();
+
+    /**
+     * 设置滚轮选择器是否开启卷曲效果
+     * 开启滚轮选择器的滚轮效果会呈现一种滚轮两端向屏幕内弯曲的效果
+     * 滚轮选择器的卷曲效果依赖于严格的几何模型,一些与尺寸相关的设置在该效果下可能会变得不再有效,例如在卷
+     * 曲效果下每一条数据项的尺寸大小因为透视关系看起来都不再一样,数据项之间的间隔也会因为卷曲的关系有微妙
+     * 的视觉差距
+     * <p>
+     * Set whether WheelPicker enable curved effect or not
+     * If setCurved true, WheelPicker will display with curved effect looks like ends bend into
+     * screen with perspective.
+     * WheelPicker's curved effect base on strict geometric model, some parameters relate with size
+     * maybe invalidated, for example each item size looks like different because of perspective in
+     * curved, the space between items looks like have a little difference
+     *
+     * @param isCurved 滚轮选择器是否开启卷曲效果
+     */
+    void setCurved(boolean isCurved);
+
+    /**
+     * 获取滚轮选择器数据项的对齐方式
+     * <p>
+     * Get alignment of WheelPicker
+     *
+     * @return 滚轮选择器数据项的对齐方式
+     */
+    int getItemAlign();
+
+    /**
+     * 设置滚轮选择器数据项的对齐方式
+     * 默认对齐方式为居中对齐{@link WheelPicker#ALIGN_CENTER}
+     * <p>
+     * Set alignment of WheelPicker
+     * The default alignment of WheelPicker is {@link WheelPicker#ALIGN_CENTER}
+     *
+     * @param align 对齐方式标识值
+     *              该值仅能是下列值之一:
+     *              {@link WheelPicker#ALIGN_CENTER}
+     *              {@link WheelPicker#ALIGN_LEFT}
+     *              {@link WheelPicker#ALIGN_RIGHT}
+     */
+    void setItemAlign(int align);
+
+    /**
+     * 获取数据项文本字体对象
+     * <p>
+     * Get typeface of item text
+     *
+     * @return 文本字体对象
+     */
+    Typeface getTypeface();
+
+    /**
+     * 设置数据项文本字体对象
+     * 数据项文本字体的设置可能会导致滚轮大小的改变
+     * <p>
+     * Set typeface of item text
+     * Set typeface of item text maybe cause WheelPicker size change
+     *
+     * @param tf 字体对象
+     */
+    void setTypeface(Typeface tf);
+}

File diff suppressed because it is too large
+ 1225 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/WheelPicker.java


+ 28 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/model/City.java

@@ -0,0 +1,28 @@
+package com.aigestudio.wheelpicker.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by Administrator on 2016/9/14 0014.
+ */
+public class City implements Serializable {
+    public String name;
+    public List<String> area;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<String> getArea() {
+        return area;
+    }
+
+    public void setArea(List<String> area) {
+        this.area = area;
+    }
+}

+ 29 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/model/Province.java

@@ -0,0 +1,29 @@
+package com.aigestudio.wheelpicker.model;
+
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by Administrator on 2016/9/14 0014.
+ */
+public class Province implements Serializable {
+    public String name;
+    public List<City> city;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<City> getCity() {
+        return city;
+    }
+
+    public void setCity(List<City> city) {
+        this.city = city;
+    }
+}

+ 15 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelAreaPicker.java

@@ -0,0 +1,15 @@
+package com.aigestudio.wheelpicker.widgets;
+
+/**
+ * Created by Administrator on 2016/9/27 0027.
+ */
+
+public interface IWheelAreaPicker {
+    String getProvince();
+
+    String getCity();
+
+    String getArea();
+
+    void hideArea();
+}

+ 35 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelDatePicker.java

@@ -0,0 +1,35 @@
+package com.aigestudio.wheelpicker.widgets;
+
+import android.widget.TextView;
+
+import java.util.Date;
+
+public interface IWheelDatePicker {
+    void setOnDateSelectedListener(WheelDatePicker.OnDateSelectedListener listener);
+
+    Date getCurrentDate();
+
+    int getItemAlignYear();
+
+    void setItemAlignYear(int align);
+
+    int getItemAlignMonth();
+
+    void setItemAlignMonth(int align);
+
+    int getItemAlignDay();
+
+    void setItemAlignDay(int align);
+
+    WheelYearPicker getWheelYearPicker();
+
+    WheelMonthPicker getWheelMonthPicker();
+
+    WheelDayPicker getWheelDayPicker();
+
+    TextView getTextViewYear();
+
+    TextView getTextViewMonth();
+
+    TextView getTextViewDay();
+}

+ 68 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelDayPicker.java

@@ -0,0 +1,68 @@
+package com.aigestudio.wheelpicker.widgets;
+
+/**
+ * 选择器方法接口
+ * <p>
+ * Interface of WheelMonthPicker
+ *
+ * @author AigeStudio 2016-07-12
+ * @version 1
+ */
+public interface IWheelDayPicker {
+    /**
+     * 获取日期选择器初始化时选择的日期
+     *
+     * @return 选择的日期
+     */
+    int getSelectedDay();
+
+    /**
+     * 设置日期选择器初始化时选择的日期
+     *
+     * @param day 选择的日期
+     */
+    void setSelectedDay(int day);
+
+    /**
+     * 获取当前选择的日期
+     *
+     * @return 选择的日期
+     */
+    int getCurrentDay();
+
+    /**
+     * 设置年份和月份
+     *
+     * @param year  年份
+     * @param month 月份
+     */
+    void setYearAndMonth(int year, int month);
+
+    /**
+     * 获取年份
+     *
+     * @return 年份
+     */
+    int getYear();
+
+    /**
+     * 设置年份
+     *
+     * @param year ...
+     */
+    void setYear(int year);
+
+    /**
+     * 获取月份
+     *
+     * @return 月份
+     */
+    int getMonth();
+
+    /**
+     * 设置月份
+     *
+     * @param month 月份
+     */
+    void setMonth(int month);
+}

+ 32 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelMonthPicker.java

@@ -0,0 +1,32 @@
+package com.aigestudio.wheelpicker.widgets;
+
+/**
+ * 月份选择器方法接口
+ * <p>
+ * Interface of WheelMonthPicker
+ *
+ * @author AigeStudio 2016-07-12
+ * @version 1
+ */
+public interface IWheelMonthPicker {
+    /**
+     * 获取月份选择器初始化时选择的月份
+     *
+     * @return 选择的月份
+     */
+    int getSelectedMonth();
+
+    /**
+     * 设置月份选择器初始化时选择的月份
+     *
+     * @param month 选择的月份
+     */
+    void setSelectedMonth(int month);
+
+    /**
+     * 获取当前选择的月份
+     *
+     * @return 当前选择的月份
+     */
+    int getCurrentMonth();
+}

+ 68 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/IWheelYearPicker.java

@@ -0,0 +1,68 @@
+package com.aigestudio.wheelpicker.widgets;
+
+/**
+ * 年份选择器方法接口
+ * <p>
+ * Interface of WheelYearPicker
+ *
+ * @author AigeStudio 2016-07-12
+ * @version 1
+ */
+public interface IWheelYearPicker {
+    /**
+     * 设置年份范围
+     *
+     * @param start 开始的年份
+     * @param end   结束的年份
+     */
+    void setYearFrame(int start, int end);
+
+    /**
+     * 获取开始的年份
+     *
+     * @return 开始的年份
+     */
+    int getYearStart();
+
+    /**
+     * 设置开始的年份
+     *
+     * @param start 开始的年份
+     */
+    void setYearStart(int start);
+
+    /**
+     * 获取结束的年份
+     *
+     * @return 结束的年份
+     */
+    int getYearEnd();
+
+    /**
+     * 设置结束的年份
+     *
+     * @param end 结束的年份
+     */
+    void setYearEnd(int end);
+
+    /**
+     * 获取年份选择器初始化时选中的年份
+     *
+     * @return 年份选择器初始化时选中的年份
+     */
+    int getSelectedYear();
+
+    /**
+     * 设置年份选择器初始化时选中的年份
+     *
+     * @param year 年份选择器初始化时选中的年份
+     */
+    void setSelectedYear(int year);
+
+    /**
+     * 获取当前选中的年份
+     *
+     * @return 当前选中的年份
+     */
+    int getCurrentYear();
+}

+ 172 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelAreaPicker.java

@@ -0,0 +1,172 @@
+package com.aigestudio.wheelpicker.widgets;
+
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.graphics.Color;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.aigestudio.wheelpicker.WheelPicker;
+import com.aigestudio.wheelpicker.model.City;
+import com.aigestudio.wheelpicker.model.Province;
+
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * WheelAreaPicker
+ * Created by Administrator on 2016/9/14 0014.
+ */
+public class WheelAreaPicker extends LinearLayout implements IWheelAreaPicker {
+    private static final float ITEM_TEXT_SIZE = 18;
+    private static final String SELECTED_ITEM_COLOR = "#353535";
+    private static final int PROVINCE_INITIAL_INDEX = 0;
+
+    private Context mContext;
+
+    private List<Province> mProvinceList;
+    private List<City> mCityList;
+    private List<String> mProvinceName, mCityName;
+
+    private AssetManager mAssetManager;
+
+    private LayoutParams mLayoutParams;
+
+    private WheelPicker mWPProvince, mWPCity, mWPArea;
+
+    public WheelAreaPicker(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        initLayoutParams();
+
+        initView(context);
+
+        mProvinceList = getJsonDataFromAssets(mAssetManager);
+
+        obtainProvinceData();
+
+        addListenerToWheelPicker();
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<Province> getJsonDataFromAssets(AssetManager assetManager) {
+        List<Province> provinceList = new ArrayList<>();
+        try {
+            InputStream inputStream = assetManager.open("RegionJsonData.dat");
+            ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
+            provinceList = (List<Province>) objectInputStream.readObject();
+            objectInputStream.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return provinceList;
+    }
+
+    private void initLayoutParams() {
+        mLayoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        mLayoutParams.setMargins(5, 5, 5, 5);
+        mLayoutParams.width = 0;
+    }
+
+    private void initView(Context context) {
+        setOrientation(HORIZONTAL);
+
+        mContext = context;
+
+        mAssetManager = mContext.getAssets();
+
+        mProvinceName = new ArrayList<>();
+        mCityName = new ArrayList<>();
+
+        mWPProvince = new WheelPicker(context);
+        mWPCity = new WheelPicker(context);
+        mWPArea = new WheelPicker(context);
+
+        initWheelPicker(mWPProvince, 1);
+        initWheelPicker(mWPCity, 1.5f);
+        initWheelPicker(mWPArea, 1.5f);
+    }
+
+    private void initWheelPicker(WheelPicker wheelPicker, float weight) {
+        mLayoutParams.weight = weight;
+        wheelPicker.setItemTextSize(dip2px(mContext, ITEM_TEXT_SIZE));
+        wheelPicker.setSelectedItemTextColor(Color.parseColor(SELECTED_ITEM_COLOR));
+        wheelPicker.setCurved(true);
+        wheelPicker.setLayoutParams(mLayoutParams);
+        addView(wheelPicker);
+    }
+
+    private void obtainProvinceData() {
+        for (Province province : mProvinceList) {
+            mProvinceName.add(province.getName());
+        }
+        mWPProvince.setData(mProvinceName);
+        setCityAndAreaData(PROVINCE_INITIAL_INDEX);
+    }
+
+    private void addListenerToWheelPicker() {
+        //监听省份的滑轮,根据省份的滑轮滑动的数据来设置市跟地区的滑轮数据
+        mWPProvince.setOnItemSelectedListener(new WheelPicker.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(WheelPicker picker, Object data, int position) {
+                //获得该省所有城市的集合
+                mCityList = mProvinceList.get(position).getCity();
+                setCityAndAreaData(position);
+            }
+        });
+
+        mWPCity.setOnItemSelectedListener(new WheelPicker.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(WheelPicker picker, Object data, int position) {
+                //获取城市对应的城区的名字
+                mWPArea.setData(mCityList.get(position).getArea());
+            }
+        });
+    }
+
+    private void setCityAndAreaData(int position) {
+        //获得该省所有城市的集合
+        mCityList = mProvinceList.get(position).getCity();
+        //获取所有city的名字
+        //重置先前的城市集合数据
+        mCityName.clear();
+        for (City city : mCityList)
+            mCityName.add(city.getName());
+        mWPCity.setData(mCityName);
+        mWPCity.setSelectedItemPosition(0);
+        //获取第一个城市对应的城区的名字
+        //重置先前的城区集合的数据
+        mWPArea.setData(mCityList.get(0).getArea());
+        mWPArea.setSelectedItemPosition(0);
+    }
+
+    @Override
+    public String getProvince() {
+        return mProvinceList.get(mWPProvince.getCurrentItemPosition()).getName();
+    }
+
+    @Override
+    public String getCity() {
+        return mCityList.get(mWPCity.getCurrentItemPosition()).getName();
+    }
+
+    @Override
+    public String getArea() {
+        return mCityList.get(mWPCity.getCurrentItemPosition()).getArea().get(mWPArea.getCurrentItemPosition());
+    }
+
+    @Override
+    public void hideArea() {
+        this.removeViewAt(2);
+    }
+
+    private int dip2px(Context context, float dpValue) {
+        final float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+}

+ 592 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelDatePicker.java

@@ -0,0 +1,592 @@
+package com.aigestudio.wheelpicker.widgets;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.aigestudio.wheelpicker.IDebug;
+import com.aigestudio.wheelpicker.IWheelPicker;
+import com.aigestudio.wheelpicker.R;
+import com.aigestudio.wheelpicker.WheelPicker;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+public class WheelDatePicker extends LinearLayout implements WheelPicker.OnItemSelectedListener,
+        IDebug, IWheelPicker, IWheelDatePicker, IWheelYearPicker, IWheelMonthPicker,
+        IWheelDayPicker {
+    private static final SimpleDateFormat SDF =
+            new SimpleDateFormat("yyyy-M-d", Locale.getDefault());
+
+    private WheelYearPicker mPickerYear;
+    private WheelMonthPicker mPickerMonth;
+    private WheelDayPicker mPickerDay;
+
+    private OnDateSelectedListener mListener;
+
+    private TextView mTVYear, mTVMonth, mTVDay;
+
+    private int mYear, mMonth, mDay;
+
+    public WheelDatePicker(Context context) {
+        this(context, null);
+    }
+
+    public WheelDatePicker(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        LayoutInflater.from(context).inflate(R.layout.view_wheel_date_picker, this);
+
+        mPickerYear = (WheelYearPicker) findViewById(R.id.wheel_date_picker_year);
+        mPickerMonth = (WheelMonthPicker) findViewById(R.id.wheel_date_picker_month);
+        mPickerDay = (WheelDayPicker) findViewById(R.id.wheel_date_picker_day);
+        mPickerYear.setOnItemSelectedListener(this);
+        mPickerMonth.setOnItemSelectedListener(this);
+        mPickerDay.setOnItemSelectedListener(this);
+
+        setMaximumWidthTextYear();
+        mPickerMonth.setMaximumWidthText("00");
+        mPickerDay.setMaximumWidthText("00");
+
+        mTVYear = (TextView) findViewById(R.id.wheel_date_picker_year_tv);
+        mTVMonth = (TextView) findViewById(R.id.wheel_date_picker_month_tv);
+        mTVDay = (TextView) findViewById(R.id.wheel_date_picker_day_tv);
+
+        mYear = mPickerYear.getCurrentYear();
+        mMonth = mPickerMonth.getCurrentMonth();
+        mDay = mPickerDay.getCurrentDay();
+    }
+
+    private void setMaximumWidthTextYear() {
+        List years = mPickerYear.getData();
+        String lastYear = String.valueOf(years.get(years.size() - 1));
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < lastYear.length(); i++)
+            sb.append("0");
+        mPickerYear.setMaximumWidthText(sb.toString());
+    }
+
+    @Override
+    public void onItemSelected(WheelPicker picker, Object data, int position) {
+        if (picker.getId() == R.id.wheel_date_picker_year) {
+            mYear = (int) data;
+            mPickerDay.setYear(mYear);
+        } else if (picker.getId() == R.id.wheel_date_picker_month) {
+            mMonth = (int) data;
+            mPickerDay.setMonth(mMonth);
+        }
+        mDay = mPickerDay.getCurrentDay();
+        String date = mYear + "-" + mMonth + "-" + mDay;
+        if (null != mListener) try {
+            mListener.onDateSelected(this, SDF.parse(date));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void setDebug(boolean isDebug) {
+        mPickerYear.setDebug(isDebug);
+        mPickerMonth.setDebug(isDebug);
+        mPickerDay.setDebug(isDebug);
+    }
+
+    @Override
+    public int getVisibleItemCount() {
+        if (mPickerYear.getVisibleItemCount() == mPickerMonth.getVisibleItemCount() &&
+                mPickerMonth.getVisibleItemCount() == mPickerDay.getVisibleItemCount())
+            return mPickerYear.getVisibleItemCount();
+        throw new ArithmeticException("Can not get visible item count correctly from" +
+                "WheelDatePicker!");
+    }
+
+    @Override
+    public void setVisibleItemCount(int count) {
+        mPickerYear.setVisibleItemCount(count);
+        mPickerMonth.setVisibleItemCount(count);
+        mPickerDay.setVisibleItemCount(count);
+    }
+
+    @Override
+    public boolean isCyclic() {
+        return mPickerYear.isCyclic() && mPickerMonth.isCyclic() && mPickerDay.isCyclic();
+    }
+
+    @Override
+    public void setCyclic(boolean isCyclic) {
+        mPickerYear.setCyclic(isCyclic);
+        mPickerMonth.setCyclic(isCyclic);
+        mPickerDay.setCyclic(isCyclic);
+    }
+
+    @Deprecated
+    @Override
+    public void setOnItemSelectedListener(WheelPicker.OnItemSelectedListener listener) {
+        throw new UnsupportedOperationException("You can not set OnItemSelectedListener for" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public int getSelectedItemPosition() {
+        throw new UnsupportedOperationException("You can not get position of selected item from" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setSelectedItemPosition(int position) {
+        throw new UnsupportedOperationException("You can not set position of selected item for" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public int getCurrentItemPosition() {
+        throw new UnsupportedOperationException("You can not get position of current item from" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public List getData() {
+        throw new UnsupportedOperationException("You can not get data source from WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setData(List data) {
+        throw new UnsupportedOperationException("You don't need to set data source for" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setSameWidth(boolean hasSameSize) {
+        throw new UnsupportedOperationException("You don't need to set same width for" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public boolean hasSameWidth() {
+        throw new UnsupportedOperationException("You don't need to set same width for" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setOnWheelChangeListener(WheelPicker.OnWheelChangeListener listener) {
+        throw new UnsupportedOperationException("WheelDatePicker unsupport set" +
+                "OnWheelChangeListener");
+    }
+
+    @Deprecated
+    @Override
+    public String getMaximumWidthText() {
+        throw new UnsupportedOperationException("You can not get maximum width text from" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setMaximumWidthText(String text) {
+        throw new UnsupportedOperationException("You don't need to set maximum width text for" +
+                "WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public int getMaximumWidthTextPosition() {
+        throw new UnsupportedOperationException("You can not get maximum width text position" +
+                "from WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setMaximumWidthTextPosition(int position) {
+        throw new UnsupportedOperationException("You don't need to set maximum width text" +
+                "position for WheelDatePicker");
+    }
+
+    @Override
+    public int getSelectedItemTextColor() {
+        if (mPickerYear.getSelectedItemTextColor() == mPickerMonth.getSelectedItemTextColor() &&
+                mPickerMonth.getSelectedItemTextColor() == mPickerDay.getSelectedItemTextColor())
+            return mPickerYear.getSelectedItemTextColor();
+        throw new RuntimeException("Can not get color of selected item text correctly from" +
+                "WheelDatePicker!");
+    }
+
+    @Override
+    public void setSelectedItemTextColor(int color) {
+        mPickerYear.setSelectedItemTextColor(color);
+        mPickerMonth.setSelectedItemTextColor(color);
+        mPickerDay.setSelectedItemTextColor(color);
+    }
+
+    @Override
+    public int getItemTextColor() {
+        if (mPickerYear.getItemTextColor() == mPickerMonth.getItemTextColor() &&
+                mPickerMonth.getItemTextColor() == mPickerDay.getItemTextColor())
+            return mPickerYear.getItemTextColor();
+        throw new RuntimeException("Can not get color of item text correctly from" +
+                "WheelDatePicker!");
+    }
+
+    @Override
+    public void setItemTextColor(int color) {
+        mPickerYear.setItemTextColor(color);
+        mPickerMonth.setItemTextColor(color);
+        mPickerDay.setItemTextColor(color);
+    }
+
+    @Override
+    public int getItemTextSize() {
+        if (mPickerYear.getItemTextSize() == mPickerMonth.getItemTextSize() &&
+                mPickerMonth.getItemTextSize() == mPickerDay.getItemTextSize())
+            return mPickerYear.getItemTextSize();
+        throw new RuntimeException("Can not get size of item text correctly from" +
+                "WheelDatePicker!");
+    }
+
+    @Override
+    public void setItemTextSize(int size) {
+        mPickerYear.setItemTextSize(size);
+        mPickerMonth.setItemTextSize(size);
+        mPickerDay.setItemTextSize(size);
+    }
+
+    @Override
+    public int getItemSpace() {
+        if (mPickerYear.getItemSpace() == mPickerMonth.getItemSpace() &&
+                mPickerMonth.getItemSpace() == mPickerDay.getItemSpace())
+            return mPickerYear.getItemSpace();
+        throw new RuntimeException("Can not get item space correctly from WheelDatePicker!");
+    }
+
+    @Override
+    public void setItemSpace(int space) {
+        mPickerYear.setItemSpace(space);
+        mPickerMonth.setItemSpace(space);
+        mPickerDay.setItemSpace(space);
+    }
+
+    @Override
+    public void setIndicator(boolean hasIndicator) {
+        mPickerYear.setIndicator(hasIndicator);
+        mPickerMonth.setIndicator(hasIndicator);
+        mPickerDay.setIndicator(hasIndicator);
+    }
+
+    @Override
+    public boolean hasIndicator() {
+        return mPickerYear.hasIndicator() && mPickerMonth.hasIndicator() &&
+                mPickerDay.hasIndicator();
+    }
+
+    @Override
+    public int getIndicatorSize() {
+        if (mPickerYear.getIndicatorSize() == mPickerMonth.getIndicatorSize() &&
+                mPickerMonth.getIndicatorSize() == mPickerDay.getIndicatorSize())
+            return mPickerYear.getIndicatorSize();
+        throw new RuntimeException("Can not get indicator size correctly from WheelDatePicker!");
+    }
+
+    @Override
+    public void setIndicatorSize(int size) {
+        mPickerYear.setIndicatorSize(size);
+        mPickerMonth.setIndicatorSize(size);
+        mPickerDay.setIndicatorSize(size);
+    }
+
+    @Override
+    public int getIndicatorColor() {
+        if (mPickerYear.getCurtainColor() == mPickerMonth.getCurtainColor() &&
+                mPickerMonth.getCurtainColor() == mPickerDay.getCurtainColor())
+            return mPickerYear.getCurtainColor();
+        throw new RuntimeException("Can not get indicator color correctly from WheelDatePicker!");
+    }
+
+    @Override
+    public void setIndicatorColor(int color) {
+        mPickerYear.setIndicatorColor(color);
+        mPickerMonth.setIndicatorColor(color);
+        mPickerDay.setIndicatorColor(color);
+    }
+
+    @Override
+    public void setCurtain(boolean hasCurtain) {
+        mPickerYear.setCurtain(hasCurtain);
+        mPickerMonth.setCurtain(hasCurtain);
+        mPickerDay.setCurtain(hasCurtain);
+    }
+
+    @Override
+    public boolean hasCurtain() {
+        return mPickerYear.hasCurtain() && mPickerMonth.hasCurtain() &&
+                mPickerDay.hasCurtain();
+    }
+
+    @Override
+    public int getCurtainColor() {
+        if (mPickerYear.getCurtainColor() == mPickerMonth.getCurtainColor() &&
+                mPickerMonth.getCurtainColor() == mPickerDay.getCurtainColor())
+            return mPickerYear.getCurtainColor();
+        throw new RuntimeException("Can not get curtain color correctly from WheelDatePicker!");
+    }
+
+    @Override
+    public void setCurtainColor(int color) {
+        mPickerYear.setCurtainColor(color);
+        mPickerMonth.setCurtainColor(color);
+        mPickerDay.setCurtainColor(color);
+    }
+
+    @Override
+    public void setAtmospheric(boolean hasAtmospheric) {
+        mPickerYear.setAtmospheric(hasAtmospheric);
+        mPickerMonth.setAtmospheric(hasAtmospheric);
+        mPickerDay.setAtmospheric(hasAtmospheric);
+    }
+
+    @Override
+    public boolean hasAtmospheric() {
+        return mPickerYear.hasAtmospheric() && mPickerMonth.hasAtmospheric() &&
+                mPickerDay.hasAtmospheric();
+    }
+
+    @Override
+    public boolean isCurved() {
+        return mPickerYear.isCurved() && mPickerMonth.isCurved() && mPickerDay.isCurved();
+    }
+
+    @Override
+    public void setCurved(boolean isCurved) {
+        mPickerYear.setCurved(isCurved);
+        mPickerMonth.setCurved(isCurved);
+        mPickerDay.setCurved(isCurved);
+    }
+
+    @Deprecated
+    @Override
+    public int getItemAlign() {
+        throw new UnsupportedOperationException("You can not get item align from WheelDatePicker");
+    }
+
+    @Deprecated
+    @Override
+    public void setItemAlign(int align) {
+        throw new UnsupportedOperationException("You don't need to set item align for" +
+                "WheelDatePicker");
+    }
+
+    @Override
+    public Typeface getTypeface() {
+        if (mPickerYear.getTypeface().equals(mPickerMonth.getTypeface()) &&
+                mPickerMonth.getTypeface().equals(mPickerDay.getTypeface()))
+            return mPickerYear.getTypeface();
+        throw new RuntimeException("Can not get typeface correctly from WheelDatePicker!");
+    }
+
+    @Override
+    public void setTypeface(Typeface tf) {
+        mPickerYear.setTypeface(tf);
+        mPickerMonth.setTypeface(tf);
+        mPickerDay.setTypeface(tf);
+    }
+
+    @Override
+    public void setOnDateSelectedListener(OnDateSelectedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public Date getCurrentDate() {
+        String date = mYear + "-" + mMonth + "-" + mDay;
+        try {
+            return SDF.parse(date);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public int getItemAlignYear() {
+        return mPickerYear.getItemAlign();
+    }
+
+    @Override
+    public void setItemAlignYear(int align) {
+        mPickerYear.setItemAlign(align);
+    }
+
+    @Override
+    public int getItemAlignMonth() {
+        return mPickerMonth.getItemAlign();
+    }
+
+    @Override
+    public void setItemAlignMonth(int align) {
+        mPickerMonth.setItemAlign(align);
+    }
+
+    @Override
+    public int getItemAlignDay() {
+        return mPickerDay.getItemAlign();
+    }
+
+    @Override
+    public void setItemAlignDay(int align) {
+        mPickerDay.setItemAlign(align);
+    }
+
+    @Override
+    public WheelYearPicker getWheelYearPicker() {
+        return mPickerYear;
+    }
+
+    @Override
+    public WheelMonthPicker getWheelMonthPicker() {
+        return mPickerMonth;
+    }
+
+    @Override
+    public WheelDayPicker getWheelDayPicker() {
+        return mPickerDay;
+    }
+
+    @Override
+    public TextView getTextViewYear() {
+        return mTVYear;
+    }
+
+    @Override
+    public TextView getTextViewMonth() {
+        return mTVMonth;
+    }
+
+    @Override
+    public TextView getTextViewDay() {
+        return mTVDay;
+    }
+
+    @Override
+    public void setYearFrame(int start, int end) {
+        mPickerYear.setYearFrame(start, end);
+    }
+
+    @Override
+    public int getYearStart() {
+        return mPickerYear.getYearStart();
+    }
+
+    @Override
+    public void setYearStart(int start) {
+        mPickerYear.setYearStart(start);
+    }
+
+    @Override
+    public int getYearEnd() {
+        return mPickerYear.getYearEnd();
+    }
+
+    @Override
+    public void setYearEnd(int end) {
+        mPickerYear.setYearEnd(end);
+    }
+
+    @Override
+    public int getSelectedYear() {
+        return mPickerYear.getSelectedYear();
+    }
+
+    @Override
+    public void setSelectedYear(int year) {
+        mYear = year;
+        mPickerYear.setSelectedYear(year);
+        mPickerDay.setYear(year);
+    }
+
+    @Override
+    public int getCurrentYear() {
+        return mPickerYear.getCurrentYear();
+    }
+
+    @Override
+    public int getSelectedMonth() {
+        return mPickerMonth.getSelectedMonth();
+    }
+
+    @Override
+    public void setSelectedMonth(int month) {
+        mMonth = month;
+        mPickerMonth.setSelectedMonth(month);
+        mPickerDay.setMonth(month);
+    }
+
+    @Override
+    public int getCurrentMonth() {
+        return mPickerMonth.getCurrentMonth();
+    }
+
+    @Override
+    public int getSelectedDay() {
+        return mPickerDay.getSelectedDay();
+    }
+
+    @Override
+    public void setSelectedDay(int day) {
+        mDay = day;
+        mPickerDay.setSelectedDay(day);
+    }
+
+    @Override
+    public int getCurrentDay() {
+        return mPickerDay.getCurrentDay();
+    }
+
+    @Override
+    public void setYearAndMonth(int year, int month) {
+        mYear = year;
+        mMonth = month;
+        mPickerYear.setSelectedYear(year);
+        mPickerMonth.setSelectedMonth(month);
+        mPickerDay.setYearAndMonth(year, month);
+    }
+
+    @Override
+    public int getYear() {
+        return getSelectedYear();
+    }
+
+    @Override
+    public void setYear(int year) {
+        mYear = year;
+        mPickerYear.setSelectedYear(year);
+        mPickerDay.setYear(year);
+    }
+
+    @Override
+    public int getMonth() {
+        return getSelectedMonth();
+    }
+
+    @Override
+    public void setMonth(int month) {
+        mMonth = month;
+        mPickerMonth.setSelectedMonth(month);
+        mPickerDay.setMonth(month);
+    }
+
+    public interface OnDateSelectedListener {
+        void onDateSelected(WheelDatePicker picker, Date date);
+    }
+}

+ 117 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelDayPicker.java

@@ -0,0 +1,117 @@
+package com.aigestudio.wheelpicker.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.aigestudio.wheelpicker.WheelPicker;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 日期选择器
+ * <p>
+ * Picker for Day
+ *
+ * @author AigeStudio 2016-07-12
+ * @version 1
+ */
+public class WheelDayPicker extends WheelPicker implements IWheelDayPicker {
+    private static final Map<Integer, List<Integer>> DAYS = new HashMap<>();
+
+    private Calendar mCalendar;
+
+    private int mYear, mMonth;
+    private int mSelectedDay;
+
+    public WheelDayPicker(Context context) {
+        this(context, null);
+    }
+
+    public WheelDayPicker(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mCalendar = Calendar.getInstance();
+
+        mYear = mCalendar.get(Calendar.YEAR);
+        mMonth = mCalendar.get(Calendar.MONTH);
+
+        updateDays();
+
+        mSelectedDay = mCalendar.get(Calendar.DAY_OF_MONTH);
+
+        updateSelectedDay();
+    }
+
+    private void updateDays() {
+        mCalendar.set(Calendar.YEAR, mYear);
+        mCalendar.set(Calendar.MONTH, mMonth);
+
+        int days = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        List<Integer> data = DAYS.get(days);
+        if (null == data) {
+            data = new ArrayList<>();
+            for (int i = 1; i <= days; i++)
+                data.add(i);
+            DAYS.put(days, data);
+        }
+        super.setData(data);
+    }
+
+    private void updateSelectedDay() {
+        setSelectedItemPosition(mSelectedDay - 1);
+    }
+
+    @Override
+    public void setData(List data) {
+        throw new UnsupportedOperationException("You can not invoke setData in WheelDayPicker");
+    }
+
+    @Override
+    public int getSelectedDay() {
+        return mSelectedDay;
+    }
+
+    @Override
+    public void setSelectedDay(int day) {
+        mSelectedDay = day;
+        updateSelectedDay();
+    }
+
+    @Override
+    public int getCurrentDay() {
+        return Integer.valueOf(String.valueOf(getData().get(getCurrentItemPosition())));
+    }
+
+    @Override
+    public void setYearAndMonth(int year, int month) {
+        mYear = year;
+        mMonth = month - 1;
+        updateDays();
+    }
+
+    @Override
+    public int getYear() {
+        return mYear;
+    }
+
+    @Override
+    public void setYear(int year) {
+        mYear = year;
+        updateDays();
+    }
+
+    @Override
+    public int getMonth() {
+        return mMonth;
+    }
+
+    @Override
+    public void setMonth(int month) {
+        mMonth = month - 1;
+        updateDays();
+    }
+}

+ 63 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelMonthPicker.java

@@ -0,0 +1,63 @@
+package com.aigestudio.wheelpicker.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.aigestudio.wheelpicker.WheelPicker;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * 月份选择器
+ * <p>
+ * Picker for Months
+ *
+ * @author AigeStudio 2016-07-12
+ * @version 1
+ */
+public class WheelMonthPicker extends WheelPicker implements IWheelMonthPicker {
+    private int mSelectedMonth;
+
+    public WheelMonthPicker(Context context) {
+        this(context, null);
+    }
+
+    public WheelMonthPicker(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        List<Integer> data = new ArrayList<>();
+        for (int i = 1; i <= 12; i++)
+            data.add(i);
+        super.setData(data);
+
+        mSelectedMonth = Calendar.getInstance().get(Calendar.MONTH) + 1;
+        updateSelectedYear();
+    }
+
+    private void updateSelectedYear() {
+        setSelectedItemPosition(mSelectedMonth - 1);
+    }
+
+    @Override
+    public void setData(List data) {
+        throw new UnsupportedOperationException("You can not invoke setData in WheelMonthPicker");
+    }
+
+    @Override
+    public int getSelectedMonth() {
+        return mSelectedMonth;
+    }
+
+    @Override
+    public void setSelectedMonth(int month) {
+        mSelectedMonth = month;
+        updateSelectedYear();
+    }
+
+    @Override
+    public int getCurrentMonth() {
+        return Integer.valueOf(String.valueOf(getData().get(getCurrentItemPosition())));
+    }
+}

+ 100 - 0
WheelPicker/src/main/java/com/aigestudio/wheelpicker/widgets/WheelYearPicker.java

@@ -0,0 +1,100 @@
+package com.aigestudio.wheelpicker.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.aigestudio.wheelpicker.WheelPicker;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * 年份选择器
+ * <p>
+ * Picker for Years
+ *
+ * @author AigeStudio 2016-07-12
+ * @version 1
+ */
+public class WheelYearPicker extends WheelPicker implements IWheelYearPicker {
+    private int mYearStart = 1000, mYearEnd = 3000;
+    private int mSelectedYear;
+
+    public WheelYearPicker(Context context) {
+        this(context, null);
+    }
+
+    public WheelYearPicker(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        updateYears();
+        mSelectedYear = Calendar.getInstance().get(Calendar.YEAR);
+        updateSelectedYear();
+    }
+
+    private void updateYears() {
+        List<Integer> data = new ArrayList<>();
+        for (int i = mYearStart; i <= mYearEnd; i++)
+            data.add(i);
+        super.setData(data);
+    }
+
+    private void updateSelectedYear() {
+        setSelectedItemPosition(mSelectedYear - mYearStart);
+    }
+
+    @Override
+    public void setData(List data) {
+        throw new UnsupportedOperationException("You can not invoke setData in WheelYearPicker");
+    }
+
+    @Override
+    public void setYearFrame(int start, int end) {
+        mYearStart = start;
+        mYearEnd = end;
+        mSelectedYear = getCurrentYear();
+        updateYears();
+        updateSelectedYear();
+    }
+
+    @Override
+    public int getYearStart() {
+        return mYearStart;
+    }
+
+    @Override
+    public void setYearStart(int start) {
+        mYearStart = start;
+        mSelectedYear = getCurrentYear();
+        updateYears();
+        updateSelectedYear();
+    }
+
+    @Override
+    public int getYearEnd() {
+        return mYearEnd;
+    }
+
+    @Override
+    public void setYearEnd(int end) {
+        mYearEnd = end;
+        updateYears();
+    }
+
+    @Override
+    public int getSelectedYear() {
+        return mSelectedYear;
+    }
+
+    @Override
+    public void setSelectedYear(int year) {
+        mSelectedYear = year;
+        updateSelectedYear();
+    }
+
+    @Override
+    public int getCurrentYear() {
+        return Integer.valueOf(String.valueOf(getData().get(getCurrentItemPosition())));
+    }
+}

+ 48 - 0
WheelPicker/src/main/res/layout-v17/view_wheel_date_picker.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:orientation="horizontal">
+
+    <com.aigestudio.wheelpicker.widgets.WheelYearPicker
+        android:id="@+id/wheel_date_picker_year"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/wheel_date_picker_year_tv"
+        android:layout_width="wrap_content"
+        android:textColor="#536D8A"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/WheelMargins"
+        android:layout_marginStart="@dimen/WheelMargins"
+        android:text="@string/Year" />
+
+    <com.aigestudio.wheelpicker.widgets.WheelMonthPicker
+        android:id="@+id/wheel_date_picker_month"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:textColor="#536D8A"
+        android:id="@+id/wheel_date_picker_month_tv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/WheelMargins"
+        android:layout_marginStart="@dimen/WheelMargins"
+        android:text="@string/Month" />
+
+    <com.aigestudio.wheelpicker.widgets.WheelDayPicker
+        android:id="@+id/wheel_date_picker_day"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:textColor="#536D8A"
+        android:id="@+id/wheel_date_picker_day_tv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/WheelMargins"
+        android:text="@string/Day" />
+</LinearLayout>

+ 48 - 0
WheelPicker/src/main/res/layout/view_wheel_date_picker.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:orientation="horizontal">
+
+    <com.aigestudio.wheelpicker.widgets.WheelYearPicker
+        android:id="@+id/wheel_date_picker_year"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/wheel_date_picker_year_tv"
+        android:layout_width="wrap_content"
+        android:textColor="#536D8A"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@dimen/WheelMargins"
+        android:layout_marginRight="@dimen/WheelMargins"
+        android:text="@string/Year" />
+
+    <com.aigestudio.wheelpicker.widgets.WheelMonthPicker
+        android:id="@+id/wheel_date_picker_month"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/wheel_date_picker_month_tv"
+        android:layout_width="wrap_content"
+        android:textColor="#536D8A"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@dimen/WheelMargins"
+        android:layout_marginRight="@dimen/WheelMargins"
+        android:text="@string/Month" />
+
+    <com.aigestudio.wheelpicker.widgets.WheelDayPicker
+        android:id="@+id/wheel_date_picker_day"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/wheel_date_picker_day_tv"
+        android:layout_width="wrap_content"
+        android:textColor="#536D8A"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@dimen/WheelMargins"
+        android:text="@string/Day" />
+</LinearLayout>

+ 6 - 0
WheelPicker/src/main/res/values-zh/strings.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="Year">年</string>
+    <string name="Month">月</string>
+    <string name="Day">日</string>
+</resources>

+ 38 - 0
WheelPicker/src/main/res/values/arrays.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string-array name="WheelArrayDefault">
+        <item>AigeStudio</item>
+        <item>Aige</item>
+        <item>爱哥</item>
+        <item>الحب  اخي</item>
+        <item>jeg elsker</item>
+        <item>사랑해요 형</item>
+        <item>Amor de irmão</item>
+        <item>armastan</item>
+        <item>愛の兄</item>
+        <item>обичам те</item>
+        <item>любовь - братa</item>
+        <item>miłość bracie</item>
+        <item>Liebe</item>
+        <item>Lamour</item>
+        <item>rakastan sinua</item>
+        <item>láska..</item>
+        <item>dragostea.</item>
+        <item>jag älskar</item>
+        <item>ljubezen, brat.</item>
+        <item>愛哥</item>
+        <item>ชอบพี่</item>
+        <item>αγάπη μου</item>
+        <item>a szerelem.</item>
+        <item>Amore, fratello.</item>
+    </string-array>
+    <string-array name="WheelArrayWeek">
+        <item>Monday</item>
+        <item>Tuesday</item>
+        <item>Wednesday</item>
+        <item>Thursday</item>
+        <item>Friday</item>
+        <item>Saturday</item>
+        <item>Sunday</item>
+    </string-array>
+</resources>

+ 29 - 0
WheelPicker/src/main/res/values/attrs.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="WheelPicker">
+        <attr name="wheel_data" format="reference" />
+        <attr name="wheel_selected_item_position" format="integer" />
+        <attr name="wheel_item_text_size" format="dimension" />
+        <attr name="wheel_item_text_color" format="color" />
+        <attr name="wheel_selected_item_text_color" format="color" />
+        <attr name="wheel_same_width" format="boolean" />
+        <attr name="wheel_maximum_width_text" format="string" />
+        <attr name="wheel_maximum_width_text_position" format="integer" />
+        <attr name="wheel_visible_item_count" format="integer" />
+        <attr name="wheel_item_space" format="dimension" />
+        <attr name="wheel_cyclic" format="boolean" />
+        <attr name="wheel_indicator" format="boolean" />
+        <attr name="wheel_indicator_color" format="color" />
+        <attr name="wheel_indicator_size" format="dimension" />
+        <attr name="wheel_curtain" format="boolean" />
+        <attr name="wheel_curtain_color" format="color" />
+        <attr name="wheel_atmospheric" format="boolean" />
+        <attr name="wheel_curved" format="boolean" />
+        <attr name="wheel_item_align" format="enum">
+            <enum name="center" value="0" />
+            <enum name="left" value="1" />
+            <enum name="right" value="2" />
+        </attr>
+        <attr name="wheel_font_path" format="string" />
+    </declare-styleable>
+</resources>

+ 7 - 0
WheelPicker/src/main/res/values/dimens.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <dimen name="WheelItemTextSize">24sp</dimen>
+    <dimen name="WheelItemSpace">12dp</dimen>
+    <dimen name="WheelIndicatorSize">2dp</dimen>
+    <dimen name="WheelMargins">8dp</dimen>
+</resources>

+ 6 - 0
WheelPicker/src/main/res/values/strings.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="Year">Y</string>
+    <string name="Month">M</string>
+    <string name="Day">D</string>
+</resources>

+ 21 - 0
build.gradle

@@ -0,0 +1,21 @@
+buildscript {
+    repositories {
+        jcenter()
+        google()
+        mavenCentral()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.4.1'
+        classpath 'com.novoda:bintray-release:0.9.1'
+    }
+}
+allprojects {
+    repositories {
+        jcenter()
+        google()
+        mavenCentral()
+    }
+}
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 0 - 0
gradle.properties


BIN
gradle/wrapper/gradle-wrapper.jar


+ 5 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

+ 8 - 0
local.properties

@@ -0,0 +1,8 @@
+## This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+#Wed Oct 09 15:34:32 GMT+08:00 2019
+sdk.dir=D\:\\Program Files\\Android\\Sdk

+ 1 - 0
settings.gradle

@@ -0,0 +1 @@
+include ':Demo', ':WheelPicker'