Browse Source

修改包名,优化代码

yanyi 5 years ago
parent
commit
37668cbf04
25 changed files with 1904 additions and 1764 deletions
  1. 17 26
      README.md
  2. 1 1
      app/src/main/java/com/yanyi/dateselect/MainActivity.java
  3. 1 1
      build.gradle
  4. 4 4
      datelib/bintrayUpload.gradle
  5. 45 57
      datelib/src/main/java/com/benyanyi/datelib/SelectData.java
  6. 115 62
      datelib/src/main/java/com/benyanyi/datelib/SelectPeriod.java
  7. 1 1
      datelib/src/main/java/com/benyanyi/datelib/config/SelectType.java
  8. 11 12
      datelib/src/main/java/com/benyanyi/datelib/wheelview/AbstractWheelAdapter.java
  9. 335 0
      datelib/src/main/java/com/benyanyi/datelib/wheelview/AbstractWheelTextAdapter1.java
  10. 92 0
      datelib/src/main/java/com/benyanyi/datelib/wheelview/ItemsRange.java
  11. 1 1
      datelib/src/main/java/com/benyanyi/datelib/wheelview/OnWheelChangedListener.java
  12. 1 1
      datelib/src/main/java/com/benyanyi/datelib/wheelview/OnWheelClickedListener.java
  13. 1 1
      datelib/src/main/java/com/benyanyi/datelib/wheelview/OnWheelScrollListener.java
  14. 169 0
      datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelRecycle.java
  15. 72 50
      datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelScroller.java
  16. 1021 0
      datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelView.java
  17. 1 1
      datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelViewAdapter.java
  18. 0 330
      datelib/src/main/java/com/yanyi/datelib/wheelview/AbstractWheelTextAdapter1.java
  19. 0 82
      datelib/src/main/java/com/yanyi/datelib/wheelview/ItemsRange.java
  20. 0 154
      datelib/src/main/java/com/yanyi/datelib/wheelview/WheelRecycle.java
  21. 0 964
      datelib/src/main/java/com/yanyi/datelib/wheelview/WheelView.java
  22. 5 5
      datelib/src/main/res/layout/select_date_pop_layout.xml
  23. 10 10
      datelib/src/main/res/layout/select_period_pop_layout.xml
  24. 1 1
      gradle/wrapper/gradle-wrapper.properties
  25. 0 0
      gradlew

+ 17 - 26
README.md

@@ -5,36 +5,16 @@
 
 #### module 下添加
 
-     compile 'com.github.BenYanYi:DateSelect:1.0.3'
-     或者
-     compile 'com.yanyi.benyanyi:datelib:1.0.0'
-     推荐使用下面这种,第一种今后将停止更新维护
+     compile 'com.yanyi.benyanyi:datelib:1.0.1'
 
-#### 使用第一种方法project 下添加
-
-    allprojects {
-        repositories {
-            jcenter()
-            maven {
-                url 'https://jitpack.io'
-            }
-        }
-    }
-    
-* 2018-06-09更新
-
-    变更开源库地址,之前的开源库将不再提交更新,推荐大家最新的引用方法    
-    
-* 1.0.3版本
+* 1.0.1版本
 
-    SelectPeriod添加是否进行时间判断<br/>
-    SelectPeriod(Context context, SelectType selectType, boolean judgmentTime)
+      SelectPeriod添加是否进行时间判断<br/>
+      SelectPeriod(Context context, SelectType selectType, boolean judgmentTime)
     
-* 1.0.2版本
-
       SelectData selectData = new SelectData(this,selectType);
     
-      其余与1.0.1版本一样
+      其余与1.0.0版本一样
     
       SelectType 表示需要隐藏的段落
     
@@ -53,7 +33,7 @@
           }
       });
     
-* 1.0.1版本
+* 1.0.0版本
 ##### 带时间的选择器
     SelectData selectData = new SelectData(this);
     selectData.showAtLocation(but, Gravity.BOTTOM, 0, 0);
@@ -72,3 +52,14 @@
             Toast.makeText(MainActivity.this, year + "-" + month + "-" + day , Toast.LENGTH_SHORT).show();
         }
     });
+
+### 更新记录
+* 2019-06-12 提交1.0.1版本,优化一些已知细节,变更包名,开源库包名进行统一
+* 2018-06-09 提交1.0.0版本
+
+<br/>
+若在使用过程中出现什么问题,可以联系作者<br/>
+作者:演绎<br/>
+QQ:1541612424<br/>
+email: work@yanyi.red<br/>
+微信公众号:benyanyi(演绎未来)&nbsp;&nbsp;&nbsp;将会不定期的更新关于android的一些文章

+ 1 - 1
app/src/main/java/com/yanyi/dateselect/MainActivity.java

@@ -8,7 +8,7 @@ import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 
-import com.yanyi.datelib.SelectPeriod;
+import com.benyanyi.datelib.SelectPeriod;
 
 /**
  * @author Administrator

+ 1 - 1
build.gradle

@@ -7,7 +7,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.0.1'
+        classpath 'com.android.tools.build:gradle:3.2.1'
         classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
         classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.2'
 

+ 4 - 4
datelib/bintrayUpload.gradle

@@ -3,11 +3,11 @@ apply plugin: 'com.github.dcendents.android-maven'
 apply plugin: 'com.jfrog.bintray'
 
 // 定义两个链接,下面会用到。
-def siteUrl = 'https://github.com/BenYanYi/DateSelect' // 项目主页。
-def gitUrl = 'https://github.com/BenYanYi/DateSelect.git' // Git仓库的url。
+def siteUrl = 'http://www.yanyis.space/yanyi/dateselect' // 项目主页。
+def gitUrl = 'http://www.yanyis.space/yanyi/dateselect.git' // Git仓库的url。
 
 group = "com.yanyi.benyanyi"// 唯一包名,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的com.ansen.http就是这里配置的。
-version = "1.0.0"//项目引用的版本号,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的1.0.1就是这里配置的。
+version = "1.0.1"//项目引用的版本号,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的1.0.1就是这里配置的。
 install {
     repositories.mavenInstaller {
         // This generates POM.xml with proper parameters
@@ -72,7 +72,7 @@ bintray {
     }
 }
 javadoc { //jav doc采用utf-8编码否则会报“GBK的不可映射字符”错误
-    options{
+    options {
         encoding "UTF-8"
         charSet 'UTF-8'
     }

+ 45 - 57
datelib/src/main/java/com/yanyi/datelib/SelectData.java → datelib/src/main/java/com/benyanyi/datelib/SelectData.java

@@ -1,4 +1,4 @@
-package com.yanyi.datelib;
+package com.benyanyi.datelib;
 
 import android.content.Context;
 import android.graphics.drawable.ColorDrawable;
@@ -9,11 +9,12 @@ import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 import android.widget.TextView;
 
-import com.yanyi.datelib.config.SelectType;
-import com.yanyi.datelib.wheelview.AbstractWheelTextAdapter1;
-import com.yanyi.datelib.wheelview.OnWheelChangedListener;
-import com.yanyi.datelib.wheelview.OnWheelScrollListener;
-import com.yanyi.datelib.wheelview.WheelView;
+import com.benyanyi.datelib.config.SelectType;
+import com.benyanyi.datelib.wheelview.AbstractWheelTextAdapter1;
+import com.benyanyi.datelib.wheelview.OnWheelChangedListener;
+import com.benyanyi.datelib.wheelview.OnWheelScrollListener;
+import com.benyanyi.datelib.wheelview.WheelView;
+import com.yanyi.datelib.R;
 
 import org.json.JSONObject;
 
@@ -21,7 +22,7 @@ import java.util.ArrayList;
 import java.util.Calendar;
 
 /**
- * Created by wuguilin on 1/9/2017.
+ * @author yanyi
  */
 
 
@@ -68,32 +69,31 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
         this(context, SelectType.NONE);
     }
 
+    /**
+     * 设置SelectPicPopupWindow弹出窗体动画效果
+     * this.setAnimationStyle(R.style.AnimBottom);
+     *
+     * @param context
+     * @param selectType
+     */
     public SelectData(final Context context, SelectType selectType) {
         super(context);
         this.context = context;
         this.selectType = selectType;
         View view = View.inflate(context, R.layout.select_date_pop_layout, null);
 
-        wvYear = (WheelView) view.findViewById(R.id.wv_date_year);
-        wvMonth = (WheelView) view.findViewById(R.id.wv_date_month);
-        wvDay = (WheelView) view.findViewById(R.id.wv_date_day);
-        wvHour = (WheelView) view.findViewById(R.id.wv_date_hour);
-        wvMinute = (WheelView) view.findViewById(R.id.wv_date_minute);
+        wvYear = view.findViewById(R.id.wv_date_year);
+        wvMonth = view.findViewById(R.id.wv_date_month);
+        wvDay = view.findViewById(R.id.wv_date_day);
+        wvHour = view.findViewById(R.id.wv_date_hour);
+        wvMinute = view.findViewById(R.id.wv_date_minute);
         lySelectDate = view.findViewById(R.id.select_date);
         lySelectDateChild = view.findViewById(R.id.select_date_child);
-        btnSure = (TextView) view.findViewById(R.id.btn_myinfo_sure);
-        btnCancel = (TextView) view.findViewById(R.id.btn_myinfo_cancel);
-
-        hourContainer = (LinearLayout) view.findViewById(R.id.hour_container);
-        minuteContainer = (LinearLayout) view.findViewById(R.id.minute_container);
-//        if(showTime){
-//            hourContainer.setVisibility(View.VISIBLE);
-//            minuteContainer.setVisibility(View.VISIBLE);
-//        }else {
-//            hourContainer.setVisibility(View.GONE);
-//            minuteContainer.setVisibility(View.GONE);
-//        }
+        btnSure = view.findViewById(R.id.btn_myinfo_sure);
+        btnCancel = view.findViewById(R.id.btn_myinfo_cancel);
 
+        hourContainer = view.findViewById(R.id.hour_container);
+        minuteContainer = view.findViewById(R.id.minute_container);
         switch (selectType) {
             case NONE:
             default:
@@ -115,8 +115,6 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
         this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
         //设置SelectPicPopupWindow弹出窗体可点击
         this.setFocusable(true);
-        //设置SelectPicPopupWindow弹出窗体动画效果
-//		this.setAnimationStyle(R.style.AnimBottom);
         //实例化一个ColorDrawable颜色为半透明
         ColorDrawable dw = new ColorDrawable(0xb0000000);
         //设置SelectPicPopupWindow弹出窗体的背景
@@ -126,7 +124,7 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
         btnSure.setOnClickListener(this);
         btnCancel.setOnClickListener(this);
 
-        initDatas();
+        initDates();
 
         yearAdapter = new DateTextAdapter(context, mYearDatas, Integer.parseInt(strYear) - calendar.get(Calendar.YEAR) + 100, maxSize, minSize);
         wvYear.setVisibleItems(5);
@@ -139,7 +137,6 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
         wvMonth.setViewAdapter(monthAdapter);
         wvMonth.setCurrentItem(Integer.parseInt(strMonth) - 1);
 
-        //initDays(mAreaDatasMap.get(strMonth));
         dayAdapter = new DateTextAdapter(context, mDayDatas, Integer.parseInt(strDay) - 1, maxSize, minSize);
         wvDay.setVisibleItems(5);
         wvDay.setViewAdapter(dayAdapter);
@@ -387,30 +384,19 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
      * @author Administrator
      */
     public interface OnDateClickListener {
+        /**
+         * 点击回调
+         *
+         * @param year
+         * @param month
+         * @param day
+         * @param hour
+         * @param minute
+         */
         void onClick(String year, String month, String day, String hour, String minute);
     }
 
-    /**
-     * 从文件中读取地址数据
-     */
-/*    private void initJsonData() {
-        try {
-            StringBuffer sb = new StringBuffer();
-            InputStream is = context.getClass().getClassLoader().getResourceAsStream("assets/" + "city.json");
-            int len = -1;
-            byte[] buf = new byte[1024];
-            while ((len = is.read(buf)) != -1) {
-                sb.append(new String(buf, 0, len, "gbk"));
-            }
-            is.close();
-            mJsonObj = new JSONObject(sb.toString());
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (JSONException e) {
-            e.printStackTrace();
-        }
-    }*/
-    private void initDatas() {
+    private void initDates() {
         int year, month, day, hour, minute;
 
         year = calendar.get(Calendar.YEAR);
@@ -437,12 +423,14 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
                 break;
         }
         mYearDatas = new String[150];
-        //int year = calendar.get(Calendar.YEAR);
-        for (int i = year - 100, j = 0; i < year + 50; i++, j++) {
+        int i1 = 100;
+        int i2 = 50;
+        for (int i = year - i1, j = 0; i < year + i2; i++, j++) {
             mYearDatas[j] = i + "";
         }
         mMonthDatas = new String[12];
-        for (int i = 0; i < 12; i++) {
+        int i3 = 12;
+        for (int i = 0; i < i3; i++) {
             if (i < 9) {
                 mMonthDatas[i] = "0" + (i + 1) + "";
             } else {
@@ -451,8 +439,6 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
 
         }
         int count = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
-        //Log.e(TAG, "initDatas: "+ strYear+":"+strMonth+":"+strDay+":"+count);
-
 
         mDayDatas = new String[count];
         for (int i = 0; i < count; i++) {
@@ -464,7 +450,8 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
 
         }
         mHourDatas = new String[24];
-        for (int i = 0; i < 24; i++) {
+        int i4 = 24;
+        for (int i = 0; i < i4; i++) {
             if (i < 10) {
                 mHourDatas[i] = "0" + i;
             } else {
@@ -472,8 +459,9 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
             }
 
         }
+        int i5 = 60;
         mMinuteDatas = new String[60];
-        for (int i = 0; i < 60; i++) {
+        for (int i = 0; i < i5; i++) {
             if (i < 10) {
                 mMinuteDatas[i] = "0" + i;
             } else {
@@ -489,7 +477,7 @@ public class SelectData extends PopupWindow implements View.OnClickListener {
         // newCal.s
         newCal.set(Calendar.YEAR, year);
         newCal.set(Calendar.MONTH, month - 1);
-        int count = newCal.getActualMaximum(Calendar.DAY_OF_MONTH);//new Date(year,month,0).getDate();
+        int count = newCal.getActualMaximum(Calendar.DAY_OF_MONTH);
 
         Log.e(TAG, "getDays: " + year + ":" + month + ":" + count);
         datas = new String[count];

+ 115 - 62
datelib/src/main/java/com/yanyi/datelib/SelectPeriod.java → datelib/src/main/java/com/benyanyi/datelib/SelectPeriod.java

@@ -1,4 +1,4 @@
-package com.yanyi.datelib;
+package com.benyanyi.datelib;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
@@ -11,11 +11,12 @@ import android.widget.PopupWindow;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.yanyi.datelib.config.SelectType;
-import com.yanyi.datelib.wheelview.AbstractWheelTextAdapter1;
-import com.yanyi.datelib.wheelview.OnWheelChangedListener;
-import com.yanyi.datelib.wheelview.OnWheelScrollListener;
-import com.yanyi.datelib.wheelview.WheelView;
+import com.benyanyi.datelib.config.SelectType;
+import com.benyanyi.datelib.wheelview.AbstractWheelTextAdapter1;
+import com.benyanyi.datelib.wheelview.OnWheelChangedListener;
+import com.benyanyi.datelib.wheelview.OnWheelScrollListener;
+import com.benyanyi.datelib.wheelview.WheelView;
+import com.yanyi.datelib.R;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -27,7 +28,7 @@ import java.util.Locale;
  * @author myLove
  */
 public class SelectPeriod extends PopupWindow implements View.OnClickListener {
-    private String TAG = "SelectPeriod";
+    private String tag = "SelectPeriod";
     private Context mContext;
     private SelectType selectType;
     private boolean boo;
@@ -36,8 +37,14 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
 
     private View mView;
 
-    private TextView butCancel;//取消按钮
-    private TextView butSend;//确定按钮
+    /**
+     * 取消按钮
+     */
+    private TextView butCancel;
+    /**
+     * 确定按钮
+     */
+    private TextView butSend;
     private LinearLayout timeLinear;
 
     private LinearLayout startTimeLinear;
@@ -124,8 +131,6 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
         this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
         //设置SelectPicPopupWindow弹出窗体可点击
         this.setFocusable(true);
-        //设置SelectPicPopupWindow弹出窗体动画效果
-//		this.setAnimationStyle(R.style.AnimBottom);
         //实例化一个ColorDrawable颜色为半透明
         ColorDrawable dw = new ColorDrawable(0xb0000000);
         //设置SelectPicPopupWindow弹出窗体的背景
@@ -140,37 +145,37 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
     }
 
     private void init() {
-        butCancel = $(R.id.but_cancel);
+        butCancel = findView(R.id.but_cancel);
         butCancel.setOnClickListener(this);
-        butSend = $(R.id.but_send);
+        butSend = findView(R.id.but_send);
         butSend.setOnClickListener(this);
-        timeLinear = $(R.id.time_linear);
+        timeLinear = findView(R.id.time_linear);
         timeLinear.setBackgroundResource(R.mipmap.begin_time_bg);
-        startTimeLinear = $(R.id.start_time_linear);
-        startTimeTv = $(R.id.start_time);
+        startTimeLinear = findView(R.id.start_time_linear);
+        startTimeTv = findView(R.id.start_time);
         startTimeLinear.setOnClickListener(this);
-        endTimeLinear = $(R.id.end_time_linear);
-        endTimeTv = $(R.id.end_time);
+        endTimeLinear = findView(R.id.end_time_linear);
+        endTimeTv = findView(R.id.end_time);
         endTimeLinear.setOnClickListener(this);
 
-        startLinear = $(R.id.start_linear);
-        startYearWv = $(R.id.start_year);
-        startMonthWv = $(R.id.start_month);
-        startDayWv = $(R.id.start_day);
-        startHourLinear = $(R.id.start_hour_linear);
-        startHourWv = $(R.id.start_hour);
-        startMinuteLinear = $(R.id.start_minute_linear);
-        startMinuteWv = $(R.id.start_minute);
+        startLinear = findView(R.id.start_linear);
+        startYearWv = findView(R.id.start_year);
+        startMonthWv = findView(R.id.start_month);
+        startDayWv = findView(R.id.start_day);
+        startHourLinear = findView(R.id.start_hour_linear);
+        startHourWv = findView(R.id.start_hour);
+        startMinuteLinear = findView(R.id.start_minute_linear);
+        startMinuteWv = findView(R.id.start_minute);
         startLinear.setVisibility(View.VISIBLE);
 
-        endLinear = $(R.id.end_linear);
-        endYearWv = $(R.id.end_year);
-        endMonthWv = $(R.id.end_month);
-        endDayWv = $(R.id.end_day);
-        endHourLinear = $(R.id.end_hour_linear);
-        endHourWv = $(R.id.end_hour);
-        endMinuteLinear = $(R.id.end_minute_linear);
-        endMinuteWv = $(R.id.end_minute);
+        endLinear = findView(R.id.end_linear);
+        endYearWv = findView(R.id.end_year);
+        endMonthWv = findView(R.id.end_month);
+        endDayWv = findView(R.id.end_day);
+        endHourLinear = findView(R.id.end_hour_linear);
+        endHourWv = findView(R.id.end_hour);
+        endMinuteLinear = findView(R.id.end_minute_linear);
+        endMinuteWv = findView(R.id.end_minute);
         endLinear.setVisibility(View.GONE);
 
         switch (selectType) {
@@ -199,30 +204,28 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
         hour = calendar.get(Calendar.HOUR_OF_DAY);
         minute = calendar.get(Calendar.MINUTE);
         String strYear = String.valueOf(year);
-        String strMonth = (month < 10 ? "0" : "") + String.valueOf(month);
-        String strDay = (day < 10 ? "0" : "") + String.valueOf(day);
+        String strMonth = (month < 10 ? "0" : "") + month;
+        String strDay = (day < 10 ? "0" : "") + day;
         startYear = strYear;
         endYear = strYear;
         startMonth = strMonth;
         endMonth = strMonth;
         startDay = strDay;
         endDay = strDay;
-
         String strHour;
         String strMinute;
-
         switch (selectType) {
             case NONE:
             default:
-                strHour = (hour < 10 ? "0" : "") + String.valueOf(hour);
-                strMinute = (minute < 10 ? "0" : "") + String.valueOf(minute);
+                strHour = (hour < 10 ? "0" : "") + hour;
+                strMinute = (minute < 10 ? "0" : "") + minute;
                 break;
             case HOUR:
                 strHour = "00";
                 strMinute = "00";
                 break;
             case MIN:
-                strHour = (hour < 10 ? "0" : "") + String.valueOf(hour);
+                strHour = (hour < 10 ? "0" : "") + hour;
                 strMinute = "00";
                 break;
         }
@@ -233,15 +236,16 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
 
         startYearData = new String[150];
         endYearData = new String[150];
-        //int year = calendar.get(Calendar.YEAR);
-        for (int i = year - 100, j = 0; i < year + 50; i++, j++) {
+        int i1 = 100;
+        int i2 = 50;
+        for (int i = year - i1, j = 0; i < year + i2; i++, j++) {
             startYearData[j] = i + "";
             endYearData[j] = i + "";
         }
-
         startMonthData = new String[12];
         endMonthData = new String[12];
-        for (int i = 0; i < 12; i++) {
+        int i3 = 12;
+        for (int i = 0; i < i3; i++) {
             if (i < 9) {
                 startMonthData[i] = "0" + (i + 1) + "";
                 endMonthData[i] = "0" + (i + 1) + "";
@@ -250,10 +254,7 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 endMonthData[i] = i + 1 + "";
             }
         }
-
         int count = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
-        //Log.e(TAG, "initDatas: "+ strYear+":"+strMonth+":"+strDay+":"+count);
-
         startDayData = new String[count];
         endDayData = new String[count];
         for (int i = 0; i < count; i++) {
@@ -265,10 +266,10 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 endDayData[i] = i + 1 + "";
             }
         }
-
         startHourData = new String[24];
         endHourData = new String[24];
-        for (int i = 0; i < 24; i++) {
+        int i4 = 24;
+        for (int i = 0; i < i4; i++) {
             if (i < 10) {
                 startHourData[i] = "0" + i;
                 endHourData[i] = "0" + i;
@@ -277,10 +278,10 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 endHourData[i] = i + "";
             }
         }
-
         startMinuteData = new String[60];
         endMinuteData = new String[60];
-        for (int i = 0; i < 60; i++) {
+        int i5 = 60;
+        for (int i = 0; i < i5; i++) {
             if (i < 10) {
                 startMinuteData[i] = "0" + i;
                 endMinuteData[i] = "0" + i;
@@ -320,6 +321,19 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
         startMinuteWv.setViewAdapter(startMinuteAdapter);
         startMinuteWv.setCurrentItem(Integer.parseInt(startMinute));
 
+        startYearListener();
+
+        startMonListener();
+
+        startDayListener();
+
+        startHourListener();
+
+        startMinListener();
+
+    }
+
+    private void startYearListener() {
         startYearWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -351,7 +365,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
 
             }
         });
+    }
 
+    private void startMonListener() {
         startMonthWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -381,7 +397,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, startMonthAdapter);
             }
         });
+    }
 
+    private void startDayListener() {
         startDayWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -404,12 +422,13 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, startDayAdapter);
             }
         });
+    }
 
+    private void startHourListener() {
         startHourWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
                 String currentText = (String) startHourAdapter.getItemText(wheel.getCurrentItem());
-//                startMinute = currentText;
                 startHour = currentText;
                 setTextViewSize(currentText, startHourAdapter);
 
@@ -428,6 +447,10 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, startHourAdapter);
             }
         });
+    }
+
+    private void startMinListener() {
+
         startMinuteWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -479,6 +502,20 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
         endMinuteWv.setViewAdapter(endMinuteAdapter);
         endMinuteWv.setCurrentItem(Integer.parseInt(endMinute));
 
+        endYearListener();
+
+        endMonListener();
+
+        endDayListener();
+
+        endHourListener();
+
+        endMinListener();
+
+
+    }
+
+    private void endYearListener() {
         endYearWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -509,7 +546,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, endYearAdapter);
             }
         });
+    }
 
+    private void endMonListener() {
         endMonthWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -539,7 +578,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, endMonthAdapter);
             }
         });
+    }
 
+    private void endDayListener() {
         endDayWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -562,7 +603,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, endDayAdapter);
             }
         });
+    }
 
+    private void endHourListener() {
         endHourWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -586,6 +629,10 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 setTextViewSize(currentText, endHourAdapter);
             }
         });
+    }
+
+    private void endMinListener() {
+
         endMinuteWv.addChangingListener(new OnWheelChangedListener() {
             @Override
             public void onChanged(WheelView wheel, int oldValue, int newValue) {
@@ -619,9 +666,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
                 String endTimeStr = getEndTimeStr();
                 log(getStringDate());
                 if (boo) {
-                    if (TimeComparison(startTimeStr, getStringDate())) {
-                        if (TimeComparison(endTimeStr, getStringDate())) {
-                            if (TimeComparison(startTimeStr, endTimeStr)) {
+                    if (timeComparison(startTimeStr, getStringDate())) {
+                        if (timeComparison(endTimeStr, getStringDate())) {
+                            if (timeComparison(startTimeStr, endTimeStr)) {
                                 log(startTimeStr + "\t" + endTimeStr);
                                 onDateClickListener.onDateClickListener(startTimeStr, endTimeStr);
                                 dismiss();
@@ -687,7 +734,7 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
         return endTimeStr;
     }
 
-    private <T extends View> T $(int id) {
+    private <T extends View> T findView(int id) {
         return mView.findViewById(id);
     }
 
@@ -723,7 +770,7 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
      * @return true 表示为真
      */
     @SuppressLint("SimpleDateFormat")
-    private boolean TimeComparison(String startTime, String endTime) {
+    private boolean timeComparison(String startTime, String endTime) {
         boolean mAfter = true;
         try {
             @SuppressLint("SimpleDateFormat")
@@ -799,9 +846,9 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
         // newCal.s
         newCal.set(Calendar.YEAR, year);
         newCal.set(Calendar.MONTH, month - 1);
-        int count = newCal.getActualMaximum(Calendar.DAY_OF_MONTH);//new Date(year,month,0).getDate();
+        int count = newCal.getActualMaximum(Calendar.DAY_OF_MONTH);
 
-        Log.e(TAG, "getDays: " + year + ":" + month + ":" + count);
+        Log.e(tag, "getDays: " + year + ":" + month + ":" + count);
         datas = new String[count];
         for (int i = 0; i < count; i++) {
             if (i < 9) {
@@ -814,8 +861,8 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
     }
 
     private void log(Object obj) {
-        if (isDebug){
-            Log.v(TAG, obj.toString());
+        if (isDebug) {
+            Log.v(tag, obj.toString());
         }
     }
 
@@ -828,6 +875,12 @@ public class SelectPeriod extends PopupWindow implements View.OnClickListener {
     }
 
     public interface OnDateClickListener {
+        /**
+         * 选择结果
+         *
+         * @param startTime
+         * @param endTime
+         */
         void onDateClickListener(String startTime, String endTime);
     }
 }

+ 1 - 1
datelib/src/main/java/com/yanyi/datelib/config/SelectType.java → datelib/src/main/java/com/benyanyi/datelib/config/SelectType.java

@@ -1,4 +1,4 @@
-package com.yanyi.datelib.config;
+package com.benyanyi.datelib.config;
 
 /**
  * @author myLove

+ 11 - 12
datelib/src/main/java/com/yanyi/datelib/wheelview/AbstractWheelAdapter.java → datelib/src/main/java/com/benyanyi/datelib/wheelview/AbstractWheelAdapter.java

@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package com.yanyi.datelib.wheelview;
+package com.benyanyi.datelib.wheelview;
 
 import android.database.DataSetObserver;
 import android.view.View;
@@ -28,8 +28,7 @@ import java.util.List;
  * @author myLove
  */
 public abstract class AbstractWheelAdapter implements WheelViewAdapter {
-    // Observers
-    private List<DataSetObserver> datasetObservers;
+    private List<DataSetObserver> dataSetObservers;
     
     @Override
     public View getEmptyItem(View convertView, ViewGroup parent) {
@@ -38,16 +37,16 @@ public abstract class AbstractWheelAdapter implements WheelViewAdapter {
 
     @Override
     public void registerDataSetObserver(DataSetObserver observer) {
-        if (datasetObservers == null) {
-            datasetObservers = new LinkedList<DataSetObserver>();
+        if (dataSetObservers == null) {
+            dataSetObservers = new LinkedList<DataSetObserver>();
         }
-        datasetObservers.add(observer);
+        dataSetObservers.add(observer);
     }
 
     @Override
     public void unregisterDataSetObserver(DataSetObserver observer) {
-        if (datasetObservers != null) {
-            datasetObservers.remove(observer);
+        if (dataSetObservers != null) {
+            dataSetObservers.remove(observer);
         }
     }
     
@@ -55,8 +54,8 @@ public abstract class AbstractWheelAdapter implements WheelViewAdapter {
      * Notifies observers about data changing
      */
     protected void notifyDataChangedEvent() {
-        if (datasetObservers != null) {
-            for (DataSetObserver observer : datasetObservers) {
+        if (dataSetObservers != null) {
+            for (DataSetObserver observer : dataSetObservers) {
                 observer.onChanged();
             }
         }
@@ -66,8 +65,8 @@ public abstract class AbstractWheelAdapter implements WheelViewAdapter {
      * Notifies observers about invalidating data
      */
     protected void notifyDataInvalidatedEvent() {
-        if (datasetObservers != null) {
-            for (DataSetObserver observer : datasetObservers) {
+        if (dataSetObservers != null) {
+            for (DataSetObserver observer : dataSetObservers) {
                 observer.onInvalidated();
             }
         }

+ 335 - 0
datelib/src/main/java/com/benyanyi/datelib/wheelview/AbstractWheelTextAdapter1.java

@@ -0,0 +1,335 @@
+/*
+ *  Copyright 2011 Yuri Kanivets
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.benyanyi.datelib.wheelview;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Abstract wheel adapter provides common functionality for adapters.
+ *
+ * @author myLove
+ */
+public abstract class AbstractWheelTextAdapter1 extends AbstractWheelAdapter {
+
+    /**
+     * Text view resource. Used as a default view for adapter.
+     */
+    public static final int TEXT_VIEW_ITEM_RESOURCE = -1;
+
+    /**
+     * No resource constant.
+     */
+    protected static final int NO_RESOURCE = 0;
+
+    /**
+     * Default text color
+     */
+    public static final int DEFAULT_TEXT_COLOR = 0xFF101010;
+
+    /**
+     * Default text color
+     */
+    public static final int LABEL_COLOR = 0xFF700070;
+
+    /**
+     * Default text size
+     */
+    public static final int DEFAULT_TEXT_SIZE = 24;
+
+    /**
+     * Text settings
+     */
+    private int textColor = DEFAULT_TEXT_COLOR;
+    private int textSize = DEFAULT_TEXT_SIZE;
+
+    /**
+     * Current context
+     */
+    protected Context context;
+    /**
+     * Layout inflater
+     */
+    protected LayoutInflater inflater;
+
+    /**
+     * Items resources
+     */
+    protected int itemResourceId;
+    protected int itemTextResourceId;
+
+    /**
+     * Empty items resources
+     */
+    protected int emptyItemResourceId;
+
+    private int currentIndex = 0;
+    private static int maxSize = 14;
+    private static int minSize = 12;
+    private ArrayList<View> arrayList = new ArrayList<View>();
+
+    /**
+     * Constructor
+     *
+     * @param context the current context
+     */
+    protected AbstractWheelTextAdapter1(Context context) {
+        this(context, TEXT_VIEW_ITEM_RESOURCE);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param context      the current context
+     * @param itemResource the resource ID for a layout file containing a TextView to use
+     *                     when instantiating items views
+     */
+    protected AbstractWheelTextAdapter1(Context context, int itemResource) {
+        this(context, itemResource, NO_RESOURCE, 0, maxSize, minSize);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param context          the current context
+     * @param itemResource     the resource ID for a layout file containing a TextView to use
+     *                         when instantiating items views
+     * @param itemTextResource the resource ID for a text view in the item layout
+     */
+    protected AbstractWheelTextAdapter1(Context context, int itemResource, int itemTextResource, int currentIndex,
+                                        int maxSize, int minSize) {
+        this.context = context;
+        itemResourceId = itemResource;
+        itemTextResourceId = itemTextResource;
+        this.currentIndex = currentIndex;
+        AbstractWheelTextAdapter1.maxSize = maxSize;
+        AbstractWheelTextAdapter1.minSize = minSize;
+
+        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+
+    /**
+     * get the list of show textview
+     *
+     * @return the array of textview
+     */
+    public ArrayList<View> getTestViews() {
+        return arrayList;
+    }
+
+    /**
+     * Gets text color
+     *
+     * @return the text color
+     */
+    public int getTextColor() {
+        return textColor;
+    }
+
+    /**
+     * Sets text color
+     *
+     * @param textColor the text color to set
+     */
+    public void setTextColor(int textColor) {
+        this.textColor = textColor;
+    }
+
+    /**
+     * Gets text size
+     *
+     * @return the text size
+     */
+    public int getTextSize() {
+        return textSize;
+    }
+
+    /**
+     * Sets text size
+     *
+     * @param textSize the text size to set
+     */
+    public void setTextSize(int textSize) {
+        this.textSize = textSize;
+    }
+
+    /**
+     * Gets resource Id for items views
+     *
+     * @return the item resource Id
+     */
+    public int getItemResource() {
+        return itemResourceId;
+    }
+
+    /**
+     * Sets resource Id for items views
+     *
+     * @param itemResourceId the resource Id to set
+     */
+    public void setItemResource(int itemResourceId) {
+        this.itemResourceId = itemResourceId;
+    }
+
+    /**
+     * Gets resource Id for text view in item layout
+     *
+     * @return the item text resource Id
+     */
+    public int getItemTextResource() {
+        return itemTextResourceId;
+    }
+
+    /**
+     * Sets resource Id for text view in item layout
+     *
+     * @param itemTextResourceId the item text resource Id to set
+     */
+    public void setItemTextResource(int itemTextResourceId) {
+        this.itemTextResourceId = itemTextResourceId;
+    }
+
+    /**
+     * Gets resource Id for empty items views
+     *
+     * @return the empty item resource Id
+     */
+    public int getEmptyItemResource() {
+        return emptyItemResourceId;
+    }
+
+    /**
+     * Sets resource Id for empty items views
+     *
+     * @param emptyItemResourceId the empty item resource Id to set
+     */
+    public void setEmptyItemResource(int emptyItemResourceId) {
+        this.emptyItemResourceId = emptyItemResourceId;
+    }
+
+    /**
+     * Returns text for specified item
+     *
+     * @param index the item index
+     * @return the text of specified items
+     */
+    protected abstract CharSequence getItemText(int index);
+
+    @Override
+    public View getItem(int index, View convertView, ViewGroup parent) {
+        if (index >= 0 && index < getItemsCount()) {
+            if (convertView == null) {
+                convertView = getView(itemResourceId, parent);
+            }
+            TextView textView = getTextView(convertView, itemTextResourceId);
+            if (!arrayList.contains(textView)) {
+                arrayList.add(textView);
+            }
+            if (textView != null) {
+                CharSequence text = getItemText(index);
+                if (text == null) {
+                    text = "";
+                }
+                textView.setText(text);
+
+                if (index == currentIndex) {
+                    textView.setTextSize(maxSize);
+                } else {
+                    textView.setTextSize(minSize);
+                }
+
+                if (itemResourceId == TEXT_VIEW_ITEM_RESOURCE) {
+                    configureTextView(textView);
+                }
+            }
+            return convertView;
+        }
+        return null;
+    }
+
+    @Override
+    public View getEmptyItem(View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = getView(emptyItemResourceId, parent);
+        }
+        if (emptyItemResourceId == TEXT_VIEW_ITEM_RESOURCE && convertView instanceof TextView) {
+            configureTextView((TextView) convertView);
+        }
+
+        return convertView;
+    }
+
+    /**
+     * Configures text view. Is called for the TEXT_VIEW_ITEM_RESOURCE views.
+     *
+     * @param view the text view to be configured
+     */
+    protected void configureTextView(TextView view) {
+        view.setTextColor(textColor);
+        view.setGravity(Gravity.CENTER);
+        view.setTextSize(textSize);
+        view.setLines(1);
+        view.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
+    }
+
+    /**
+     * Loads a text view from view
+     *
+     * @param view         the text view or layout containing it
+     * @param textResource the text resource Id in layout
+     * @return the loaded text view
+     */
+    private TextView getTextView(View view, int textResource) {
+        TextView text = null;
+        try {
+            if (textResource == NO_RESOURCE && view instanceof TextView) {
+                text = (TextView) view;
+            } else if (textResource != NO_RESOURCE) {
+                text = (TextView) view.findViewById(textResource);
+            }
+        } catch (ClassCastException e) {
+            Log.e("AbstractWheelAdapter", "You must supply a resource ID for a TextView");
+            throw new IllegalStateException("AbstractWheelAdapter requires the resource ID to be a TextView", e);
+        }
+
+        return text;
+    }
+
+    /**
+     * Loads view from resources
+     *
+     * @param resource the resource Id
+     * @return the loaded view or null if resource is not set
+     */
+    private View getView(int resource, ViewGroup parent) {
+        switch (resource) {
+            case NO_RESOURCE:
+                return null;
+            case TEXT_VIEW_ITEM_RESOURCE:
+                return new TextView(context);
+            default:
+                return inflater.inflate(resource, parent, false);
+        }
+    }
+}

+ 92 - 0
datelib/src/main/java/com/benyanyi/datelib/wheelview/ItemsRange.java

@@ -0,0 +1,92 @@
+/*
+ *  Android Wheel Control.
+ *  https://code.google.com/p/android-wheel/
+ *
+ *  Copyright 2011 Yuri Kanivets
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.benyanyi.datelib.wheelview;
+
+/**
+ * Range for visible items.
+ *
+ * @author myLove
+ */
+public class ItemsRange {
+    /**
+     * First item number
+     */
+    private int first;
+
+    /**
+     * Items count
+     */
+    private int count;
+
+    /**
+     * Default constructor. Creates an empty range
+     */
+    public ItemsRange() {
+        this(0, 0);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param first the number of first item
+     * @param count the count of items
+     */
+    public ItemsRange(int first, int count) {
+        this.first = first;
+        this.count = count;
+    }
+
+    /**
+     * Gets number of  first item
+     *
+     * @return the number of the first item
+     */
+    public int getFirst() {
+        return first;
+    }
+
+    /**
+     * Gets number of last item
+     *
+     * @return the number of last item
+     */
+    public int getLast() {
+        return getFirst() + getCount() - 1;
+    }
+
+    /**
+     * Get items count
+     *
+     * @return the count of items
+     */
+    public int getCount() {
+        return count;
+    }
+
+    /**
+     * Tests whether item is contained by range
+     *
+     * @param index the item number
+     * @return true if item is contained
+     */
+    public boolean contains(int index) {
+        return index >= getFirst() && index <= getLast();
+    }
+}

+ 1 - 1
datelib/src/main/java/com/yanyi/datelib/wheelview/OnWheelChangedListener.java → datelib/src/main/java/com/benyanyi/datelib/wheelview/OnWheelChangedListener.java

@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package com.yanyi.datelib.wheelview;
+package com.benyanyi.datelib.wheelview;
 
 /**
  * Wheel changed listener interface.

+ 1 - 1
datelib/src/main/java/com/yanyi/datelib/wheelview/OnWheelClickedListener.java → datelib/src/main/java/com/benyanyi/datelib/wheelview/OnWheelClickedListener.java

@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package com.yanyi.datelib.wheelview;
+package com.benyanyi.datelib.wheelview;
 
 /**
  * Wheel clicked listener interface.

+ 1 - 1
datelib/src/main/java/com/yanyi/datelib/wheelview/OnWheelScrollListener.java → datelib/src/main/java/com/benyanyi/datelib/wheelview/OnWheelScrollListener.java

@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package com.yanyi.datelib.wheelview;
+package com.benyanyi.datelib.wheelview;
 
 /**
  * Wheel scrolled listener interface.

+ 169 - 0
datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelRecycle.java

@@ -0,0 +1,169 @@
+/*
+ *  Android Wheel Control.
+ *  https://code.google.com/p/android-wheel/
+ *
+ *  Copyright 2011 Yuri Kanivets
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.benyanyi.datelib.wheelview;
+
+import android.view.View;
+import android.widget.LinearLayout;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Recycle stores wheel items to reuse.
+ *
+ * @author myLove
+ */
+public class WheelRecycle {
+    /**
+     * Cached items
+     */
+    private List<View> items;
+
+    /**
+     * Cached empty items
+     */
+    private List<View> emptyItems;
+
+    /**
+     * Wheel view
+     */
+    private WheelView wheel;
+
+    /**
+     * Constructor
+     *
+     * @param wheel the wheel view
+     */
+    public WheelRecycle(WheelView wheel) {
+        this.wheel = wheel;
+    }
+
+    /**
+     * Recycles items from specified layout.
+     * There are saved only items not included to specified range.
+     * All the cached items are removed from original layout.
+     *
+     * @param layout    the layout containing items to be cached
+     * @param firstItem the number of first item in layout
+     * @param range     the range of current wheel items
+     * @return the new value of first item number
+     */
+    public int recycleItems(LinearLayout layout, int firstItem, ItemsRange range) {
+        int index = firstItem;
+        for (int i = 0; i < layout.getChildCount(); ) {
+            if (!range.contains(index)) {
+                recycleView(layout.getChildAt(i), index);
+                layout.removeViewAt(i);
+                // first item
+                if (i == 0) {
+                    firstItem++;
+                }
+            } else {
+                // go to next item
+                i++;
+            }
+            index++;
+        }
+        return firstItem;
+    }
+
+    /**
+     * Gets item view
+     *
+     * @return the cached view
+     */
+    public View getItem() {
+        return getCachedView(items);
+    }
+
+    /**
+     * Gets empty item view
+     *
+     * @return the cached empty view
+     */
+    public View getEmptyItem() {
+        return getCachedView(emptyItems);
+    }
+
+    /**
+     * Clears all views
+     */
+    public void clearAll() {
+        if (items != null) {
+            items.clear();
+        }
+        if (emptyItems != null) {
+            emptyItems.clear();
+        }
+    }
+
+    /**
+     * Adds view to specified cache. Creates a cache list if it is null.
+     *
+     * @param view  the view to be cached
+     * @param cache the cache list
+     * @return the cache list
+     */
+    private List<View> addView(View view, List<View> cache) {
+        if (cache == null) {
+            cache = new LinkedList<View>();
+        }
+
+        cache.add(view);
+        return cache;
+    }
+
+    /**
+     * Adds view to cache. Determines view type (item view or empty one) by index.
+     *
+     * @param view  the view to be cached
+     * @param index the index of view
+     */
+    private void recycleView(View view, int index) {
+        int count = wheel.getViewAdapter().getItemsCount();
+        boolean boo = (index < 0 || index >= count) && !wheel.isCyclic();
+        if (boo) {
+            // empty view
+            emptyItems = addView(view, emptyItems);
+        } else {
+            while (index < 0) {
+                index = count + index;
+            }
+            index %= count;
+            items = addView(view, items);
+        }
+    }
+
+    /**
+     * Gets view from specified cache.
+     *
+     * @param cache the cache
+     * @return the first view from cache.
+     */
+    private View getCachedView(List<View> cache) {
+        if (cache != null && cache.size() > 0) {
+            View view = cache.get(0);
+            cache.remove(0);
+            return view;
+        }
+        return null;
+    }
+
+}

+ 72 - 50
datelib/src/main/java/com/yanyi/datelib/wheelview/WheelScroller.java → datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelScroller.java

@@ -1,7 +1,7 @@
 /*
  *  Android Wheel Control.
  *  https://code.google.com/p/android-wheel/
- *  
+ *
  *  Copyright 2011 Yuri Kanivets
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,7 @@
  *  limitations under the License.
  */
 
-package com.yanyi.datelib.wheelview;
+package com.benyanyi.datelib.wheelview;
 
 import android.content.Context;
 import android.os.Handler;
@@ -30,6 +30,7 @@ import android.widget.Scroller;
 
 /**
  * Scroller class handles scrolling events and updates the
+ *
  * @author myLove
  */
 public class WheelScroller {
@@ -39,6 +40,7 @@ public class WheelScroller {
     public interface ScrollingListener {
         /**
          * Scrolling callback called when scrolling is performed.
+         *
          * @param distance the distance to scroll
          */
         void onScroll(int distance);
@@ -47,31 +49,35 @@ public class WheelScroller {
          * Starting callback called when scrolling is started
          */
         void onStarted();
-        
+
         /**
          * Finishing callback called after justifying
          */
         void onFinished();
-        
+
         /**
          * Justifying callback called to justify a view when scrolling is ended
          */
         void onJustify();
     }
-    
-    /** Scrolling duration */
+
+    /**
+     * Scrolling duration
+     */
     private static final int SCROLLING_DURATION = 400;
 
-    /** Minimum delta for scrolling */
+    /**
+     * Minimum delta for scrolling
+     */
     public static final int MIN_DELTA_FOR_SCROLLING = 1;
 
-    // Listener
     private ScrollingListener listener;
-    
-    // Context
+
     private Context context;
-    
-    // Scrolling
+
+    /**
+     * Scrolling
+     */
     private GestureDetector gestureDetector;
     private Scroller scroller;
     private int lastScrollY;
@@ -80,53 +86,80 @@ public class WheelScroller {
 
     /**
      * Constructor
-     * @param context the current context
+     *
+     * @param context  the current context
      * @param listener the scrolling listener
      */
     public WheelScroller(Context context, ScrollingListener listener) {
+        /**
+         * gesture listener
+         */
+        // Do scrolling in onTouchEvent() since onScroll() are not call immediately
+        //  when user touch and move the wheel
+        SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() {
+            @Override
+            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+                // Do scrolling in onTouchEvent() since onScroll() are not call immediately
+                //  when user touch and move the wheel
+                return true;
+            }
+
+            @Override
+            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+                lastScrollY = 0;
+                final int maxY = 0x7FFFFFFF;
+                final int minY = -maxY;
+                scroller.fling(0, lastScrollY, 0, (int) -velocityY, 0, 0, minY, maxY);
+                setNextMessage(MESSAGE_SCROLL);
+                return true;
+            }
+        };
         gestureDetector = new GestureDetector(context, gestureListener);
         gestureDetector.setIsLongpressEnabled(false);
-        
+
         scroller = new Scroller(context);
 
         this.listener = listener;
         this.context = context;
     }
-    
+
     /**
      * Set the the specified scrolling interpolator
+     *
      * @param interpolator the interpolator
      */
     public void setInterpolator(Interpolator interpolator) {
         scroller.forceFinished(true);
         scroller = new Scroller(context, interpolator);
     }
-    
+
     /**
      * Scroll the wheel
+     *
      * @param distance the scrolling distance
-     * @param time the scrolling duration
+     * @param time     the scrolling duration
      */
     public void scroll(int distance, int time) {
         scroller.forceFinished(true);
 
         lastScrollY = 0;
-        
+
         scroller.startScroll(0, 0, 0, distance, time != 0 ? time : SCROLLING_DURATION);
         setNextMessage(MESSAGE_SCROLL);
-        
+
         startScrolling();
     }
-   
+
     /**
      * Stops scrolling
      */
     public void stopScrolling() {
         scroller.forceFinished(true);
     }
-    
+
     /**
-     * Handles Touch event 
+     * Handles Touch event
+     *
      * @param event the motion event
      * @return
      */
@@ -137,50 +170,36 @@ public class WheelScroller {
                 scroller.forceFinished(true);
                 clearMessages();
                 break;
-    
+
             case MotionEvent.ACTION_MOVE:
                 // perform scrolling
-                int distanceY = (int)(event.getY() - lastTouchedY);
+                int distanceY = (int) (event.getY() - lastTouchedY);
                 if (distanceY != 0) {
                     startScrolling();
                     listener.onScroll(distanceY);
                     lastTouchedY = event.getY();
                 }
                 break;
+            default:
+                break;
         }
-        
+
         if (!gestureDetector.onTouchEvent(event) && event.getAction() == MotionEvent.ACTION_UP) {
             justify();
         }
 
         return true;
     }
-    
-    // gesture listener
-    private SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() {
-        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-            // Do scrolling in onTouchEvent() since onScroll() are not call immediately
-            //  when user touch and move the wheel
-            return true;
-        }
-        
-        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-            lastScrollY = 0;
-            final int maxY = 0x7FFFFFFF;
-            final int minY = -maxY;
-            scroller.fling(0, lastScrollY, 0, (int) -velocityY, 0, 0, minY, maxY);
-            setNextMessage(MESSAGE_SCROLL);
-            return true;
-        }
-    };
 
-    // Messages
+    /**
+     * Messages
+     */
     private final int MESSAGE_SCROLL = 0;
     private final int MESSAGE_JUSTIFY = 1;
-    
+
     /**
      * Set next message to queue. Clears queue before.
-     * 
+     *
      * @param message the message to set
      */
     private void setNextMessage(int message) {
@@ -195,9 +214,12 @@ public class WheelScroller {
         animationHandler.removeMessages(MESSAGE_SCROLL);
         animationHandler.removeMessages(MESSAGE_JUSTIFY);
     }
-    
-    // animation handler
+
+    /**
+     * animation handler
+     */
     private Handler animationHandler = new Handler() {
+        @Override
         public void handleMessage(Message msg) {
             scroller.computeScrollOffset();
             int currY = scroller.getCurrY();
@@ -206,7 +228,7 @@ public class WheelScroller {
             if (delta != 0) {
                 listener.onScroll(delta);
             }
-            
+
             // scrolling is not finished when it comes to final Y
             // so, finish it manually 
             if (Math.abs(currY - scroller.getFinalY()) < MIN_DELTA_FOR_SCROLLING) {
@@ -222,7 +244,7 @@ public class WheelScroller {
             }
         }
     };
-    
+
     /**
      * Justifies wheel
      */

+ 1021 - 0
datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelView.java

@@ -0,0 +1,1021 @@
+/*
+ *  Android Wheel Control.
+ *  https://code.google.com/p/android-wheel/
+ *
+ *  Copyright 2011 Yuri Kanivets
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.benyanyi.datelib.wheelview;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.GradientDrawable.Orientation;
+import android.support.v4.content.ContextCompat;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.animation.Interpolator;
+import android.widget.LinearLayout;
+
+import com.yanyi.datelib.R;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Numeric wheel view.
+ *
+ * @author myLove
+ */
+public class WheelView extends View {
+
+    /**
+     * Top and bottom shadows colors
+     */
+    private int[] shadowsColors = new int[]{0xFFFFFFFF, 0x00FFFFFF, 0x00FFFFFF};
+
+    /**
+     * Top and bottom items offset (to hide that)
+     */
+    private static final int ITEM_OFFSET_PERCENT = 0;
+
+    /**
+     * Left and right padding value
+     */
+    private static final int PADDING = 10;
+
+    /**
+     * Default count of visible items
+     */
+    private static final int DEF_VISIBLE_ITEMS = 5;
+
+    /**
+     * Wheel Values
+     */
+    private int currentItem = 0;
+
+    /**
+     * Count of visible items
+     */
+    private int visibleItems = DEF_VISIBLE_ITEMS;
+
+    /**
+     * Item height
+     */
+    private int itemHeight = 0;
+
+    /**
+     * Center Line
+     */
+    private Drawable centerDrawable;
+
+    /**
+     * Wheel drawables
+     */
+    private int wheelBackground = R.drawable.wheel_bg;
+    private int wheelForeground = R.drawable.wheel_val;
+
+    /**
+     * Shadows drawables
+     */
+    private GradientDrawable topShadow;
+    private GradientDrawable bottomShadow;
+
+    /**
+     * Draw Shadows
+     */
+    private boolean drawShadows = true;
+
+    /**
+     * Scrolling
+     */
+    private WheelScroller scroller;
+    private boolean isScrollingPerformed;
+    private int scrollingOffset;
+
+    /**
+     * Cyclic
+     */
+    boolean isCyclic = false;
+
+    /**
+     * Items layout
+     */
+    private LinearLayout itemsLayout;
+
+    /**
+     * The number of first item in layout
+     */
+    private int firstItem;
+
+    /**
+     * View adapter
+     */
+    private WheelViewAdapter viewAdapter;
+
+    /**
+     * Recycle
+     */
+    private WheelRecycle recycle = new WheelRecycle(this);
+
+    /**
+     * Listeners
+     */
+    private List<OnWheelChangedListener> changingListeners = new LinkedList<OnWheelChangedListener>();
+    private List<OnWheelScrollListener> scrollingListeners = new LinkedList<OnWheelScrollListener>();
+    private List<OnWheelClickedListener> clickingListeners = new LinkedList<OnWheelClickedListener>();
+
+    String label = "";
+
+    /**
+     * Constructor
+     */
+    public WheelView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        initData(context);
+    }
+
+    /**
+     * Constructor
+     */
+    public WheelView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initData(context);
+    }
+
+    /**
+     * Constructor
+     */
+    public WheelView(Context context) {
+        super(context);
+        initData(context);
+    }
+
+    /**
+     * Initializes class data
+     *
+     * @param context the context
+     */
+    private void initData(Context context) {
+        scroller = new WheelScroller(getContext(), scrollingListener);
+    }
+
+    /**
+     * Scrolling listener
+     */
+    WheelScroller.ScrollingListener scrollingListener = new WheelScroller.ScrollingListener() {
+        @Override
+        public void onStarted() {
+            isScrollingPerformed = true;
+            notifyScrollingListenersAboutStart();
+        }
+
+        @Override
+        public void onScroll(int distance) {
+            doScroll(distance);
+
+            int height = getHeight();
+            if (scrollingOffset > height) {
+                scrollingOffset = height;
+                scroller.stopScrolling();
+            } else if (scrollingOffset < -height) {
+                scrollingOffset = -height;
+                scroller.stopScrolling();
+            }
+        }
+
+        @Override
+        public void onFinished() {
+            if (isScrollingPerformed) {
+                notifyScrollingListenersAboutEnd();
+                isScrollingPerformed = false;
+            }
+
+            scrollingOffset = 0;
+            invalidate();
+        }
+
+        @Override
+        public void onJustify() {
+            if (Math.abs(scrollingOffset) > WheelScroller.MIN_DELTA_FOR_SCROLLING) {
+                scroller.scroll(scrollingOffset, 0);
+            }
+        }
+    };
+
+    /**
+     * Set the the specified scrolling interpolator
+     *
+     * @param interpolator the interpolator
+     */
+    public void setInterpolator(Interpolator interpolator) {
+        scroller.setInterpolator(interpolator);
+    }
+
+    /**
+     * Gets count of visible items
+     *
+     * @return the count of visible items
+     */
+    public int getVisibleItems() {
+        return visibleItems;
+    }
+
+    /**
+     * Sets the desired count of visible items.
+     * Actual amount of visible items depends on wheel layout parameters.
+     * To apply changes and rebuild view call measure().
+     *
+     * @param count the desired count for visible items
+     */
+    public void setVisibleItems(int count) {
+        visibleItems = count;
+    }
+
+    /**
+     * Gets view adapter
+     *
+     * @return the view adapter
+     */
+    public WheelViewAdapter getViewAdapter() {
+        return viewAdapter;
+    }
+
+    /**
+     * Adapter listener
+     */
+    private DataSetObserver dataObserver = new DataSetObserver() {
+        @Override
+        public void onChanged() {
+            invalidateWheel(false);
+        }
+
+        @Override
+        public void onInvalidated() {
+            invalidateWheel(true);
+        }
+    };
+
+    /**
+     * Sets view adapter. Usually new adapters contain different views, so
+     * it needs to rebuild view by calling measure().
+     *
+     * @param viewAdapter the view adapter
+     */
+    public void setViewAdapter(WheelViewAdapter viewAdapter) {
+        if (this.viewAdapter != null) {
+            this.viewAdapter.unregisterDataSetObserver(dataObserver);
+        }
+        this.viewAdapter = viewAdapter;
+        if (this.viewAdapter != null) {
+            this.viewAdapter.registerDataSetObserver(dataObserver);
+        }
+
+        invalidateWheel(true);
+    }
+
+    /**
+     * Adds wheel changing listener
+     *
+     * @param listener the listener
+     */
+    public void addChangingListener(OnWheelChangedListener listener) {
+        changingListeners.add(listener);
+    }
+
+    /**
+     * Removes wheel changing listener
+     *
+     * @param listener the listener
+     */
+    public void removeChangingListener(OnWheelChangedListener listener) {
+        changingListeners.remove(listener);
+    }
+
+    /**
+     * Notifies changing listeners
+     *
+     * @param oldValue the old wheel value
+     * @param newValue the new wheel value
+     */
+    protected void notifyChangingListeners(int oldValue, int newValue) {
+        for (OnWheelChangedListener listener : changingListeners) {
+            listener.onChanged(this, oldValue, newValue);
+        }
+    }
+
+    /**
+     * Adds wheel scrolling listener
+     *
+     * @param listener the listener
+     */
+    public void addScrollingListener(OnWheelScrollListener listener) {
+        scrollingListeners.add(listener);
+    }
+
+    /**
+     * Removes wheel scrolling listener
+     *
+     * @param listener the listener
+     */
+    public void removeScrollingListener(OnWheelScrollListener listener) {
+        scrollingListeners.remove(listener);
+    }
+
+    /**
+     * Notifies listeners about starting scrolling
+     */
+    protected void notifyScrollingListenersAboutStart() {
+        for (OnWheelScrollListener listener : scrollingListeners) {
+            listener.onScrollingStarted(this);
+        }
+    }
+
+    /**
+     * Notifies listeners about ending scrolling
+     */
+    protected void notifyScrollingListenersAboutEnd() {
+        for (OnWheelScrollListener listener : scrollingListeners) {
+            listener.onScrollingFinished(this);
+        }
+    }
+
+    /**
+     * Adds wheel clicking listener
+     *
+     * @param listener the listener
+     */
+    public void addClickingListener(OnWheelClickedListener listener) {
+        clickingListeners.add(listener);
+    }
+
+    /**
+     * Removes wheel clicking listener
+     *
+     * @param listener the listener
+     */
+    public void removeClickingListener(OnWheelClickedListener listener) {
+        clickingListeners.remove(listener);
+    }
+
+    /**
+     * Notifies listeners about clicking
+     */
+    protected void notifyClickListenersAboutClick(int item) {
+        for (OnWheelClickedListener listener : clickingListeners) {
+            listener.onItemClicked(this, item);
+        }
+    }
+
+    /**
+     * Gets current value
+     *
+     * @return the current value
+     */
+    public int getCurrentItem() {
+        return currentItem;
+    }
+
+    /**
+     * Sets the current item. Does nothing when index is wrong.
+     *
+     * @param index    the item index
+     * @param animated the animation flag
+     */
+    public void setCurrentItem(int index, boolean animated) {
+        if (viewAdapter == null || viewAdapter.getItemsCount() == 0) {
+            return; // throw?
+        }
+
+        int itemCount = viewAdapter.getItemsCount();
+        if (index < 0 || index >= itemCount) {
+            if (isCyclic) {
+                while (index < 0) {
+                    index += itemCount;
+                }
+                index %= itemCount;
+            } else {
+                return; // throw?
+            }
+        }
+        if (index != currentItem) {
+            if (animated) {
+                int itemsToScroll = index - currentItem;
+                if (isCyclic) {
+                    int scroll = itemCount + Math.min(index, currentItem) - Math.max(index, currentItem);
+                    if (scroll < Math.abs(itemsToScroll)) {
+                        itemsToScroll = itemsToScroll < 0 ? scroll : -scroll;
+                    }
+                }
+                scroll(itemsToScroll, 0);
+            } else {
+                scrollingOffset = 0;
+
+                int old = currentItem;
+                currentItem = index;
+
+                notifyChangingListeners(old, currentItem);
+
+                invalidate();
+            }
+        }
+    }
+
+    /**
+     * Sets the current item w/o animation. Does nothing when index is wrong.
+     *
+     * @param index the item index
+     */
+    public void setCurrentItem(int index) {
+        setCurrentItem(index, false);
+    }
+
+    /**
+     * Tests if wheel is cyclic. That means before the 1st item there is shown the last one
+     *
+     * @return true if wheel is cyclic
+     */
+    public boolean isCyclic() {
+        return isCyclic;
+    }
+
+    /**
+     * Set wheel cyclic flag
+     *
+     * @param isCyclic the flag to set
+     */
+    public void setCyclic(boolean isCyclic) {
+        this.isCyclic = isCyclic;
+        invalidateWheel(false);
+    }
+
+    /**
+     * Determine whether shadows are drawn
+     *
+     * @return true is shadows are drawn
+     */
+    public boolean drawShadows() {
+        return drawShadows;
+    }
+
+    /**
+     * Set whether shadows should be drawn
+     *
+     * @param drawShadows flag as true or false
+     */
+    public void setDrawShadows(boolean drawShadows) {
+        this.drawShadows = drawShadows;
+    }
+
+    /**
+     * Set the shadow gradient color
+     *
+     * @param start
+     * @param middle
+     * @param end
+     */
+    public void setShadowColor(int start, int middle, int end) {
+        shadowsColors = new int[]{start, middle, end};
+    }
+
+    /**
+     * Sets the drawable for the wheel background
+     *
+     * @param resource
+     */
+    public void setWheelBackground(int resource) {
+        wheelBackground = resource;
+        setBackgroundResource(wheelBackground);
+    }
+
+    /**
+     * Sets the drawable for the wheel foreground
+     *
+     * @param resource
+     */
+    public void setWheelForeground(int resource) {
+        wheelForeground = resource;
+        centerDrawable = ContextCompat.getDrawable(getContext(), wheelForeground);
+    }
+
+    /**
+     * Invalidates wheel
+     *
+     * @param clearCaches if true then cached views will be clear
+     */
+    public void invalidateWheel(boolean clearCaches) {
+        if (clearCaches) {
+            recycle.clearAll();
+            if (itemsLayout != null) {
+                itemsLayout.removeAllViews();
+            }
+            scrollingOffset = 0;
+        } else if (itemsLayout != null) {
+            // cache all items
+            recycle.recycleItems(itemsLayout, firstItem, new ItemsRange());
+        }
+
+        invalidate();
+    }
+
+    /**
+     * Initializes resources
+     */
+    private void initResourcesIfNecessary() {
+        if (centerDrawable == null) {
+            centerDrawable = ContextCompat.getDrawable(getContext(), wheelForeground);
+        }
+
+        if (topShadow == null) {
+            topShadow = new GradientDrawable(Orientation.TOP_BOTTOM, shadowsColors);
+        }
+
+        if (bottomShadow == null) {
+            bottomShadow = new GradientDrawable(Orientation.BOTTOM_TOP, shadowsColors);
+        }
+
+        setBackgroundResource(wheelBackground);
+    }
+
+    /**
+     * Calculates desired height for layout
+     *
+     * @param layout the source layout
+     * @return the desired layout height
+     */
+    private int getDesiredHeight(LinearLayout layout) {
+        if (layout != null && layout.getChildAt(0) != null) {
+            itemHeight = layout.getChildAt(0).getMeasuredHeight();
+        }
+
+        int desired = itemHeight * visibleItems - itemHeight * ITEM_OFFSET_PERCENT / 50;
+
+        return Math.max(desired, getSuggestedMinimumHeight());
+    }
+
+    /**
+     * Returns height of wheel item
+     *
+     * @return the item height
+     */
+    private int getItemHeight() {
+        if (itemHeight != 0) {
+            return itemHeight;
+        }
+
+        if (itemsLayout != null && itemsLayout.getChildAt(0) != null) {
+            itemHeight = itemsLayout.getChildAt(0).getHeight();
+            return itemHeight;
+        }
+
+        return getHeight() / visibleItems;
+    }
+
+    /**
+     * Calculates control width and creates text layouts
+     *
+     * @param widthSize the input layout width
+     * @param mode      the layout mode
+     * @return the calculated control width
+     */
+    private int calculateLayoutWidth(int widthSize, int mode) {
+        initResourcesIfNecessary();
+
+        // TODO: make it static
+        itemsLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+        itemsLayout.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.UNSPECIFIED),
+                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+        int width = itemsLayout.getMeasuredWidth();
+
+        if (mode == MeasureSpec.EXACTLY) {
+            width = widthSize;
+        } else {
+            width += 2 * PADDING;
+
+            // Check against our minimum width
+            width = Math.max(width, getSuggestedMinimumWidth());
+
+            if (mode == MeasureSpec.AT_MOST && widthSize < width) {
+                width = widthSize;
+            }
+        }
+
+        itemsLayout.measure(MeasureSpec.makeMeasureSpec(width - 2 * PADDING, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+
+        return width;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+        buildViewForMeasuring();
+
+        int width = calculateLayoutWidth(widthSize, widthMode);
+
+        int height;
+        if (heightMode == MeasureSpec.EXACTLY) {
+            height = heightSize;
+        } else {
+            height = getDesiredHeight(itemsLayout);
+
+            if (heightMode == MeasureSpec.AT_MOST) {
+                height = Math.min(height, heightSize);
+            }
+        }
+
+        setMeasuredDimension(width, height);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        layout(r - l, b - t);
+    }
+
+    /**
+     * Sets layouts width and height
+     *
+     * @param width  the layout width
+     * @param height the layout height
+     */
+    private void layout(int width, int height) {
+        int itemsWidth = width - 2 * PADDING;
+
+        itemsLayout.layout(0, 0, itemsWidth, height);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        if (viewAdapter != null && viewAdapter.getItemsCount() > 0) {
+            updateView();
+
+            drawItems(canvas);
+            drawCenterRect(canvas);
+        }
+
+        if (drawShadows) {
+            drawShadows(canvas);
+        }
+    }
+
+    /**
+     * Draws shadows on top and bottom of control
+     *
+     * @param canvas the canvas for drawing
+     */
+    private void drawShadows(Canvas canvas) {
+		/*/ Modified by wulianghuan 2014-11-25
+		int height = (int)(1.5 * getItemHeight());
+		//*/
+        int height = (int) (3 * getItemHeight());
+        topShadow.setBounds(0, 0, getWidth(), getHeight());
+        topShadow.draw(canvas);
+
+        bottomShadow.setBounds(0, 0, getWidth(), getHeight());
+        bottomShadow.draw(canvas);
+    }
+
+    /**
+     * Draws items
+     *
+     * @param canvas the canvas for drawing
+     */
+    private void drawItems(Canvas canvas) {
+        canvas.save();
+
+        int top = (currentItem - firstItem) * getItemHeight() + (getItemHeight() - getHeight()) / 2;
+        canvas.translate(PADDING, -top + scrollingOffset);
+
+        itemsLayout.draw(canvas);
+
+        canvas.restore();
+    }
+
+    /**
+     * Draws rect for current value
+     *
+     * @param canvas the canvas for drawing
+     */
+    private void drawCenterRect(Canvas canvas) {
+        int center = getHeight() / 2;
+        int offset = (int) (getItemHeight() / 2 * 1.2);
+        Paint paint = new Paint();
+        paint.setColor(Color.parseColor("#D0D0D0"));
+        // 设置线宽
+        paint.setStrokeWidth((float) 2);
+        // 绘制上边直线
+        canvas.drawLine(0, center - offset, getWidth(), center - offset, paint);
+        // 绘制下边直线
+        canvas.drawLine(0, center + offset, getWidth(), center + offset, paint);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (!isEnabled() || getViewAdapter() == null) {
+            return true;
+        }
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_MOVE:
+                if (getParent() != null) {
+                    getParent().requestDisallowInterceptTouchEvent(true);
+                }
+                break;
+
+            case MotionEvent.ACTION_UP:
+                if (!isScrollingPerformed) {
+                    int distance = (int) event.getY() - getHeight() / 2;
+                    if (distance > 0) {
+                        distance += getItemHeight() / 2;
+                    } else {
+                        distance -= getItemHeight() / 2;
+                    }
+                    int items = distance / getItemHeight();
+                    if (items != 0 && isValidItemIndex(currentItem + items)) {
+                        notifyClickListenersAboutClick(currentItem + items);
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+
+        return scroller.onTouchEvent(event);
+    }
+
+    /**
+     * Scrolls the wheel
+     *
+     * @param delta the scrolling value
+     */
+    private void doScroll(int delta) {
+        scrollingOffset += delta;
+
+        int itemHeight = getItemHeight();
+        int count = scrollingOffset / itemHeight;
+
+        int pos = currentItem - count;
+        int itemCount = viewAdapter.getItemsCount();
+
+        int fixPos = scrollingOffset % itemHeight;
+        int num = 2;
+        if (Math.abs(fixPos) <= itemHeight / num) {
+            fixPos = 0;
+        }
+        if (isCyclic && itemCount > 0) {
+            if (fixPos > 0) {
+                pos--;
+                count++;
+            } else if (fixPos < 0) {
+                pos++;
+                count--;
+            }
+            // fix position by rotating
+            while (pos < 0) {
+                pos += itemCount;
+            }
+            pos %= itemCount;
+        } else {
+            //
+            if (pos < 0) {
+                count = currentItem;
+                pos = 0;
+            } else if (pos >= itemCount) {
+                count = currentItem - itemCount + 1;
+                pos = itemCount - 1;
+            } else if (pos > 0 && fixPos > 0) {
+                pos--;
+                count++;
+            } else if (pos < itemCount - 1 && fixPos < 0) {
+                pos++;
+                count--;
+            }
+        }
+
+        int offset = scrollingOffset;
+        if (pos != currentItem) {
+            setCurrentItem(pos, false);
+        } else {
+            invalidate();
+        }
+
+        // update offset
+        scrollingOffset = offset - count * itemHeight;
+        if (scrollingOffset > getHeight()) {
+            scrollingOffset = scrollingOffset % getHeight() + getHeight();
+        }
+    }
+
+    /**
+     * Scroll the wheel
+     *
+     * @param itemsToScroll items to scroll
+     * @param time          scrolling duration
+     */
+    public void scroll(int itemsToScroll, int time) {
+        int distance = itemsToScroll * getItemHeight() - scrollingOffset;
+        scroller.scroll(distance, time);
+    }
+
+    /**
+     * Calculates range for wheel items
+     *
+     * @return the items range
+     */
+    private ItemsRange getItemsRange() {
+        if (getItemHeight() == 0) {
+            return null;
+        }
+
+        int first = currentItem;
+        int count = 1;
+
+        while (count * getItemHeight() < getHeight()) {
+            first--;
+            count += 2; // top + bottom items
+        }
+
+        if (scrollingOffset != 0) {
+            if (scrollingOffset > 0) {
+                first--;
+            }
+            count++;
+
+            // process empty items above the first or below the second
+            int emptyItems = scrollingOffset / getItemHeight();
+            first -= emptyItems;
+            count += Math.asin(emptyItems);
+        }
+        return new ItemsRange(first, count);
+    }
+
+    /**
+     * Rebuilds wheel items if necessary. Caches all unused items.
+     *
+     * @return true if items are rebuilt
+     */
+    private boolean rebuildItems() {
+        boolean updated = false;
+        ItemsRange range = getItemsRange();
+        if (itemsLayout != null) {
+            int first = recycle.recycleItems(itemsLayout, firstItem, range);
+            updated = firstItem != first;
+            firstItem = first;
+        } else {
+            createItemsLayout();
+            updated = true;
+        }
+
+        if (!updated) {
+            updated = firstItem != range.getFirst() || itemsLayout.getChildCount() != range.getCount();
+        }
+
+        if (firstItem > range.getFirst() && firstItem <= range.getLast()) {
+            for (int i = firstItem - 1; i >= range.getFirst(); i--) {
+                if (!addViewItem(i, true)) {
+                    break;
+                }
+                firstItem = i;
+            }
+        } else {
+            firstItem = range.getFirst();
+        }
+
+        int first = firstItem;
+        for (int i = itemsLayout.getChildCount(); i < range.getCount(); i++) {
+            if (!addViewItem(firstItem + i, false) && itemsLayout.getChildCount() == 0) {
+                first++;
+            }
+        }
+        firstItem = first;
+
+        return updated;
+    }
+
+    /**
+     * Updates view. Rebuilds items and label if necessary, recalculate items sizes.
+     */
+    private void updateView() {
+        if (rebuildItems()) {
+            calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY);
+            layout(getWidth(), getHeight());
+        }
+    }
+
+    /**
+     * Creates item layouts if necessary
+     */
+    private void createItemsLayout() {
+        if (itemsLayout == null) {
+            itemsLayout = new LinearLayout(getContext());
+            itemsLayout.setOrientation(LinearLayout.VERTICAL);
+        }
+    }
+
+    /**
+     * Builds view for measuring
+     */
+    private void buildViewForMeasuring() {
+        // clear all items
+        if (itemsLayout != null) {
+            recycle.recycleItems(itemsLayout, firstItem, new ItemsRange());
+        } else {
+            createItemsLayout();
+        }
+
+        // add views
+        int addItems = visibleItems / 2;
+        for (int i = currentItem + addItems; i >= currentItem - addItems; i--) {
+            if (addViewItem(i, true)) {
+                firstItem = i;
+            }
+        }
+    }
+
+    /**
+     * Adds view for item to items layout
+     *
+     * @param index the item index
+     * @param first the flag indicates if view should be first
+     * @return true if corresponding item exists and is added
+     */
+    private boolean addViewItem(int index, boolean first) {
+        View view = getItemView(index);
+        if (view != null) {
+            if (first) {
+                itemsLayout.addView(view, 0);
+            } else {
+                itemsLayout.addView(view);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks whether intem index is valid
+     *
+     * @param index the item index
+     * @return true if item index is not out of bounds or the wheel is cyclic
+     */
+    private boolean isValidItemIndex(int index) {
+        return viewAdapter != null && viewAdapter.getItemsCount() > 0 &&
+                (isCyclic || index >= 0 && index < viewAdapter.getItemsCount());
+    }
+
+    /**
+     * Returns view for specified item
+     *
+     * @param index the item index
+     * @return item view or empty view if index is out of bounds
+     */
+    private View getItemView(int index) {
+        if (viewAdapter == null || viewAdapter.getItemsCount() == 0) {
+            return null;
+        }
+        int count = viewAdapter.getItemsCount();
+        if (!isValidItemIndex(index)) {
+            return viewAdapter.getEmptyItem(recycle.getEmptyItem(), itemsLayout);
+        } else {
+            while (index < 0) {
+                index = count + index;
+            }
+        }
+
+        index %= count;
+        return viewAdapter.getItem(index, recycle.getItem(), itemsLayout);
+    }
+
+    /**
+     * Stops scrolling
+     */
+    public void stopScrolling() {
+        scroller.stopScrolling();
+    }
+}

+ 1 - 1
datelib/src/main/java/com/yanyi/datelib/wheelview/WheelViewAdapter.java → datelib/src/main/java/com/benyanyi/datelib/wheelview/WheelViewAdapter.java

@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package com.yanyi.datelib.wheelview;
+package com.benyanyi.datelib.wheelview;
 
 import android.database.DataSetObserver;
 import android.view.View;

+ 0 - 330
datelib/src/main/java/com/yanyi/datelib/wheelview/AbstractWheelTextAdapter1.java

@@ -1,330 +0,0 @@
-/*
- *  Copyright 2011 Yuri Kanivets
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package com.yanyi.datelib.wheelview;
-
-import android.content.Context;
-import android.graphics.Typeface;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-
-/**
- * Abstract wheel adapter provides common functionality for adapters.
- * @author myLove
- */
-public abstract class AbstractWheelTextAdapter1 extends AbstractWheelAdapter {
-
-	/** Text view resource. Used as a default view for adapter. */
-	public static final int TEXT_VIEW_ITEM_RESOURCE = -1;
-
-	/** No resource constant. */
-	protected static final int NO_RESOURCE = 0;
-
-	/** Default text color */
-	public static final int DEFAULT_TEXT_COLOR = 0xFF101010;
-
-	/** Default text color */
-	public static final int LABEL_COLOR = 0xFF700070;
-
-	/** Default text size */
-	public static final int DEFAULT_TEXT_SIZE = 24;
-
-	// Text settings
-	private int textColor = DEFAULT_TEXT_COLOR;
-	private int textSize = DEFAULT_TEXT_SIZE;
-
-	// Current context
-	protected Context context;
-	// Layout inflater
-	protected LayoutInflater inflater;
-
-	// Items resources
-	protected int itemResourceId;
-	protected int itemTextResourceId;
-
-	// Empty items resources
-	protected int emptyItemResourceId;
-
-	private int currentIndex = 0;
-	private static int maxsize = 14;
-	private static int minsize = 12;
-	private ArrayList<View> arrayList = new ArrayList<View>();
-
-	/**
-	 * Constructor
-	 * 
-	 * @param context
-	 *            the current context
-	 */
-	protected AbstractWheelTextAdapter1(Context context) {
-		this(context, TEXT_VIEW_ITEM_RESOURCE);
-	}
-
-	/**
-	 * Constructor
-	 * 
-	 * @param context
-	 *            the current context
-	 * @param itemResource
-	 *            the resource ID for a layout file containing a TextView to use
-	 *            when instantiating items views
-	 */
-	protected AbstractWheelTextAdapter1(Context context, int itemResource) {
-		this(context, itemResource, NO_RESOURCE, 0, maxsize, minsize);
-	}
-
-	/**
-	 * Constructor
-	 * 
-	 * @param context
-	 *            the current context
-	 * @param itemResource
-	 *            the resource ID for a layout file containing a TextView to use
-	 *            when instantiating items views
-	 * @param itemTextResource
-	 *            the resource ID for a text view in the item layout
-	 */
-	protected AbstractWheelTextAdapter1(Context context, int itemResource, int itemTextResource, int currentIndex,
-                                        int maxsize, int minsize) {
-		this.context = context;
-		itemResourceId = itemResource;
-		itemTextResourceId = itemTextResource;
-		this.currentIndex = currentIndex;
-		this.maxsize = maxsize;
-		this.minsize = minsize;
-
-		inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-	}
-
-	/**
-	 * get the list of show textview
-	 * 
-	 * @return the array of textview
-	 */
-	public ArrayList<View> getTestViews() {
-		return arrayList;
-	}
-
-	/**
-	 * Gets text color
-	 * 
-	 * @return the text color
-	 */
-	public int getTextColor() {
-		return textColor;
-	}
-
-	/**
-	 * Sets text color
-	 * 
-	 * @param textColor
-	 *            the text color to set
-	 */
-	public void setTextColor(int textColor) {
-		this.textColor = textColor;
-	}
-
-	/**
-	 * Gets text size
-	 * 
-	 * @return the text size
-	 */
-	public int getTextSize() {
-		return textSize;
-	}
-
-	/**
-	 * Sets text size
-	 * 
-	 * @param textSize
-	 *            the text size to set
-	 */
-	public void setTextSize(int textSize) {
-		this.textSize = textSize;
-	}
-
-	/**
-	 * Gets resource Id for items views
-	 * 
-	 * @return the item resource Id
-	 */
-	public int getItemResource() {
-		return itemResourceId;
-	}
-
-	/**
-	 * Sets resource Id for items views
-	 * 
-	 * @param itemResourceId
-	 *            the resource Id to set
-	 */
-	public void setItemResource(int itemResourceId) {
-		this.itemResourceId = itemResourceId;
-	}
-
-	/**
-	 * Gets resource Id for text view in item layout
-	 * 
-	 * @return the item text resource Id
-	 */
-	public int getItemTextResource() {
-		return itemTextResourceId;
-	}
-
-	/**
-	 * Sets resource Id for text view in item layout
-	 * 
-	 * @param itemTextResourceId
-	 *            the item text resource Id to set
-	 */
-	public void setItemTextResource(int itemTextResourceId) {
-		this.itemTextResourceId = itemTextResourceId;
-	}
-
-	/**
-	 * Gets resource Id for empty items views
-	 * 
-	 * @return the empty item resource Id
-	 */
-	public int getEmptyItemResource() {
-		return emptyItemResourceId;
-	}
-
-	/**
-	 * Sets resource Id for empty items views
-	 * 
-	 * @param emptyItemResourceId
-	 *            the empty item resource Id to set
-	 */
-	public void setEmptyItemResource(int emptyItemResourceId) {
-		this.emptyItemResourceId = emptyItemResourceId;
-	}
-
-	/**
-	 * Returns text for specified item
-	 * 
-	 * @param index
-	 *            the item index
-	 * @return the text of specified items
-	 */
-	protected abstract CharSequence getItemText(int index);
-
-	@Override
-	public View getItem(int index, View convertView, ViewGroup parent) {
-		if (index >= 0 && index < getItemsCount()) {
-			if (convertView == null) {
-				convertView = getView(itemResourceId, parent);
-			}
-			TextView textView = getTextView(convertView, itemTextResourceId);
-			if (!arrayList.contains(textView)) {
-				arrayList.add(textView);
-			}
-			if (textView != null) {
-				CharSequence text = getItemText(index);
-				if (text == null) {
-					text = "";
-				}
-				textView.setText(text);
-
-				if (index == currentIndex) {
-					textView.setTextSize(maxsize);
-				} else {
-					textView.setTextSize(minsize);
-				}
-
-				if (itemResourceId == TEXT_VIEW_ITEM_RESOURCE) {
-					configureTextView(textView);
-				}
-			}
-			return convertView;
-		}
-		return null;
-	}
-
-	@Override
-	public View getEmptyItem(View convertView, ViewGroup parent) {
-		if (convertView == null) {
-			convertView = getView(emptyItemResourceId, parent);
-		}
-		if (emptyItemResourceId == TEXT_VIEW_ITEM_RESOURCE && convertView instanceof TextView) {
-			configureTextView((TextView) convertView);
-		}
-
-		return convertView;
-	}
-
-	/**
-	 * Configures text view. Is called for the TEXT_VIEW_ITEM_RESOURCE views.
-	 * 
-	 * @param view
-	 *            the text view to be configured
-	 */
-	protected void configureTextView(TextView view) {
-		view.setTextColor(textColor);
-		view.setGravity(Gravity.CENTER);
-		view.setTextSize(textSize);
-		view.setLines(1);
-		view.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
-	}
-
-	/**
-	 * Loads a text view from view
-	 * 
-	 * @param view
-	 *            the text view or layout containing it
-	 * @param textResource
-	 *            the text resource Id in layout
-	 * @return the loaded text view
-	 */
-	private TextView getTextView(View view, int textResource) {
-		TextView text = null;
-		try {
-			if (textResource == NO_RESOURCE && view instanceof TextView) {
-				text = (TextView) view;
-			} else if (textResource != NO_RESOURCE) {
-				text = (TextView) view.findViewById(textResource);
-			}
-		} catch (ClassCastException e) {
-			Log.e("AbstractWheelAdapter", "You must supply a resource ID for a TextView");
-			throw new IllegalStateException("AbstractWheelAdapter requires the resource ID to be a TextView", e);
-		}
-
-		return text;
-	}
-
-	/**
-	 * Loads view from resources
-	 * 
-	 * @param resource
-	 *            the resource Id
-	 * @return the loaded view or null if resource is not set
-	 */
-	private View getView(int resource, ViewGroup parent) {
-		switch (resource) {
-		case NO_RESOURCE:
-			return null;
-		case TEXT_VIEW_ITEM_RESOURCE:
-			return new TextView(context);
-		default:
-			return inflater.inflate(resource, parent, false);
-		}
-	}
-}

+ 0 - 82
datelib/src/main/java/com/yanyi/datelib/wheelview/ItemsRange.java

@@ -1,82 +0,0 @@
-/*
- *  Android Wheel Control.
- *  https://code.google.com/p/android-wheel/
- *  
- *  Copyright 2011 Yuri Kanivets
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package com.yanyi.datelib.wheelview;
-
-/**
- * Range for visible items.
- * @author myLove
- */
-public class ItemsRange {
-	// First item number
-	private int first;
-	
-	// Items count
-	private int count;
-
-	/**
-	 * Default constructor. Creates an empty range
-	 */
-    public ItemsRange() {
-        this(0, 0);
-    }
-    
-	/**
-	 * Constructor
-	 * @param first the number of first item
-	 * @param count the count of items
-	 */
-	public ItemsRange(int first, int count) {
-		this.first = first;
-		this.count = count;
-	}
-	
-	/**
-	 * Gets number of  first item
-	 * @return the number of the first item
-	 */
-	public int getFirst() {
-		return first;
-	}
-	
-	/**
-	 * Gets number of last item
-	 * @return the number of last item
-	 */
-	public int getLast() {
-		return getFirst() + getCount() - 1;
-	}
-	
-	/**
-	 * Get items count
-	 * @return the count of items
-	 */
-	public int getCount() {
-		return count;
-	}
-	
-	/**
-	 * Tests whether item is contained by range
-	 * @param index the item number
-	 * @return true if item is contained
-	 */
-	public boolean contains(int index) {
-		return index >= getFirst() && index <= getLast();
-	}
-}

+ 0 - 154
datelib/src/main/java/com/yanyi/datelib/wheelview/WheelRecycle.java

@@ -1,154 +0,0 @@
-/*
- *  Android Wheel Control.
- *  https://code.google.com/p/android-wheel/
- *  
- *  Copyright 2011 Yuri Kanivets
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package com.yanyi.datelib.wheelview;
-
-import android.view.View;
-import android.widget.LinearLayout;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Recycle stores wheel items to reuse.
- * @author myLove
- */
-public class WheelRecycle {
-	// Cached items
-	private List<View> items;
-	
-	// Cached empty items
-	private List<View> emptyItems;
-	
-	// Wheel view
-	private WheelView wheel;
-	
-	/**
-	 * Constructor
-	 * @param wheel the wheel view
-	 */
-	public WheelRecycle(WheelView wheel) {
-		this.wheel = wheel;
-	}
-
-	/**
-	 * Recycles items from specified layout.
-	 * There are saved only items not included to specified range.
-	 * All the cached items are removed from original layout.
-	 * 
-	 * @param layout the layout containing items to be cached
-	 * @param firstItem the number of first item in layout
-	 * @param range the range of current wheel items 
-	 * @return the new value of first item number
-	 */
-	public int recycleItems(LinearLayout layout, int firstItem, ItemsRange range) {
-		int index = firstItem;
-		for (int i = 0; i < layout.getChildCount();) {
-			if (!range.contains(index)) {
-				recycleView(layout.getChildAt(i), index);
-				layout.removeViewAt(i);
-				if (i == 0) { // first item
-					firstItem++;
-				}
-			} else {
-				i++; // go to next item
-			}
-			index++;
-		}
-		return firstItem;
-	}
-	
-	/**
-	 * Gets item view
-	 * @return the cached view
-	 */
-	public View getItem() {
-		return getCachedView(items);
-	}
-
-	/**
-	 * Gets empty item view
-	 * @return the cached empty view
-	 */
-	public View getEmptyItem() {
-		return getCachedView(emptyItems);
-	}
-	
-	/**
-	 * Clears all views 
-	 */
-	public void clearAll() {
-		if (items != null) {
-			items.clear();
-		}
-		if (emptyItems != null) {
-			emptyItems.clear();
-		}
-	}
-
-	/**
-	 * Adds view to specified cache. Creates a cache list if it is null.
-	 * @param view the view to be cached
-	 * @param cache the cache list
-	 * @return the cache list
-	 */
-	private List<View> addView(View view, List<View> cache) {
-		if (cache == null) {
-			cache = new LinkedList<View>();
-		}
-		
-		cache.add(view);
-		return cache;
-	}
-
-	/**
-	 * Adds view to cache. Determines view type (item view or empty one) by index.
-	 * @param view the view to be cached
-	 * @param index the index of view
-	 */
-	private void recycleView(View view, int index) {
-		int count = wheel.getViewAdapter().getItemsCount();
-
-		if ((index < 0 || index >= count) && !wheel.isCyclic()) {
-			// empty view
-			emptyItems = addView(view, emptyItems);
-		} else {
-			while (index < 0) {
-				index = count + index;
-			}
-			index %= count;
-			items = addView(view, items);
-		}
-	}
-	
-	/**
-	 * Gets view from specified cache.
-	 * @param cache the cache
-	 * @return the first view from cache.
-	 */
-	private View getCachedView(List<View> cache) {
-		if (cache != null && cache.size() > 0) {
-			View view = cache.get(0);
-			cache.remove(0);
-			return view;
-		}
-		return null;
-	}
-
-}

+ 0 - 964
datelib/src/main/java/com/yanyi/datelib/wheelview/WheelView.java

@@ -1,964 +0,0 @@
-/*
- *  Android Wheel Control.
- *  https://code.google.com/p/android-wheel/
- * 
- *  Copyright 2011 Yuri Kanivets
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package com.yanyi.datelib.wheelview;
-
-import android.content.Context;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.GradientDrawable.Orientation;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.animation.Interpolator;
-import android.widget.LinearLayout;
-
-import com.yanyi.datelib.R;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Numeric wheel view.
- *
- * @author myLove
- */
-public class WheelView extends View {
-
-	/** Top and bottom shadows colors */
-	/*/ Modified by wulianghuan 2014-11-25
-	private int[] SHADOWS_COLORS = new int[] { 0xFF111111,
-			0x00AAAAAA, 0x00AAAAAA };
-	//*/
-	private int[] SHADOWS_COLORS = new int[] {0xFFFFFFFF, 0x00FFFFFF, 0x00FFFFFF };
-
-	/** Top and bottom items offset (to hide that) */
-	private static final int ITEM_OFFSET_PERCENT = 0;
-
-	/** Left and right padding value */
-	private static final int PADDING = 10;
-
-	/** Default count of visible items */
-	private static final int DEF_VISIBLE_ITEMS = 5;
-
-	// Wheel Values
-	private int currentItem = 0;
-
-	// Count of visible items
-	private int visibleItems = DEF_VISIBLE_ITEMS;
-
-	// Item height
-	private int itemHeight = 0;
-
-	// Center Line
-	private Drawable centerDrawable;
-
-	// Wheel drawables
-	private int wheelBackground = R.drawable.wheel_bg;
-	private int wheelForeground = R.drawable.wheel_val;
-
-	// Shadows drawables
-	private GradientDrawable topShadow;
-	private GradientDrawable bottomShadow;
-
-	// Draw Shadows
-	private boolean drawShadows = true;
-
-	// Scrolling
-	private WheelScroller scroller;
-	private boolean isScrollingPerformed;
-	private int scrollingOffset;
-
-	// Cyclic
-	boolean isCyclic = false;
-
-	// Items layout
-	private LinearLayout itemsLayout;
-
-	// The number of first item in layout
-	private int firstItem;
-
-	// View adapter
-	private WheelViewAdapter viewAdapter;
-
-	// Recycle
-	private WheelRecycle recycle = new WheelRecycle(this);
-
-	// Listeners
-	private List<OnWheelChangedListener> changingListeners = new LinkedList<OnWheelChangedListener>();
-	private List<OnWheelScrollListener> scrollingListeners = new LinkedList<OnWheelScrollListener>();
-	private List<OnWheelClickedListener> clickingListeners = new LinkedList<OnWheelClickedListener>();
-	
-	String label="";
-
-	/**
-	 * Constructor
-	 */
-	public WheelView(Context context, AttributeSet attrs, int defStyle) {
-		super(context, attrs, defStyle);
-		initData(context);
-	}
-
-	/**
-	 * Constructor
-	 */
-	public WheelView(Context context, AttributeSet attrs) {
-		super(context, attrs);
-		initData(context);
-	}
-
-	/**
-	 * Constructor
-	 */
-	public WheelView(Context context) {
-		super(context);
-		initData(context);
-	}
-
-	/**
-	 * Initializes class data
-	 * @param context the context
-	 */
-	private void initData(Context context) {
-		scroller = new WheelScroller(getContext(), scrollingListener);
-	}
-
-	// Scrolling listener
-	WheelScroller.ScrollingListener scrollingListener = new WheelScroller.ScrollingListener() {
-		@Override
-		public void onStarted() {
-			isScrollingPerformed = true;
-			notifyScrollingListenersAboutStart();
-		}
-
-		@Override
-		public void onScroll(int distance) {
-			doScroll(distance);
-
-			int height = getHeight();
-			if (scrollingOffset > height) {
-				scrollingOffset = height;
-				scroller.stopScrolling();
-			} else if (scrollingOffset < -height) {
-				scrollingOffset = -height;
-				scroller.stopScrolling();
-			}
-		}
-
-		@Override
-		public void onFinished() {
-			if (isScrollingPerformed) {
-				notifyScrollingListenersAboutEnd();
-				isScrollingPerformed = false;
-			}
-
-			scrollingOffset = 0;
-			invalidate();
-		}
-
-		@Override
-		public void onJustify() {
-			if (Math.abs(scrollingOffset) > WheelScroller.MIN_DELTA_FOR_SCROLLING) {
-				scroller.scroll(scrollingOffset, 0);
-			}
-		}
-	};
-
-	/**
-	 * Set the the specified scrolling interpolator
-	 * @param interpolator the interpolator
-	 */
-	public void setInterpolator(Interpolator interpolator) {
-		scroller.setInterpolator(interpolator);
-	}
-
-	/**
-	 * Gets count of visible items
-	 * 
-	 * @return the count of visible items
-	 */
-	public int getVisibleItems() {
-		return visibleItems;
-	}
-
-	/**
-	 * Sets the desired count of visible items.
-	 * Actual amount of visible items depends on wheel layout parameters.
-	 * To apply changes and rebuild view call measure().
-	 * 
-	 * @param count the desired count for visible items
-	 */
-	public void setVisibleItems(int count) {
-		visibleItems = count;
-	}
-
-	/**
-	 * Gets view adapter
-	 * @return the view adapter
-	 */
-	public WheelViewAdapter getViewAdapter() {
-		return viewAdapter;
-	}
-
-	// Adapter listener
-	private DataSetObserver dataObserver = new DataSetObserver() {
-		@Override
-		public void onChanged() {
-			invalidateWheel(false);
-		}
-
-		@Override
-		public void onInvalidated() {
-			invalidateWheel(true);
-		}
-	};
-
-	/**
-	 * Sets view adapter. Usually new adapters contain different views, so
-	 * it needs to rebuild view by calling measure().
-	 * 
-	 * @param viewAdapter the view adapter
-	 */
-	public void setViewAdapter(WheelViewAdapter viewAdapter) {
-		if (this.viewAdapter != null) {
-			this.viewAdapter.unregisterDataSetObserver(dataObserver);
-		}
-		this.viewAdapter = viewAdapter;
-		if (this.viewAdapter != null) {
-			this.viewAdapter.registerDataSetObserver(dataObserver);
-		}
-
-		invalidateWheel(true);
-	}
-
-	/**
-	 * Adds wheel changing listener
-	 * @param listener the listener
-	 */
-	public void addChangingListener(OnWheelChangedListener listener) {
-		changingListeners.add(listener);
-	}
-
-	/**
-	 * Removes wheel changing listener
-	 * @param listener the listener
-	 */
-	public void removeChangingListener(OnWheelChangedListener listener) {
-		changingListeners.remove(listener);
-	}
-
-	/**
-	 * Notifies changing listeners
-	 * @param oldValue the old wheel value
-	 * @param newValue the new wheel value
-	 */
-	protected void notifyChangingListeners(int oldValue, int newValue) {
-		for (OnWheelChangedListener listener : changingListeners) {
-			listener.onChanged(this, oldValue, newValue);
-		}
-	}
-
-	/**
-	 * Adds wheel scrolling listener
-	 * @param listener the listener
-	 */
-	public void addScrollingListener(OnWheelScrollListener listener) {
-		scrollingListeners.add(listener);
-	}
-
-	/**
-	 * Removes wheel scrolling listener
-	 * @param listener the listener
-	 */
-	public void removeScrollingListener(OnWheelScrollListener listener) {
-		scrollingListeners.remove(listener);
-	}
-
-	/**
-	 * Notifies listeners about starting scrolling
-	 */
-	protected void notifyScrollingListenersAboutStart() {
-		for (OnWheelScrollListener listener : scrollingListeners) {
-			listener.onScrollingStarted(this);
-		}
-	}
-
-	/**
-	 * Notifies listeners about ending scrolling
-	 */
-	protected void notifyScrollingListenersAboutEnd() {
-		for (OnWheelScrollListener listener : scrollingListeners) {
-			listener.onScrollingFinished(this);
-		}
-	}
-
-	/**
-	 * Adds wheel clicking listener
-	 * @param listener the listener
-	 */
-	public void addClickingListener(OnWheelClickedListener listener) {
-		clickingListeners.add(listener);
-	}
-
-	/**
-	 * Removes wheel clicking listener
-	 * @param listener the listener
-	 */
-	public void removeClickingListener(OnWheelClickedListener listener) {
-		clickingListeners.remove(listener);
-	}
-
-	/**
-	 * Notifies listeners about clicking
-	 */
-	protected void notifyClickListenersAboutClick(int item) {
-		for (OnWheelClickedListener listener : clickingListeners) {
-			listener.onItemClicked(this, item);
-		}
-	}
-
-	/**
-	 * Gets current value
-	 * 
-	 * @return the current value
-	 */
-	public int getCurrentItem() {
-		return currentItem;
-	}
-
-	/**
-	 * Sets the current item. Does nothing when index is wrong.
-	 * 
-	 * @param index the item index
-	 * @param animated the animation flag
-	 */
-	public void setCurrentItem(int index, boolean animated) {
-		if (viewAdapter == null || viewAdapter.getItemsCount() == 0) {
-			return; // throw?
-		}
-
-		int itemCount = viewAdapter.getItemsCount();
-		if (index < 0 || index >= itemCount) {
-			if (isCyclic) {
-				while (index < 0) {
-					index += itemCount;
-				}
-				index %= itemCount;
-			} else{
-				return; // throw?
-			}
-		}
-		if (index != currentItem) {
-			if (animated) {
-				int itemsToScroll = index - currentItem;
-				if (isCyclic) {
-					int scroll = itemCount + Math.min(index, currentItem) - Math.max(index, currentItem);
-					if (scroll < Math.abs(itemsToScroll)) {
-						itemsToScroll = itemsToScroll < 0 ? scroll : -scroll;
-					}
-				}
-				scroll(itemsToScroll, 0);
-			} else {
-				scrollingOffset = 0;
-
-				int old = currentItem;
-				currentItem = index;
-
-				notifyChangingListeners(old, currentItem);
-
-				invalidate();
-			}
-		}
-	}
-
-	/**
-	 * Sets the current item w/o animation. Does nothing when index is wrong.
-	 * 
-	 * @param index the item index
-	 */
-	public void setCurrentItem(int index) {
-		setCurrentItem(index, false);
-	}
-
-	/**
-	 * Tests if wheel is cyclic. That means before the 1st item there is shown the last one
-	 * @return true if wheel is cyclic
-	 */
-	public boolean isCyclic() {
-		return isCyclic;
-	}
-
-	/**
-	 * Set wheel cyclic flag
-	 * @param isCyclic the flag to set
-	 */
-	public void setCyclic(boolean isCyclic) {
-		this.isCyclic = isCyclic;
-		invalidateWheel(false);
-	}
-
-	/**
-	 * Determine whether shadows are drawn
-	 * @return true is shadows are drawn
-	 */
-	public boolean drawShadows() {
-		return drawShadows;
-	}
-
-	/**
-	 * Set whether shadows should be drawn
-	 * @param drawShadows flag as true or false
-	 */
-	public void setDrawShadows(boolean drawShadows) {
-		this.drawShadows = drawShadows;
-	}
-
-	/**
-	 * Set the shadow gradient color
-	 * @param start
-	 * @param middle
-	 * @param end
-	 */
-	public void setShadowColor(int start, int middle, int end) {
-		SHADOWS_COLORS = new int[] {start, middle, end};
-	}
-
-	/**
-	 * Sets the drawable for the wheel background
-	 * @param resource
-	 */
-	public void setWheelBackground(int resource) {
-		wheelBackground = resource;
-		setBackgroundResource(wheelBackground);
-	}
-
-	/**
-	 * Sets the drawable for the wheel foreground
-	 * @param resource
-	 */
-	public void setWheelForeground(int resource) {
-		wheelForeground = resource;
-		centerDrawable = getContext().getResources().getDrawable(wheelForeground);
-	}
-
-	/**
-	 * Invalidates wheel
-	 * @param clearCaches if true then cached views will be clear
-	 */
-	public void invalidateWheel(boolean clearCaches) {
-		if (clearCaches) {
-			recycle.clearAll();
-			if (itemsLayout != null) {
-				itemsLayout.removeAllViews();
-			}
-			scrollingOffset = 0;
-		} else if (itemsLayout != null) {
-			// cache all items
-			recycle.recycleItems(itemsLayout, firstItem, new ItemsRange());
-		}
-
-		invalidate();
-	}
-
-	/**
-	 * Initializes resources
-	 */
-	private void initResourcesIfNecessary() {
-		if (centerDrawable == null) {
-			centerDrawable = getContext().getResources().getDrawable(wheelForeground);
-		}
-
-		if (topShadow == null) {
-			topShadow = new GradientDrawable(Orientation.TOP_BOTTOM, SHADOWS_COLORS);
-		}
-
-		if (bottomShadow == null) {
-			bottomShadow = new GradientDrawable(Orientation.BOTTOM_TOP, SHADOWS_COLORS);
-		}
-
-		setBackgroundResource(wheelBackground);
-	}
-
-	/**
-	 * Calculates desired height for layout
-	 * 
-	 * @param layout
-	 *            the source layout
-	 * @return the desired layout height
-	 */
-	private int getDesiredHeight(LinearLayout layout) {
-		if (layout != null && layout.getChildAt(0) != null) {
-			itemHeight = layout.getChildAt(0).getMeasuredHeight();
-		}
-
-		int desired = itemHeight * visibleItems - itemHeight * ITEM_OFFSET_PERCENT / 50;
-
-		return Math.max(desired, getSuggestedMinimumHeight());
-	}
-
-	/**
-	 * Returns height of wheel item
-	 * @return the item height
-	 */
-	private int getItemHeight() {
-		if (itemHeight != 0) {
-			return itemHeight;
-		}
-
-		if (itemsLayout != null && itemsLayout.getChildAt(0) != null) {
-			itemHeight = itemsLayout.getChildAt(0).getHeight();
-			return itemHeight;
-		}
-
-		return getHeight() / visibleItems;
-	}
-
-	/**
-	 * Calculates control width and creates text layouts
-	 * @param widthSize the input layout width
-	 * @param mode the layout mode
-	 * @return the calculated control width
-	 */
-	private int calculateLayoutWidth(int widthSize, int mode) {
-		initResourcesIfNecessary();
-
-		// TODO: make it static
-		itemsLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-		itemsLayout.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.UNSPECIFIED),
-				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-		int width = itemsLayout.getMeasuredWidth();
-
-		if (mode == MeasureSpec.EXACTLY) {
-			width = widthSize;
-		} else {
-			width += 2 * PADDING;
-
-			// Check against our minimum width
-			width = Math.max(width, getSuggestedMinimumWidth());
-
-			if (mode == MeasureSpec.AT_MOST && widthSize < width) {
-				width = widthSize;
-			}
-		}
-
-		itemsLayout.measure(MeasureSpec.makeMeasureSpec(width - 2 * PADDING, MeasureSpec.EXACTLY),
-				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-
-		return width;
-	}
-
-	@Override
-	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-
-		buildViewForMeasuring();
-
-		int width = calculateLayoutWidth(widthSize, widthMode);
-
-		int height;
-		if (heightMode == MeasureSpec.EXACTLY) {
-			height = heightSize;
-		} else {
-			height = getDesiredHeight(itemsLayout);
-
-			if (heightMode == MeasureSpec.AT_MOST) {
-				height = Math.min(height, heightSize);
-			}
-		}
-
-		setMeasuredDimension(width, height);
-	}
-
-	@Override
-	protected void onLayout(boolean changed, int l, int t, int r, int b) {
-		layout(r - l, b - t);
-	}
-
-	/**
-	 * Sets layouts width and height
-	 * @param width the layout width
-	 * @param height the layout height
-	 */
-	private void layout(int width, int height) {
-		int itemsWidth = width - 2 * PADDING;
-
-		itemsLayout.layout(0, 0, itemsWidth, height);
-	}
-
-	@Override
-	protected void onDraw(Canvas canvas) {
-		super.onDraw(canvas);
-
-		if (viewAdapter != null && viewAdapter.getItemsCount() > 0) {
-			updateView();
-
-			drawItems(canvas);
-			drawCenterRect(canvas);
-		}
-
-		if (drawShadows) {
-			drawShadows(canvas);
-		}
-	}
-
-	/**
-	 * Draws shadows on top and bottom of control
-	 * @param canvas the canvas for drawing
-	 */
-	private void drawShadows(Canvas canvas) {
-		/*/ Modified by wulianghuan 2014-11-25
-		int height = (int)(1.5 * getItemHeight());
-		//*/
-		int height = (int)(3 * getItemHeight());
-		//*/
-		//topShadow.setBounds(0, 0, getWidth(), height);
-		topShadow.setBounds(0, 0, getWidth(), getHeight());
-		topShadow.draw(canvas);
-
-		//bottomShadow.setBounds(0, getHeight() - height, getWidth(), getHeight());
-		bottomShadow.setBounds(0, 0, getWidth(), getHeight());
-		bottomShadow.draw(canvas);
-	}
-
-	/**
-	 * Draws items
-	 * @param canvas the canvas for drawing
-	 */
-	private void drawItems(Canvas canvas) {
-		canvas.save();
-
-		int top = (currentItem - firstItem) * getItemHeight() + (getItemHeight() - getHeight()) / 2;
-		canvas.translate(PADDING, - top + scrollingOffset);
-
-		itemsLayout.draw(canvas);
-
-		canvas.restore();
-	}
-
-	/**
-	 * Draws rect for current value
-	 * @param canvas the canvas for drawing
-	 */
-	private void drawCenterRect(Canvas canvas) {
-		int center = getHeight() / 2;
-		int offset = (int) (getItemHeight() / 2 * 1.2);
-//		int offset = 60;
-		/*/ Remarked by wulianghuan 2014-11-27  使用自己的画线,而不是描边
-		Rect rect = new Rect(left, top, right, bottom)
-		centerDrawable.setBounds(bounds)
-		centerDrawable.setBounds(0, center - offset, getWidth(), center + offset);
-		centerDrawable.draw(canvas);
-		//*/
-		Paint paint = new Paint();
-		paint.setColor(Color.parseColor("#D0D0D0"));
-		// 设置线宽
-//		paint.setStrokeWidth((float) 3);
-		paint.setStrokeWidth((float) 2);
-		// 绘制上边直线
-		canvas.drawLine(0, center - offset, getWidth(), center - offset, paint);
-		// 绘制下边直线
-		canvas.drawLine(0, center + offset, getWidth(), center + offset, paint);
-		//*/
-	}
-
-	@Override
-	public boolean onTouchEvent(MotionEvent event) {
-		if (!isEnabled() || getViewAdapter() == null) {
-			return true;
-		}
-
-		switch (event.getAction()) {
-			case MotionEvent.ACTION_MOVE:
-				if (getParent() != null) {
-					getParent().requestDisallowInterceptTouchEvent(true);
-				}
-				break;
-
-			case MotionEvent.ACTION_UP:
-				if (!isScrollingPerformed) {
-					int distance = (int) event.getY() - getHeight() / 2;
-					if (distance > 0) {
-						distance += getItemHeight() / 2;
-					} else {
-						distance -= getItemHeight() / 2;
-					}
-					int items = distance / getItemHeight();
-					if (items != 0 && isValidItemIndex(currentItem + items)) {
-						notifyClickListenersAboutClick(currentItem + items);
-					}
-				}
-				break;
-		}
-
-		return scroller.onTouchEvent(event);
-	}
-
-	/**
-	 * Scrolls the wheel
-	 * @param delta the scrolling value
-	 */
-	private void doScroll(int delta) {
-		scrollingOffset += delta;
-
-		int itemHeight = getItemHeight();
-		int count = scrollingOffset / itemHeight;
-
-		int pos = currentItem - count;
-		int itemCount = viewAdapter.getItemsCount();
-
-		int fixPos = scrollingOffset % itemHeight;
-		if (Math.abs(fixPos) <= itemHeight / 2) {
-			fixPos = 0;
-		}
-		if (isCyclic && itemCount > 0) {
-			if (fixPos > 0) {
-				pos--;
-				count++;
-			} else if (fixPos < 0) {
-				pos++;
-				count--;
-			}
-			// fix position by rotating
-			while (pos < 0) {
-				pos += itemCount;
-			}
-			pos %= itemCount;
-		} else {
-			//
-			if (pos < 0) {
-				count = currentItem;
-				pos = 0;
-			} else if (pos >= itemCount) {
-				count = currentItem - itemCount + 1;
-				pos = itemCount - 1;
-			} else if (pos > 0 && fixPos > 0) {
-				pos--;
-				count++;
-			} else if (pos < itemCount - 1 && fixPos < 0) {
-				pos++;
-				count--;
-			}
-		}
-
-		int offset = scrollingOffset;
-		if (pos != currentItem) {
-			setCurrentItem(pos, false);
-		} else {
-			invalidate();
-		}
-
-		// update offset
-		scrollingOffset = offset - count * itemHeight;
-		if (scrollingOffset > getHeight()) {
-			scrollingOffset = scrollingOffset % getHeight() + getHeight();
-		}
-	}
-
-	/**
-	 * Scroll the wheel
-	 * @param itemsToScroll items to scroll
-	 * @param time scrolling duration
-	 */
-	public void scroll(int itemsToScroll, int time) {
-		int distance = itemsToScroll * getItemHeight() - scrollingOffset;
-		scroller.scroll(distance, time);
-	}
-
-	/**
-	 * Calculates range for wheel items
-	 * @return the items range
-	 */
-	private ItemsRange getItemsRange() {
-		if (getItemHeight() == 0) {
-			return null;
-		}
-
-		int first = currentItem;
-		int count = 1;
-
-		while (count * getItemHeight() < getHeight()) {
-			first--;
-			count += 2; // top + bottom items
-		}
-
-		if (scrollingOffset != 0) {
-			if (scrollingOffset > 0) {
-				first--;
-			}
-			count++;
-
-			// process empty items above the first or below the second
-			int emptyItems = scrollingOffset / getItemHeight();
-			first -= emptyItems;
-			count += Math.asin(emptyItems);
-		}
-		return new ItemsRange(first, count);
-	}
-
-	/**
-	 * Rebuilds wheel items if necessary. Caches all unused items.
-	 * 
-	 * @return true if items are rebuilt
-	 */
-	private boolean rebuildItems() {
-		boolean updated = false;
-		ItemsRange range = getItemsRange();
-		if (itemsLayout != null) {
-			int first = recycle.recycleItems(itemsLayout, firstItem, range);
-			updated = firstItem != first;
-			firstItem = first;
-		} else {
-			createItemsLayout();
-			updated = true;
-		}
-
-		if (!updated) {
-			updated = firstItem != range.getFirst() || itemsLayout.getChildCount() != range.getCount();
-		}
-
-		if (firstItem > range.getFirst() && firstItem <= range.getLast()) {
-			for (int i = firstItem - 1; i >= range.getFirst(); i--) {
-				if (!addViewItem(i, true)) {
-					break;
-				}
-				firstItem = i;
-			}
-		} else {
-			firstItem = range.getFirst();
-		}
-
-		int first = firstItem;
-		for (int i = itemsLayout.getChildCount(); i < range.getCount(); i++) {
-			if (!addViewItem(firstItem + i, false) && itemsLayout.getChildCount() == 0) {
-				first++;
-			}
-		}
-		firstItem = first;
-
-		return updated;
-	}
-
-	/**
-	 * Updates view. Rebuilds items and label if necessary, recalculate items sizes.
-	 */
-	private void updateView() {
-		if (rebuildItems()) {
-			calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY);
-			layout(getWidth(), getHeight());
-		}
-	}
-
-	/**
-	 * Creates item layouts if necessary
-	 */
-	private void createItemsLayout() {
-		if (itemsLayout == null) {
-			itemsLayout = new LinearLayout(getContext());
-			itemsLayout.setOrientation(LinearLayout.VERTICAL);
-		}
-	}
-
-	/**
-	 * Builds view for measuring
-	 */
-	private void buildViewForMeasuring() {
-		// clear all items
-		if (itemsLayout != null) {
-			recycle.recycleItems(itemsLayout, firstItem, new ItemsRange());
-		} else {
-			createItemsLayout();
-		}
-
-		// add views
-		int addItems = visibleItems / 2;
-		for (int i = currentItem + addItems; i >= currentItem - addItems; i--) {
-			if (addViewItem(i, true)) {
-				firstItem = i;
-			}
-		}
-	}
-
-	/**
-	 * Adds view for item to items layout
-	 * @param index the item index
-	 * @param first the flag indicates if view should be first
-	 * @return true if corresponding item exists and is added
-	 */
-	private boolean addViewItem(int index, boolean first) {
-		View view = getItemView(index);
-		if (view != null) {
-			if (first) {
-				itemsLayout.addView(view, 0);
-			} else {
-				itemsLayout.addView(view);
-			}
-
-			return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Checks whether intem index is valid
-	 * @param index the item index
-	 * @return true if item index is not out of bounds or the wheel is cyclic
-	 */
-	private boolean isValidItemIndex(int index) {
-		return viewAdapter != null && viewAdapter.getItemsCount() > 0 &&
-				(isCyclic || index >= 0 && index < viewAdapter.getItemsCount());
-	}
-
-	/**
-	 * Returns view for specified item
-	 * @param index the item index
-	 * @return item view or empty view if index is out of bounds
-	 */
-	private View getItemView(int index) {
-		if (viewAdapter == null || viewAdapter.getItemsCount() == 0) {
-			return null;
-		}
-		int count = viewAdapter.getItemsCount();
-		if (!isValidItemIndex(index)) {
-			return viewAdapter.getEmptyItem(recycle.getEmptyItem(), itemsLayout);
-		} else {
-			while (index < 0) {
-				index = count + index;
-			}
-		}
-
-		index %= count;
-		return viewAdapter.getItem(index, recycle.getItem(), itemsLayout);
-	}
-
-	/**
-	 * Stops scrolling
-	 */
-	public void stopScrolling() {
-		scroller.stopScrolling();
-	}
-}

+ 5 - 5
datelib/src/main/res/layout/select_date_pop_layout.xml

@@ -73,7 +73,7 @@
                     android:text="年"
                     android:textColor="@android:color/black" />
 
-                <com.yanyi.datelib.wheelview.WheelView
+                <com.benyanyi.datelib.wheelview.WheelView
                     android:id="@+id/wv_date_year"
                     android:layout_width="match_parent"
                     android:layout_height="160dp"
@@ -97,7 +97,7 @@
                     android:text="月"
                     android:textColor="@android:color/black" />
 
-                <com.yanyi.datelib.wheelview.WheelView
+                <com.benyanyi.datelib.wheelview.WheelView
                     android:id="@+id/wv_date_month"
                     android:layout_width="match_parent"
                     android:layout_height="160dp"
@@ -121,7 +121,7 @@
                     android:text="日"
                     android:textColor="@android:color/black" />
 
-                <com.yanyi.datelib.wheelview.WheelView
+                <com.benyanyi.datelib.wheelview.WheelView
                     android:id="@+id/wv_date_day"
                     android:layout_width="match_parent"
                     android:layout_height="160dp"
@@ -146,7 +146,7 @@
                     android:text="时"
                     android:textColor="@android:color/black" />
 
-                <com.yanyi.datelib.wheelview.WheelView
+                <com.benyanyi.datelib.wheelview.WheelView
                     android:id="@+id/wv_date_hour"
                     android:layout_width="match_parent"
                     android:layout_height="160dp"
@@ -171,7 +171,7 @@
                     android:text="分"
                     android:textColor="@android:color/black" />
 
-                <com.yanyi.datelib.wheelview.WheelView
+                <com.benyanyi.datelib.wheelview.WheelView
                     android:id="@+id/wv_date_minute"
                     android:layout_width="match_parent"
                     android:layout_height="160dp"

+ 10 - 10
datelib/src/main/res/layout/select_period_pop_layout.xml

@@ -130,7 +130,7 @@
                             android:text="年"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/start_year"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -154,7 +154,7 @@
                             android:text="月"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/start_month"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -178,7 +178,7 @@
                             android:text="日"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/start_day"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -203,7 +203,7 @@
                             android:text="时"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/start_hour"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -228,7 +228,7 @@
                             android:text="分"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/start_minute"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -267,7 +267,7 @@
                             android:text="年"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/end_year"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -291,7 +291,7 @@
                             android:text="月"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/end_month"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -315,7 +315,7 @@
                             android:text="日"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/end_day"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -340,7 +340,7 @@
                             android:text="时"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/end_hour"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"
@@ -365,7 +365,7 @@
                             android:text="分"
                             android:textColor="@android:color/black" />
 
-                        <com.yanyi.datelib.wheelview.WheelView
+                        <com.benyanyi.datelib.wheelview.WheelView
                             android:id="@+id/end_minute"
                             android:layout_width="match_parent"
                             android:layout_height="160dp"

+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

+ 0 - 0
gradlew