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
T_!q6w&A(oZy)(MT)<5B2qpSg;
literal 0
HcmV?d00001
diff --git a/PersonalCenter/app/src/main/res/mipmap-xhdpi/logo_info.png b/PersonalCenter/app/src/main/res/mipmap-xhdpi/logo_info.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4e8b47c960217116fe238cacf740e03421cbd13
GIT binary patch
literal 5160
zcmV+@6xZvCP)
zdAL;NeaAm{VG}N*Y&D>XXh0LtO01H&L?vp3)YvGlEJD(zwRvh|ZJ*ROwM}VlQo_puK
z?>Uz_^EAg2h0F2299-H`#kVBz|V}YsX+sCnrnRl4N^rPB)rxD*W)hy01ii*;CF#0vny-R
zAO>1%eE|(p!!f{oV2sgzUkBC#-!|H>K?8G=G=cjAQ#{tK1YU4B{^P)Lz;0l(!@A|b
z4u|8j#8-gpfL_M?Zbv@D^&V@-0|On`Yz20CoGXM5U?Z>&_#okPHwYw24e%`BzdY6*
z;duNvfoYCwUIy+i`rXHXr>NeHa}~HgG$Wxf0O-t}Z#}RYcn>NagTC0+G649J$9d+L_}!O*
zL5}K>1UKM+s0{kGZ3(PUxW6c!mPxt|RB=e82+Ty9X(@UGHxhp!%*XtlVSW|0;V57+x|c2j+8x&ZKJb@uT-091
z4&X814)i_WQ21t2QQ!+b&ee>Exqju0T=GLe4-!yPlZ_TwdY*bAeGYUqcu0KaOig
z0Vl+8Ew$t{WEQ(v2w8au)S5oPNyyT93z!Y`&A*wH0Ce@q0o;e8h}AL@nRKp{GJpTX
zW1lqgSIAT@#TODd|6RbFj%$1#V)ejbz%^AK+Y2cT4Q%O;+(b_xd69?!90wffvF;Yf
zny`l1#xi)!|^`=zUFw2wa5=pctf`4ewQ>Yr~+d#
zO69TQS;}i115k>CW0t-SJmPSCFZ88zWg$JE#vQnuZB|U6AUb8hZs5`i?{7hYkOv9(
zH*Ey2&b_i+4KX%w{c=>A455aar1rx=cvR+!erQnki|D54X+X-JoX(1yy|d#
zFJQ38d8Pwr7yWKIdIBfSWx#g~_uGnc03VJx?m5)r>N?;LJZnSn(fBo>D5g|qLl!w7<+J+opsxTNgl>kAlb53(O6HB5A-Pu}t~qO=G@-63mI<#<
zBEM_3_0w-5pVJZOGd&&oQ%j}Kv?I-8CGb<=|3WXej`%!&RV{hiiEa^Qq5bUuZZ+7a
z9teFP{lr%Qo=ZH!ua;~=^_xl28~KyYH{5d(syc89Amw=$B~D+Cl1GOihkPsDHOIfR
zxy-s`R^a*tRBqJJjGxP>n4c1DW@mxX$Zh0HJFv`G0A?{vzl7xcSNo#UoQX#Jb)r6g
zR%Y}L;O*SYg(g(~)egL2bS-IM2;qt2QReSSz=4710Ht=h*086Q&6JOthsvOZz%CyF
zI0~gJWR2o_;J7#dxEIxWTCg5zfw!8}Y%Dn{O)PNJGm7fs*AfE}SReW*a#g`?>
zFBNA+N1ndGXXzGtm6|BT)myMujK{qvWg$C>*2>PtuZvNZsT9c$4Ssx>%jqfrKSTN2
z(t0NDw1G*e=GdagT_-B&{&(UP+9T-}coV5E+4KS2x_8$Dq1xX)MCZ$8(Wf558q__f
z6a#>B0`~5tz}@940JCWRJ^{QK$|rB)z~gK*sGWp;L}LpO~Oy>$(r`phw!c}
zQNfRckV)5|oB5P~xcm0}%yS>`ZvF=s0oV)Wh;6KJOkZ@<)Dx~1TCmO*{Z7KZshj}4K6gH|LeSIdkl7+Z?4B}7D+u2
zYW~hAy7|Gyf#(1P@UAr2Ck^aGGkQvKAnFs~%O;AtOj*_f?~7j-3!k?4J`Drn)btAJ
zhn`?Qvq_5SLO1qo{QZ4xXdFS_w2h*N<81}6tBal`c!rX}WC!n@Wq5KH9<{|Zp
zPtVUn7E_e#YbgNF!`=K%s_p$sG$18z1|c)>c!Rw*qmnisvvLd)c9VeX*NZ5>uiA)e
zANEXBImF-^T!?$JTrCJKeVZHcejjYgAeZI#ire?T1$9fR6%$Y%tuL>jhteKc3BZH#
z(|TM5laIrACsKXmT11#nk(kJ{Z*ovBzzJ@;VSBw5V65E>R8*mq1vrs-`R(YN1zLFOZ
ze>e69-OMfbhQ){AqsqU5+ZVAnetwQykq@w#tPDQ78db8aK|-!Q;&{t>$GcGag$pfY
zvzEM&`9$YKUYx*nG!Wb9Ir{cPLIq$Sl>Xw%0^E{jC*jxjzLb{PhTja4wDA(^0a$H*
z;QqKLsaN85;J1!zP9^?%#I+{M{5^v7_;2?H?x2GEBUAuR#;<%T3G??Q;PDc_KNs7{
zYqeqyZpqQpu}zimNqxz><9`Lwlh}p<*OYm0DB-oopuE>B=)OOyo#1u_^0kNX9`IGq
zwN2Or6ASrer8h$bpwA8M+I(Oz611+A6S9_OV6EuDy@JN_?|zaJIaLu11pdhI8q!Eq
z-#^e4z6VSEekAbU2G{Tq8gRAEaos-HGzDHv9VKRmWV#Q=Z?LxO7xx0(D;c^_kH2EZ
zp#Vs|a}RFj=Lz^l(97YY{Y}Ak>}T58f_p?f&!MQ4?URAmuoQLWb`^f0yhMwhgr&ZB
zsU<`Jo`<_&>cBlI*+;_=Q&QEJXF^
zrGkFda8cm-LDd$e+)k+_L;(8u<(3g0sVwAh{CpCn%-_CbBLevrZl;oT@M8|{!=nyH
zHOW~fD)>=~qfyFCXa&)a&;!P|RBeC48$UpuX@B7F100Q?Dd}4J=A$)yKaJKc(%pdse>3tYriu57aJHA=L}apt{w+74
z;Dv8h6NC?a%2Rg&u&HZ?SI}iPYRm4z29yG^qsrr(QNEz-({T|tk+gDr6h-<%n^+!A
zGK0leW9R?78}~p)6N<=(j#9Xd@CuEza0Yq+T8v0&(32HZ*=5_u1a895l)RPdg&)9a
z_?ZTAcYgT_;ll4pk`aE^!H@5ItnsZBDkko^ElDv24KHs9zxb$H6ZH{*Cn7D#71ta1
z8y@Fa3*7Iqu3B2K$>RU9!5-CM8T?p{U(-#Co_FhrZY^IA%tDGl-2EB%W_F-}R8{y0
zKp%h3%edu@O-B9gTv7YU|*~wYYbs_N^2uW+Cx6Oo*FHQ2@zm
z1VMw++(YHLMSI}$VfaLgRyZ8H5AdHJ=h%(rQpCxZ4fa?}GK0e{gCCplb1i%ko6P>C
z#u>!LKj3#yH*m-4Uh#(cTxGBe`j6jaR+!giAJWeow&Hr&s5;E_f2_d(!o
zgMAwG#KJxCE^59|xA+7>R(q`34|S+0MZOT+XI||l;2h$gR%M}4EkViPaWexyH$^F4
zMGq!d#^E;Xz8v)){75UlGrWt5JL@8Ld`y(5@M|Z3CGt5G3ag{h7i@^fex2wk_8X72
zE(}G!$xxE;lQdy#{{9fRvOAEU^b&(}Zv*Z!*r%3Uh4NXqkS;;df{pom3GsGUuXdKp
zMkGs|Q>ACg~#px1*%a
zD?QdWBfmiiUnjYw(h~^RsCJM{9jkTlqg?9CXjI*C5iq92`<>WSJGgdNNgEbHpa#*r
zLcqP^d!v3AwPi|@?WoI3k{R_D8r7X>JZIck20tDFo-6qIAmDP8ko+P_J1P`@?ZEd?
z;{(@Tf#q0Zv`;N)!@c!d13zxTy+rdveDkz6A?IgO1?q308!E|)fI--3R7se>*1?bO
zql%w%kcoR7Jv-oZA~W@7yAnfC^wXm5_a>6LQLHE3
zO)UC3KU{ha@F?Z~rqGd!g`A4t?2$C^XzrCJnov`QP=1Eo9ho51S=|q5IPVx-OCcS=
zKcYIrq-aHE{R`L#zjmq{lNicSY=a+#JdT9x0m#Sr2$cnT=$L>)uE2JV@!rk^!mF8}
zzDpB(;Hm-k20n#K+fG6yVsVT*Y(;}!zJtE#KA9^|7pfgj!i1ZN
zUGM|cx#t!nyjMA_>x-@5YaBAery-wngD@XlCG#o()Sz}EvRmHXy86Kk)6@9K(_#FL5anO00*L^)_NFX{TdR4GwGf;ay)Pp
z-CxE5D584+FbWNyJ}{>1*$I3V1qhO0B5D}m%gadU%|l<1P&Sj@s)sytDIehYd*E}%
z=i7zfyx~IH&;vh|r%*;lt$7>xbBm4gCh$b`#jQ6EMjuGwu%+vf#+o#%ke@8cR2`qs
zY#TByZ${;LmO+}w=@~%D8s*Y1`l4WdAyzqMur2<_?vbk%+aBI@=zbLvLXG{KhWLp5fN%^#&AiEYR%y)XBAmToQMuhBsD^U#2y!vfD$JOtf39i$S^p!W82QI$&4TugM6hTozG
z#2ggej+=!@D?KiObJc&0n8JzOr8u-5n(5*m3S|0?NDf5-34Q`)u
z?}Y>WuGJ1KUZ^x%joo
z{216yfmU%A({t>0<0t5DH&Fw9kEMyW`*5$T1L)zsAnV@HIy}-Ilcv&XsAlBo?1lA0ohw^Wx
z0j$IAMEhfSN@uRnkFg-Z?hbw!eJC5WiVK*XWA_HzWeVxCK~G_Mg56;}$PSbVx(7QG
z?EaPs`KZbQ-Dsp-%h5}0!?;SR4A9m1Lo{#AG%U{LvwD;523;XOo@#>aNnC9-*-p?U
zxGb$&`U}UK8MF&@mAEcvCD=Z}R!w?(+5@^qcxXm~Z9l#hA5l}a8gv&f;-duHL2M8n
z%~c9$6?;XW^9w$!V>1Om;%8|M`bMFitolV|Ul@|`XiBJy>ZyRdKiQ4C#hKYM*^TPxCN|?m
zD>kc$9;THV7C&dd(IQ9!^q*F3hF8LiJ)$3PnJPFaryxkwEqspiE!bk7zQ%rhsRT&I-%P#YtNl$>M70_e
z|2Plf-}a)7RlU2uPbBIi!eiZdh%2JZdtMq{M(+S_p@OR{E%GD)0000gu000JONklP(t`pL@;J+sSoFFy3CyE?so2(rM16gU(W2FbLO9!d*_~e
zW>YkGV#KY$dSDtb#41Q0{sLNnXMv*@0a8W+jsOk;qb!{FfU`giaKg9av~P!w2Cg0P
z0EPiuEF4=1crP&9z;9e01n%?g)Iz{l4Sf3I72ghh3pg35RqWe-(cJkDa9!ZQ5TqR5PZyQI#egkSPFOrhUcBs`Fa?+hj6=qlLGJiv;3TrI
zaTpn!z5}i#n4_jiMT+K5Z7r9w&c-ncs0SVgZYlD&CxDNTl2x1MyrKwcRVo3ikjnKF
z6u-s}k^w#dRs-i_`pQR0E2~YV?wAMs3@jzScsL(RozFTC{)!?=0n3r<^bVlfz<)JT
zy4vDmB|=hx1|q^e)XjI=f&IW&$OQ2laKRlL3fzWFG}D3mfdLVIo#q^Nc=gB085n->cK4-wwzz8+X+5G#s$7c-YOWV6aE
z76M)Ywk!4(z;J_jL58_lLAGPi3S#vfxS4P@WGJxFC|)ib3GdWp(BE2$jg^3HNV`Rl
zI^_1Uq8`2C{UJvEGuE3*t%N6!q&Jn$BSi!seKUz}DxF84ILeR{^;u$Hf-W9NiQla0
z$a*c@2y9jCWk}Wd6XH!Q!<~-?bn)KD_;s@+iV4e+HVcjU$Zfuw;+_+$+;3Wm-sRg1
zJXM6x9+6ak;6UJ0;DK(wlWi_KKv#3oAMV(VbTt>vaG&m4Me?C2g=A0KALd
z>fw{E$d%V_;Jc&^mhDLE*#e|F$T#PJ$6O2x@l;AtP;CSz0Pmr^KH38^&esHFLP?Zs
zp~-w1vgtjt$lsnsmS>yzA2yi>$-d?=6{#JLL&P2Ij%QzfK8lpfz9#wC93Vo#i-b2@
z`d_pOGnlX@nKXKt+xrG|A3$phIh6)}R1Q32oJ?;-)8ud(*sUCx39Pcsr&qBG(Im+3
z6wRF#z^~}<4DSKnL8{E9{Qs9yFbKFCDb8w5@+X1Yv;W#L7pZ3SQ#kX0rtE`s6R@s?
z$@DhXA(~ya5_y3H-mB;XY(}&Kt`@KZS%l9)8pQj#nq$aNw~U;3Qo8%=r@6?#7}X%l
qtf+U>`YP?nL~#W9>!&7^wfldVq*0fq0Z4QJ0000M17`ggq7B_VfLKg?Yv>aO8
z9Id4PR-v1}JN?c*KhEcJ?mefWP$;xw72`Ni-(0~W?j(WsU>8^G
zh+f8X^y68A`}mHQI^xZNw&55L6TC)W;FkjLs3CeD+i1rR3}8Qr$v1(2E5fhU0Byt;
zy6_W2*n^~~sTgm@OLU$BJ%cawy%ZBU}vpMuq+cEMPRoQ_{<#
z>>F0fyTHHXz~^x<>ZdU-oBzRC{6gS2Gds_kn*dfluK{)C+i=XTiL1
z7H#1cb8ff
#CCCCCC
#ff480f
+ #afafaf
+ #eeeeee
diff --git a/PersonalCenter/app/src/main/res/values/strings.xml b/PersonalCenter/app/src/main/res/values/strings.xml
index ec61086..683c65d 100644
--- a/PersonalCenter/app/src/main/res/values/strings.xml
+++ b/PersonalCenter/app/src/main/res/values/strings.xml
@@ -16,14 +16,28 @@
学校
下一步
开始学习体验
+ 绑定家长控制
+ 完成
//电子保卡
填写保卡信息
填写电子保卡
+ 修改保卡信息
修改保卡信息
+ 确认保卡信息
+ 好记星-电子报卡
更换绑定
+ 温馨提示:若您想修改的相关信息请拨打客服电话
请先填写《好记星-电子保卡》信息
该信息是本产品的三包证明,为维护您的合法权益,请认真填写
+ 您已填写完《好记星-电子保卡》信息
+ 您也可以设置家长管理,用手机及时了解和管理孩子的学习情况
+
+ //意见反馈
+ 写下您对我们产品的意见吧,我们将努力完善,最多输入500字。
+ QQ或手机号码
+ 留下您的联系方式,方便与您沟通。
+
diff --git a/PersonalCenter/pickerview/.gitignore b/PersonalCenter/pickerview/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/PersonalCenter/pickerview/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/PersonalCenter/pickerview/build.gradle b/PersonalCenter/pickerview/build.gradle
new file mode 100644
index 0000000..8c09b9c
--- /dev/null
+++ b/PersonalCenter/pickerview/build.gradle
@@ -0,0 +1,49 @@
+apply plugin: 'com.android.library'
+apply plugin: 'maven'
+apply plugin: 'com.novoda.bintray-release'//添加插件
+
+
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.2"
+
+ defaultConfig {
+ minSdkVersion 15
+ targetSdkVersion 25
+ versionCode 22
+ versionName "3.2.6"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ lintOptions {
+ abortOnError false
+ }
+}
+
+allprojects {
+ tasks.withType(Javadoc) {//兼容中文字符
+ options{
+ encoding "UTF-8"
+ charSet 'UTF-8'
+ links "http://docs.oracle.com/javase/7/docs/api"
+ }
+ }
+}
+publish {
+ userOrg = 'contrarywind'//bintray.com 用户名/组织名 user/org name
+ groupId = 'com.contrarywind'//JCenter上显示的路径 path
+ artifactId = 'Android-PickerView'//项目名称 project name
+ publishVersion = '3.2.6'//版本号 version code
+ desc = 'this is a pickerview for android'//项目描述 description
+ website = 'https://github.com/Contrarywind/Android-PickerView' //项目网址链接 link
+}
+
+dependencies {
+ compile fileTree(include: ['*.jar'], dir: 'libs')
+
+}
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/proguard-rules.pro b/PersonalCenter/pickerview/proguard-rules.pro
new file mode 100644
index 0000000..71a43e0
--- /dev/null
+++ b/PersonalCenter/pickerview/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/Sai/Documents/software/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/PersonalCenter/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java b/PersonalCenter/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java
new file mode 100644
index 0000000..542bc94
--- /dev/null
+++ b/PersonalCenter/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java
@@ -0,0 +1,13 @@
+package com.bigkoo.pickerview;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/AndroidManifest.xml b/PersonalCenter/pickerview/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9d55db2
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/OptionsPickerView.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/OptionsPickerView.java
new file mode 100644
index 0000000..eabbf7a
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/OptionsPickerView.java
@@ -0,0 +1,542 @@
+package com.bigkoo.pickerview;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.bigkoo.pickerview.lib.WheelView;
+import com.bigkoo.pickerview.listener.CustomListener;
+import com.bigkoo.pickerview.view.BasePickerView;
+import com.bigkoo.pickerview.view.WheelOptions;
+
+import java.util.List;
+
+/**
+ * 条件选择器
+ * Created by Sai on 15/11/22.
+ */
+public class OptionsPickerView extends BasePickerView implements View.OnClickListener {
+
+ WheelOptions wheelOptions;
+ private int layoutRes;
+ private CustomListener customListener;
+ private Button btnSubmit, btnCancel; //确定、取消按钮
+ private TextView tvTitle;
+ private RelativeLayout rv_top_bar;
+
+ private static final String TAG_SUBMIT = "submit";
+ private static final String TAG_CANCEL = "cancel";
+
+ private OnOptionsSelectListener optionsSelectListener;
+
+ private String Str_Submit;//确定按钮文字
+ private String Str_Cancel;//取消按钮文字
+ private String Str_Title;//标题文字
+
+ private int Color_Submit;//确定按钮颜色
+ private int Color_Cancel;//取消按钮颜色
+ private int Color_Title;//标题颜色
+
+ private int Color_Background_Wheel;//滚轮背景颜色
+ private int Color_Background_Title;//标题背景颜色
+
+ private int Size_Submit_Cancel;//确定取消按钮大小
+ private int Size_Title;//标题文字大小
+ private int Size_Content;//内容文字大小
+
+ private int textColorOut; //分割线以外的文字颜色
+ private int textColorCenter; //分割线之间的文字颜色
+ private int dividerColor; //分割线的颜色
+ private int backgroundId; //显示时的外部背景色颜色,默认是灰色
+ // 条目间距倍数 默认1.6
+ private float lineSpacingMultiplier = 1.6F;
+ private boolean isDialog;//是否是对话框模式
+
+ private boolean cancelable;//是否能取消
+ private boolean linkage;//是否联动
+
+ private boolean isCenterLabel ;//是否只显示中间的label
+
+ private String label1;//单位
+ private String label2;
+ private String label3;
+
+ private boolean cyclic1;//是否循环
+ private boolean cyclic2;
+ private boolean cyclic3;
+
+ private Typeface font;//字体样式
+
+ private int option1;//默认选中项
+ private int option2;
+ private int option3;
+ private WheelView.DividerType dividerType;//分隔线类型
+
+ //构造方法
+ public OptionsPickerView(Builder builder) {
+ super(builder.context);
+ this.optionsSelectListener = builder.optionsSelectListener;
+ this.Str_Submit = builder.Str_Submit;
+ this.Str_Cancel = builder.Str_Cancel;
+ this.Str_Title = builder.Str_Title;
+
+ this.Color_Submit = builder.Color_Submit;
+ this.Color_Cancel = builder.Color_Cancel;
+ this.Color_Title = builder.Color_Title;
+ this.Color_Background_Wheel = builder.Color_Background_Wheel;
+ this.Color_Background_Title = builder.Color_Background_Title;
+
+ this.Size_Submit_Cancel = builder.Size_Submit_Cancel;
+ this.Size_Title = builder.Size_Title;
+ this.Size_Content = builder.Size_Content;
+
+ this.cyclic1 = builder.cyclic1;
+ this.cyclic2 = builder.cyclic2;
+ this.cyclic3 = builder.cyclic3;
+
+ this.cancelable = builder.cancelable;
+ this.linkage = builder.linkage;
+ this.isCenterLabel = builder.isCenterLabel;
+
+ this.label1 = builder.label1;
+ this.label2 = builder.label2;
+ this.label3 = builder.label3;
+
+ this.font = builder.font;
+
+
+ this.option1 = builder.option1;
+ this.option2 = builder.option2;
+ this.option3 = builder.option3;
+ this.textColorCenter = builder.textColorCenter;
+ this.textColorOut = builder.textColorOut;
+ this.dividerColor = builder.dividerColor;
+ this.lineSpacingMultiplier = builder.lineSpacingMultiplier;
+ this.customListener = builder.customListener;
+ this.layoutRes = builder.layoutRes;
+ this.isDialog = builder.isDialog;
+ this.dividerType = builder.dividerType;
+ this.backgroundId = builder.backgroundId;
+ this.decorView = builder.decorView;
+ initView(builder.context);
+ }
+
+
+ //建造器
+ public static class Builder {
+ private int layoutRes = R.layout.pickerview_options;
+ private CustomListener customListener;
+ private Context context;
+ private OnOptionsSelectListener optionsSelectListener;
+
+ private String Str_Submit;//确定按钮文字
+ private String Str_Cancel;//取消按钮文字
+ private String Str_Title;//标题文字
+
+ private int Color_Submit;//确定按钮颜色
+ private int Color_Cancel;//取消按钮颜色
+ private int Color_Title;//标题颜色
+
+ private int Color_Background_Wheel;//滚轮背景颜色
+ private int Color_Background_Title;//标题背景颜色
+
+ private int Size_Submit_Cancel = 17;//确定取消按钮大小
+ private int Size_Title = 18;//标题文字大小
+ private int Size_Content = 18;//内容文字大小
+
+ private boolean cancelable = true;//是否能取消
+ private boolean linkage = true;//是否联动
+ private boolean isCenterLabel = true;//是否只显示中间的label
+
+ private int textColorOut; //分割线以外的文字颜色
+ private int textColorCenter; //分割线之间的文字颜色
+ private int dividerColor; //分割线的颜色
+ private int backgroundId; //显示时的外部背景色颜色,默认是灰色
+ public ViewGroup decorView ;//显示pickerview的根View,默认是activity的根view
+ // 条目间距倍数 默认1.6
+ private float lineSpacingMultiplier = 1.6F;
+ private boolean isDialog;//是否是对话框模式
+
+ private String label1;
+ private String label2;
+ private String label3;
+
+ private boolean cyclic1 = false;//是否循环,默认否
+ private boolean cyclic2 = false;
+ private boolean cyclic3 = false;
+
+ private Typeface font;
+
+ private int option1;//默认选中项
+ private int option2;
+ private int option3;
+
+ private WheelView.DividerType dividerType;//分隔线类型
+
+ //Required
+ public Builder(Context context, OnOptionsSelectListener listener) {
+ this.context = context;
+ this.optionsSelectListener = listener;
+ }
+
+ //Option
+
+ public Builder setSubmitText(String Str_Cancel) {
+ this.Str_Submit = Str_Cancel;
+ return this;
+ }
+
+ public Builder setCancelText(String Str_Cancel) {
+ this.Str_Cancel = Str_Cancel;
+ return this;
+ }
+
+ public Builder setTitleText(String Str_Title) {
+ this.Str_Title = Str_Title;
+ return this;
+ }
+
+ public Builder isDialog(boolean isDialog) {
+ this.isDialog = isDialog;
+ return this;
+ }
+
+ public Builder setSubmitColor(int Color_Submit) {
+ this.Color_Submit = Color_Submit;
+ return this;
+ }
+
+ public Builder setCancelColor(int Color_Cancel) {
+ this.Color_Cancel = Color_Cancel;
+ return this;
+ }
+
+ /**
+ * 显示时的外部背景色颜色,默认是灰色
+ * @param backgroundId
+ * @return
+ */
+ public Builder setBackgroundId(int backgroundId) {
+ this.backgroundId = backgroundId;
+ return this;
+ }
+ /**
+ * 必须是viewgroup
+ * 设置要将pickerview显示到的容器
+ * @param decorView
+ * @return
+ */
+ public Builder setDecorView(ViewGroup decorView) {
+ this.decorView = decorView;
+ return this;
+ }
+
+
+
+
+ public Builder setLayoutRes(int res, CustomListener listener) {
+ this.layoutRes = res;
+ this.customListener = listener;
+ return this;
+ }
+
+ public Builder setBgColor(int Color_Background_Wheel) {
+ this.Color_Background_Wheel = Color_Background_Wheel;
+ return this;
+ }
+
+ public Builder setTitleBgColor(int Color_Background_Title) {
+ this.Color_Background_Title = Color_Background_Title;
+ return this;
+ }
+
+ public Builder setTitleColor(int Color_Title) {
+ this.Color_Title = Color_Title;
+ return this;
+ }
+
+ public Builder setSubCalSize(int Size_Submit_Cancel) {
+ this.Size_Submit_Cancel = Size_Submit_Cancel;
+ return this;
+ }
+
+ public Builder setTitleSize(int Size_Title) {
+ this.Size_Title = Size_Title;
+ return this;
+ }
+
+ public Builder setContentTextSize(int Size_Content) {
+ this.Size_Content = Size_Content;
+ return this;
+ }
+
+
+ public Builder setOutSideCancelable(boolean cancelable) {
+ this.cancelable = cancelable;
+ return this;
+ }
+
+ /**
+ * 此方法已废弃
+ * 不联动的情况下,请调用 setNPicker 方法。
+ * */
+ @Deprecated
+ public Builder setLinkage(boolean linkage) {
+ this.linkage = linkage;
+ return this;
+ }
+
+ public Builder setLabels(String label1, String label2, String label3) {
+ this.label1 = label1;
+ this.label2 = label2;
+ this.label3 = label3;
+ return this;
+ }
+
+ /**
+ * 设置间距倍数,但是只能在1.2-2.0f之间
+ *
+ * @param lineSpacingMultiplier
+ */
+ public Builder setLineSpacingMultiplier(float lineSpacingMultiplier) {
+ this.lineSpacingMultiplier = lineSpacingMultiplier;
+ return this;
+ }
+
+ /**
+ * 设置分割线的颜色
+ *
+ * @param dividerColor
+ */
+ public Builder setDividerColor(int dividerColor) {
+ this.dividerColor = dividerColor;
+ return this;
+ }
+
+ /**
+ * 设置分割线的类型
+ *
+ * @param dividerType
+ */
+ public Builder setDividerType(WheelView.DividerType dividerType) {
+ this.dividerType = dividerType;
+ return this;
+ }
+
+ /**
+ * 设置分割线之间的文字的颜色
+ *
+ * @param textColorCenter
+ */
+ public Builder setTextColorCenter(int textColorCenter) {
+ this.textColorCenter = textColorCenter;
+ return this;
+ }
+
+ /**
+ * 设置分割线以外文字的颜色
+ *
+ * @param textColorOut
+ */
+ public Builder setTextColorOut(int textColorOut) {
+ this.textColorOut = textColorOut;
+ return this;
+ }
+
+ public Builder setTypeface(Typeface font) {
+ this.font = font;
+ return this;
+ }
+
+ public Builder setCyclic(boolean cyclic1, boolean cyclic2, boolean cyclic3) {
+ this.cyclic1 = cyclic1;
+ this.cyclic2 = cyclic2;
+ this.cyclic3 = cyclic3;
+ return this;
+ }
+
+ public Builder setSelectOptions(int option1) {
+ this.option1 = option1;
+ return this;
+ }
+
+ public Builder setSelectOptions(int option1, int option2) {
+ this.option1 = option1;
+ this.option2 = option2;
+ return this;
+ }
+
+ public Builder setSelectOptions(int option1, int option2, int option3) {
+ this.option1 = option1;
+ this.option2 = option2;
+ this.option3 = option3;
+ return this;
+ }
+
+ public Builder isCenterLabel(boolean isCenterLabel) {
+ this.isCenterLabel = isCenterLabel;
+ return this;
+ }
+
+ public OptionsPickerView build() {
+ return new OptionsPickerView(this);
+ }
+ }
+
+
+ private void initView(Context context) {
+ setDialogOutSideCancelable(cancelable);
+ initViews(backgroundId);
+ init();
+ initEvents();
+ if (customListener == null) {
+ LayoutInflater.from(context).inflate(layoutRes, contentContainer);
+
+ //顶部标题
+ tvTitle = (TextView) findViewById(R.id.tvTitle);
+ rv_top_bar = (RelativeLayout)findViewById(R.id.rv_topbar);
+
+ //确定和取消按钮
+ btnSubmit = (Button) findViewById(R.id.btnSubmit);
+ btnCancel = (Button) findViewById(R.id.btnCancel);
+
+ btnSubmit.setTag(TAG_SUBMIT);
+ btnCancel.setTag(TAG_CANCEL);
+ btnSubmit.setOnClickListener(this);
+ btnCancel.setOnClickListener(this);
+
+ //设置文字
+ btnSubmit.setText(TextUtils.isEmpty(Str_Submit) ? context.getResources().getString(R.string.pickerview_submit) : Str_Submit);
+ btnCancel.setText(TextUtils.isEmpty(Str_Cancel) ? context.getResources().getString(R.string.pickerview_cancel) : Str_Cancel);
+ tvTitle.setText(TextUtils.isEmpty(Str_Title) ? "" : Str_Title);//默认为空
+
+ //设置color
+ btnSubmit.setTextColor(Color_Submit == 0 ? pickerview_timebtn_nor : Color_Submit);
+ btnCancel.setTextColor(Color_Cancel == 0 ? pickerview_timebtn_nor : Color_Cancel);
+ tvTitle.setTextColor(Color_Title == 0 ? pickerview_topbar_title : Color_Title);
+ rv_top_bar.setBackgroundColor(Color_Background_Title == 0 ? pickerview_bg_topbar : Color_Background_Title);
+
+ //设置文字大小
+ btnSubmit.setTextSize(Size_Submit_Cancel);
+ btnCancel.setTextSize(Size_Submit_Cancel);
+ tvTitle.setTextSize(Size_Title);
+ tvTitle.setText(Str_Title);
+ } else {
+ customListener.customLayout(LayoutInflater.from(context).inflate(layoutRes, contentContainer));
+ }
+
+ // ----滚轮布局
+ final LinearLayout optionsPicker = (LinearLayout) findViewById(R.id.optionspicker);
+ optionsPicker.setBackgroundColor(Color_Background_Wheel == 0 ? bgColor_default : Color_Background_Wheel);
+
+ wheelOptions = new WheelOptions(optionsPicker, linkage);
+ wheelOptions.setTextContentSize(Size_Content);
+ wheelOptions.setLabels(label1, label2, label3);
+ wheelOptions.setCyclic(cyclic1, cyclic2, cyclic3);
+ wheelOptions.setTypeface(font);
+
+ setOutSideCancelable(cancelable);
+
+ if (tvTitle!= null){
+ tvTitle.setText(Str_Title);
+ }
+
+ wheelOptions.setDividerColor(dividerColor);
+ wheelOptions.setDividerType(dividerType);
+ wheelOptions.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wheelOptions.setTextColorOut(textColorOut);
+ wheelOptions.setTextColorCenter(textColorCenter);
+ wheelOptions.isCenterLabel(isCenterLabel);
+
+ }
+
+
+ /**
+ * 设置默认选中项
+ *
+ * @param option1
+ */
+ public void setSelectOptions(int option1) {
+ this.option1 = option1;
+ SetCurrentItems();
+ }
+
+
+ public void setSelectOptions(int option1, int option2) {
+ this.option1 = option1;
+ this.option2 = option2;
+ SetCurrentItems();
+ }
+
+ public void setSelectOptions(int option1, int option2, int option3) {
+ this.option1 = option1;
+ this.option2 = option2;
+ this.option3 = option3;
+ SetCurrentItems();
+ }
+
+ private void SetCurrentItems() {
+ if(wheelOptions!=null){
+ wheelOptions.setCurrentItems(option1, option2, option3);
+ }
+ }
+
+ public void setPicker(List optionsItems) {
+ this.setPicker(optionsItems, null, null);
+ }
+
+ public void setPicker(List options1Items, List> options2Items) {
+ this.setPicker(options1Items, options2Items, null);
+ }
+
+ public void setPicker(List options1Items,
+ List> options2Items,
+ List>> options3Items) {
+
+ wheelOptions.setPicker(options1Items, options2Items, options3Items);
+ SetCurrentItems();
+ }
+
+
+ //不联动情况下调用
+ public void setNPicker(List options1Items,
+ List options2Items,
+ List options3Items) {
+
+ wheelOptions.setNPicker(options1Items, options2Items, options3Items);
+ SetCurrentItems();
+ }
+
+ @Override
+ public void onClick(View v) {
+ String tag = (String) v.getTag();
+ if (tag.equals(TAG_SUBMIT)) {
+ returnData();
+ }
+ dismiss();
+ }
+
+ //抽离接口回调的方法
+ public void returnData() {
+ if (optionsSelectListener != null) {
+ int[] optionsCurrentItems = wheelOptions.getCurrentItems();
+ optionsSelectListener.onOptionsSelect(optionsCurrentItems[0], optionsCurrentItems[1], optionsCurrentItems[2], clickView);
+ }
+ }
+
+ public interface OnOptionsSelectListener {
+ void onOptionsSelect(int options1, int options2, int options3, View v);
+ }
+
+ @Override
+ public boolean isDialog() {
+ return isDialog;
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/TimePickerView.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/TimePickerView.java
new file mode 100644
index 0000000..5801657
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/TimePickerView.java
@@ -0,0 +1,555 @@
+package com.bigkoo.pickerview;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.bigkoo.pickerview.lib.WheelView;
+import com.bigkoo.pickerview.listener.CustomListener;
+import com.bigkoo.pickerview.view.BasePickerView;
+import com.bigkoo.pickerview.view.WheelTime;
+
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 时间选择器
+ * Created by Sai on 15/11/22.
+ * Updated by XiaoSong on 2017-2-22.
+ */
+public class TimePickerView extends BasePickerView implements View.OnClickListener {
+ private int layoutRes;
+ private CustomListener customListener;
+
+ WheelTime wheelTime; //自定义控件
+ private Button btnSubmit, btnCancel; //确定、取消按钮
+ private TextView tvTitle;//标题
+ private OnTimeSelectListener timeSelectListener;//回调接口
+ private int gravity = Gravity.CENTER;//内容显示位置 默认居中
+ private boolean[] type;// 显示类型
+
+ private String Str_Submit;//确定按钮字符串
+ private String Str_Cancel;//取消按钮字符串
+ private String Str_Title;//标题字符串
+
+ private int Color_Submit;//确定按钮颜色
+ private int Color_Cancel;//取消按钮颜色
+ private int Color_Title;//标题颜色
+
+ private int Color_Background_Wheel;//滚轮背景颜色
+ private int Color_Background_Title;//标题背景颜色
+
+ private int Size_Submit_Cancel;//确定取消按钮大小
+ private int Size_Title;//标题字体大小
+ private int Size_Content;//内容字体大小
+
+ private Calendar date;//当前选中时间
+ private Calendar startDate;//开始时间
+ private Calendar endDate;//终止时间
+ private int startYear;//开始年份
+ private int endYear;//结尾年份
+
+ private boolean cyclic;//是否循环
+ private boolean cancelable;//是否能取消
+ private boolean isCenterLabel;//是否只显示中间的label
+
+ private int textColorOut; //分割线以外的文字颜色
+ private int textColorCenter; //分割线之间的文字颜色
+ private int dividerColor; //分割线的颜色
+ private int backgroundId; //显示时的外部背景色颜色,默认是灰色
+
+ // 条目间距倍数 默认1.6
+ private float lineSpacingMultiplier = 1.6F;
+ private boolean isDialog;//是否是对话框模式
+ private String label_year, label_month, label_day, label_hours, label_mins, label_seconds;
+ private WheelView.DividerType dividerType;//分隔线类型
+
+ private static final String TAG_SUBMIT = "submit";
+ private static final String TAG_CANCEL = "cancel";
+
+ //构造方法
+ public TimePickerView(Builder builder) {
+ super(builder.context);
+ this.timeSelectListener = builder.timeSelectListener;
+ this.gravity = builder.gravity;
+ this.type = builder.type;
+ this.Str_Submit = builder.Str_Submit;
+ this.Str_Cancel = builder.Str_Cancel;
+ this.Str_Title = builder.Str_Title;
+ this.Color_Submit = builder.Color_Submit;
+ this.Color_Cancel = builder.Color_Cancel;
+ this.Color_Title = builder.Color_Title;
+ this.Color_Background_Wheel = builder.Color_Background_Wheel;
+ this.Color_Background_Title = builder.Color_Background_Title;
+ this.Size_Submit_Cancel = builder.Size_Submit_Cancel;
+ this.Size_Title = builder.Size_Title;
+ this.Size_Content = builder.Size_Content;
+ this.startYear = builder.startYear;
+ this.endYear = builder.endYear;
+ this.startDate = builder.startDate;
+ this.endDate = builder.endDate;
+ this.date = builder.date;
+ this.cyclic = builder.cyclic;
+ this.isCenterLabel = builder.isCenterLabel;
+ this.cancelable = builder.cancelable;
+ this.label_year = builder.label_year;
+ this.label_month = builder.label_month;
+ this.label_day = builder.label_day;
+ this.label_hours = builder.label_hours;
+ this.label_mins = builder.label_mins;
+ this.label_seconds = builder.label_seconds;
+ this.textColorCenter = builder.textColorCenter;
+ this.textColorOut = builder.textColorOut;
+ this.dividerColor = builder.dividerColor;
+ this.customListener = builder.customListener;
+ this.layoutRes = builder.layoutRes;
+ this.lineSpacingMultiplier = builder.lineSpacingMultiplier;
+ this.isDialog = builder.isDialog;
+ this.dividerType = builder.dividerType;
+ this.backgroundId = builder.backgroundId;
+ this.decorView = builder.decorView;
+ initView(builder.context);
+ }
+
+
+ //建造器
+ public static class Builder {
+ private int layoutRes = R.layout.pickerview_time;
+ private CustomListener customListener;
+ private Context context;
+ private OnTimeSelectListener timeSelectListener;
+ private boolean[] type = new boolean[]{true, true, true, true, true, true};//显示类型 默认全部显示
+ private int gravity = Gravity.CENTER;//内容显示位置 默认居中
+
+ private String Str_Submit;//确定按钮文字
+ private String Str_Cancel;//取消按钮文字
+ private String Str_Title;//标题文字
+
+ private int Color_Submit;//确定按钮颜色
+ private int Color_Cancel;//取消按钮颜色
+ private int Color_Title;//标题颜色
+
+ private int Color_Background_Wheel;//滚轮背景颜色
+ private int Color_Background_Title;//标题背景颜色
+
+ private int Size_Submit_Cancel = 17;//确定取消按钮大小
+ private int Size_Title = 18;//标题字体大小
+ private int Size_Content = 18;//内容字体大小
+ private Calendar date;//当前选中时间
+ private Calendar startDate;//开始时间
+ private Calendar endDate;//终止时间
+ private int startYear;//开始年份
+ private int endYear;//结尾年份
+
+ private boolean cyclic = false;//是否循环
+ private boolean cancelable = true;//是否能取消
+
+ private boolean isCenterLabel = true ;//是否只显示中间的label
+ public ViewGroup decorView ;//显示pickerview的根View,默认是activity的根view
+
+ private int textColorOut; //分割线以外的文字颜色
+ private int textColorCenter; //分割线之间的文字颜色
+ private int dividerColor; //分割线的颜色
+ private int backgroundId; //显示时的外部背景色颜色,默认是灰色
+ private WheelView.DividerType dividerType;//分隔线类型
+ // 条目间距倍数 默认1.6
+ private float lineSpacingMultiplier = 1.6F;
+
+ private boolean isDialog;//是否是对话框模式
+
+ private String label_year, label_month, label_day, label_hours, label_mins, label_seconds;//单位
+
+ //Required
+ public Builder(Context context, OnTimeSelectListener listener) {
+ this.context = context;
+ this.timeSelectListener = listener;
+ }
+
+ //Option
+ public Builder setType(boolean[] type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder gravity(int gravity) {
+ this.gravity = gravity;
+ return this;
+ }
+
+ public Builder setSubmitText(String Str_Submit) {
+ this.Str_Submit = Str_Submit;
+ return this;
+ }
+
+ public Builder isDialog(boolean isDialog) {
+ this.isDialog = isDialog;
+ return this;
+ }
+
+ public Builder setCancelText(String Str_Cancel) {
+ this.Str_Cancel = Str_Cancel;
+ return this;
+ }
+
+ public Builder setTitleText(String Str_Title) {
+ this.Str_Title = Str_Title;
+ return this;
+ }
+
+ public Builder setSubmitColor(int Color_Submit) {
+ this.Color_Submit = Color_Submit;
+ return this;
+ }
+
+ public Builder setCancelColor(int Color_Cancel) {
+ this.Color_Cancel = Color_Cancel;
+ return this;
+ }
+ /**
+ * 必须是viewgroup
+ * 设置要将pickerview显示到的容器id
+ * @param decorView
+ * @return
+ */
+ public Builder setDecorView(ViewGroup decorView) {
+ this.decorView = decorView;
+ return this;
+ }
+
+ public Builder setBgColor(int Color_Background_Wheel) {
+ this.Color_Background_Wheel = Color_Background_Wheel;
+ return this;
+ }
+
+ public Builder setTitleBgColor(int Color_Background_Title) {
+ this.Color_Background_Title = Color_Background_Title;
+ return this;
+ }
+
+ public Builder setTitleColor(int Color_Title) {
+ this.Color_Title = Color_Title;
+ return this;
+ }
+
+ public Builder setSubCalSize(int Size_Submit_Cancel) {
+ this.Size_Submit_Cancel = Size_Submit_Cancel;
+ return this;
+ }
+
+ public Builder setTitleSize(int Size_Title) {
+ this.Size_Title = Size_Title;
+ return this;
+ }
+
+ public Builder setContentSize(int Size_Content) {
+ this.Size_Content = Size_Content;
+ return this;
+ }
+
+ /**
+ * 因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11
+ *
+ * @param date
+ * @return
+ */
+ public Builder setDate(Calendar date) {
+ this.date = date;
+ return this;
+ }
+
+ public Builder setLayoutRes(int res, CustomListener customListener) {
+ this.layoutRes = res;
+ this.customListener = customListener;
+ return this;
+ }
+
+ public Builder setRange(int startYear, int endYear) {
+ this.startYear = startYear;
+ this.endYear = endYear;
+ return this;
+ }
+
+ /**
+ * 设置起始时间
+ * 因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11
+ *
+ * @return
+ */
+
+ public Builder setRangDate(Calendar startDate, Calendar endDate) {
+ this.startDate = startDate;
+ this.endDate = endDate;
+ return this;
+ }
+
+
+ /**
+ * 设置间距倍数,但是只能在1.2-2.0f之间
+ *
+ * @param lineSpacingMultiplier
+ */
+ public Builder setLineSpacingMultiplier(float lineSpacingMultiplier) {
+ this.lineSpacingMultiplier = lineSpacingMultiplier;
+ return this;
+ }
+
+ /**
+ * 设置分割线的颜色
+ *
+ * @param dividerColor
+ */
+ public Builder setDividerColor(int dividerColor) {
+ this.dividerColor = dividerColor;
+ return this;
+ }
+
+ /**
+ * 设置分割线的类型
+ *
+ * @param dividerType
+ */
+ public Builder setDividerType(WheelView.DividerType dividerType) {
+ this.dividerType = dividerType;
+ return this;
+ }
+
+ /**
+ * //显示时的外部背景色颜色,默认是灰色
+ * @param backgroundId
+ */
+
+ public Builder setBackgroundId(int backgroundId) {
+ this.backgroundId = backgroundId;
+ return this;
+ }
+
+ /**
+ * 设置分割线之间的文字的颜色
+ *
+ * @param textColorCenter
+ */
+ public Builder setTextColorCenter(int textColorCenter) {
+ this.textColorCenter = textColorCenter;
+ return this;
+ }
+
+ /**
+ * 设置分割线以外文字的颜色
+ *
+ * @param textColorOut
+ */
+ public Builder setTextColorOut(int textColorOut) {
+ this.textColorOut = textColorOut;
+ return this;
+ }
+
+ public Builder isCyclic(boolean cyclic) {
+ this.cyclic = cyclic;
+ return this;
+ }
+
+ public Builder setOutSideCancelable(boolean cancelable) {
+ this.cancelable = cancelable;
+ return this;
+ }
+
+ public Builder setLabel(String label_year, String label_month, String label_day, String label_hours, String label_mins, String label_seconds) {
+ this.label_year = label_year;
+ this.label_month = label_month;
+ this.label_day = label_day;
+ this.label_hours = label_hours;
+ this.label_mins = label_mins;
+ this.label_seconds = label_seconds;
+ return this;
+ }
+
+ public Builder isCenterLabel(boolean isCenterLabel) {
+ this.isCenterLabel = isCenterLabel;
+ return this;
+ }
+
+
+ public TimePickerView build() {
+ return new TimePickerView(this);
+ }
+ }
+
+
+ private void initView(Context context) {
+ setDialogOutSideCancelable(cancelable);
+ initViews(backgroundId);
+ init();
+ initEvents();
+ if (customListener == null) {
+ LayoutInflater.from(context).inflate(R.layout.pickerview_time, contentContainer);
+
+ //顶部标题
+ tvTitle = (TextView) findViewById(R.id.tvTitle);
+
+ //确定和取消按钮
+ btnSubmit = (Button) findViewById(R.id.btnSubmit);
+ btnCancel = (Button) findViewById(R.id.btnCancel);
+
+ btnSubmit.setTag(TAG_SUBMIT);
+ btnCancel.setTag(TAG_CANCEL);
+
+ btnSubmit.setOnClickListener(this);
+ btnCancel.setOnClickListener(this);
+
+ //设置文字
+ btnSubmit.setText(TextUtils.isEmpty(Str_Submit) ? context.getResources().getString(R.string.pickerview_submit) : Str_Submit);
+ btnCancel.setText(TextUtils.isEmpty(Str_Cancel) ? context.getResources().getString(R.string.pickerview_cancel) : Str_Cancel);
+ tvTitle.setText(TextUtils.isEmpty(Str_Title) ? "" : Str_Title);//默认为空
+
+ //设置文字颜色
+ btnSubmit.setTextColor(Color_Submit == 0 ? pickerview_timebtn_nor : Color_Submit);
+ btnCancel.setTextColor(Color_Cancel == 0 ? pickerview_timebtn_nor : Color_Cancel);
+ tvTitle.setTextColor(Color_Title == 0 ? pickerview_topbar_title : Color_Title);
+
+ //设置文字大小
+ btnSubmit.setTextSize(Size_Submit_Cancel);
+ btnCancel.setTextSize(Size_Submit_Cancel);
+ tvTitle.setTextSize(Size_Title);
+ RelativeLayout rv_top_bar = (RelativeLayout) findViewById(R.id.rv_topbar);
+ rv_top_bar.setBackgroundColor(Color_Background_Title == 0 ? pickerview_bg_topbar : Color_Background_Title);
+ } else {
+ customListener.customLayout(LayoutInflater.from(context).inflate(layoutRes, contentContainer));
+ }
+ // 时间转轮 自定义控件
+ LinearLayout timePickerView = (LinearLayout) findViewById(R.id.timepicker);
+
+ timePickerView.setBackgroundColor(Color_Background_Wheel == 0 ? bgColor_default : Color_Background_Wheel);
+
+ wheelTime = new WheelTime(timePickerView, type, gravity, Size_Content);
+
+ if (startYear != 0 && endYear != 0 && startYear <= endYear) {
+ setRange();
+ }
+
+ if (startDate != null && endDate != null) {
+ if (startDate.getTimeInMillis() <= endDate.getTimeInMillis()) {
+ setRangDate();
+ }
+ } else if (startDate != null && endDate == null) {
+ setRangDate();
+ } else if (startDate == null && endDate != null) {
+ setRangDate();
+ }
+
+ setTime();
+ wheelTime.setLabels(label_year, label_month, label_day, label_hours, label_mins, label_seconds);
+
+ setOutSideCancelable(cancelable);
+ wheelTime.setCyclic(cyclic);
+ wheelTime.setDividerColor(dividerColor);
+ wheelTime.setDividerType(dividerType);
+ wheelTime.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wheelTime.setTextColorOut(textColorOut);
+ wheelTime.setTextColorCenter(textColorCenter);
+ wheelTime.isCenterLabel(isCenterLabel);
+ }
+
+
+ /**
+ * 设置默认时间
+ */
+ public void setDate(Calendar date) {
+ this.date = date;
+ setTime();
+ }
+
+ /**
+ * 设置可以选择的时间范围, 要在setTime之前调用才有效果
+ */
+ private void setRange() {
+ wheelTime.setStartYear(startYear);
+ wheelTime.setEndYear(endYear);
+
+ }
+
+ /**
+ * 设置可以选择的时间范围, 要在setTime之前调用才有效果
+ */
+ private void setRangDate() {
+ wheelTime.setRangDate(startDate, endDate);
+ //如果设置了时间范围
+ if (startDate != null && endDate != null) {
+ //判断一下默认时间是否设置了,或者是否在起始终止时间范围内
+ if (date == null || date.getTimeInMillis() < startDate.getTimeInMillis()
+ || date.getTimeInMillis() > endDate.getTimeInMillis()) {
+ date = startDate;
+ }
+ } else if (startDate != null) {
+ //没有设置默认选中时间,那就拿开始时间当默认时间
+ date = startDate;
+ } else if (endDate != null) {
+ date = endDate;
+ }
+ }
+
+ /**
+ * 设置选中时间,默认选中当前时间
+ */
+ private void setTime() {
+ int year, month, day, hours, minute, seconds;
+
+ Calendar calendar = Calendar.getInstance();
+ if (date == null) {
+ calendar.setTimeInMillis(System.currentTimeMillis());
+ year = calendar.get(Calendar.YEAR);
+ month = calendar.get(Calendar.MONTH);
+ day = calendar.get(Calendar.DAY_OF_MONTH);
+ hours = calendar.get(Calendar.HOUR_OF_DAY);
+ minute = calendar.get(Calendar.MINUTE);
+ seconds = calendar.get(Calendar.SECOND);
+ } else {
+ year = date.get(Calendar.YEAR);
+ month = date.get(Calendar.MONTH);
+ day = date.get(Calendar.DAY_OF_MONTH);
+ hours = date.get(Calendar.HOUR_OF_DAY);
+ minute = date.get(Calendar.MINUTE);
+ seconds = date.get(Calendar.SECOND);
+ }
+
+
+ wheelTime.setPicker(year, month, day, hours, minute, seconds);
+ }
+
+
+ @Override
+ public void onClick(View v) {
+ String tag = (String) v.getTag();
+ if (tag.equals(TAG_SUBMIT)) {
+ returnData();
+ }
+ dismiss();
+ }
+
+ public void returnData() {
+ if (timeSelectListener != null) {
+ try {
+ Date date = WheelTime.dateFormat.parse(wheelTime.getTime());
+ timeSelectListener.onTimeSelect(date, clickView);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public interface OnTimeSelectListener {
+ void onTimeSelect(Date date, View v);
+ }
+
+ @Override
+ public boolean isDialog() {
+ return isDialog;
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java
new file mode 100644
index 0000000..a195412
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java
@@ -0,0 +1,55 @@
+package com.bigkoo.pickerview.adapter;
+
+import java.util.List;
+
+/**
+ * The simple Array wheel adapter
+ * @param the element type
+ */
+public class ArrayWheelAdapter implements WheelAdapter {
+
+ /** The default items length */
+ public static final int DEFAULT_LENGTH = 4;
+
+ // items
+ private List items;
+ // length
+ private int length;
+
+ /**
+ * Constructor
+ * @param items the items
+ * @param length the max items length
+ */
+ public ArrayWheelAdapter(List items, int length) {
+ this.items = items;
+ this.length = length;
+ }
+
+ /**
+ * Contructor
+ * @param items the items
+ */
+ public ArrayWheelAdapter(List items) {
+ this(items, DEFAULT_LENGTH);
+ }
+
+ @Override
+ public Object getItem(int index) {
+ if (index >= 0 && index < items.size()) {
+ return items.get(index);
+ }
+ return "";
+ }
+
+ @Override
+ public int getItemsCount() {
+ return items.size();
+ }
+
+ @Override
+ public int indexOf(Object o){
+ return items.indexOf(o);
+ }
+
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java
new file mode 100644
index 0000000..501b315
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java
@@ -0,0 +1,59 @@
+package com.bigkoo.pickerview.adapter;
+
+
+/**
+ * Numeric Wheel adapter.
+ */
+public class NumericWheelAdapter implements WheelAdapter {
+
+ /** The default min value */
+ public static final int DEFAULT_MAX_VALUE = 9;
+
+ /** The default max value */
+ private static final int DEFAULT_MIN_VALUE = 0;
+
+ // Values
+ private int minValue;
+ private int maxValue;
+
+ /**
+ * Default constructor
+ */
+ public NumericWheelAdapter() {
+ this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE);
+ }
+
+ /**
+ * Constructor
+ * @param minValue the wheel min value
+ * @param maxValue the wheel max value
+ */
+ public NumericWheelAdapter(int minValue, int maxValue) {
+ this.minValue = minValue;
+ this.maxValue = maxValue;
+ }
+
+ @Override
+ public Object getItem(int index) {
+ if (index >= 0 && index < getItemsCount()) {
+ int value = minValue + index;
+ return value;
+ }
+ return 0;
+ }
+
+ @Override
+ public int getItemsCount() {
+ return maxValue - minValue + 1;
+ }
+
+ @Override
+ public int indexOf(Object o){
+ try {
+ return (int)o - minValue;
+ } catch (Exception e) {
+ return -1;
+ }
+
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/WheelAdapter.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/WheelAdapter.java
new file mode 100644
index 0000000..c07949a
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/adapter/WheelAdapter.java
@@ -0,0 +1,24 @@
+package com.bigkoo.pickerview.adapter;
+
+public interface WheelAdapter {
+ /**
+ * Gets items count
+ * @return the count of wheel items
+ */
+ int getItemsCount();
+
+ /**
+ * Gets a wheel item by index.
+ * @param index the item index
+ * @return the wheel item text or null
+ */
+ T getItem(int index);
+
+ /**
+ * Gets maximum item length. It is used to determine the wheel width.
+ * If -1 is returned there will be used the default wheel width.
+ * @param o
+ * @return the maximum item length or -1
+ */
+ int indexOf(T o);
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/InertiaTimerTask.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/InertiaTimerTask.java
new file mode 100644
index 0000000..a4ce7ea
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/InertiaTimerTask.java
@@ -0,0 +1,68 @@
+package com.bigkoo.pickerview.lib;
+
+import java.util.TimerTask;
+/**
+ * @TODO<滚动惯性的实现>
+ * @author 小嵩
+ */
+final class InertiaTimerTask extends TimerTask {
+
+ float a;
+ final float velocityY;
+ final WheelView loopView;
+
+ InertiaTimerTask(WheelView loopview, float velocityY) {
+ super();
+ loopView = loopview;
+ this.velocityY = velocityY;
+ a = Integer.MAX_VALUE;
+ }
+
+ @Override
+ public final void run() {
+ if (a == Integer.MAX_VALUE) {
+ if (Math.abs(velocityY) > 2000F) {
+ if (velocityY > 0.0F) {
+ a = 2000F;
+ } else {
+ a = -2000F;
+ }
+ } else {
+ a = velocityY;
+ }
+ }
+ if (Math.abs(a) >= 0.0F && Math.abs(a) <= 20F) {
+ loopView.cancelFuture();
+ loopView.handler.sendEmptyMessage(MessageHandler.WHAT_SMOOTH_SCROLL);
+ return;
+ }
+ int i = (int) ((a * 10F) / 1000F);
+ loopView.totalScrollY = loopView.totalScrollY - i;
+ if (!loopView.isLoop) {
+ float itemHeight = loopView.itemHeight;
+ float top = (-loopView.initPosition) * itemHeight;
+ float bottom = (loopView.getItemsCount() - 1 - loopView.initPosition) * itemHeight;
+ if(loopView.totalScrollY - itemHeight*0.25 < top){
+ top = loopView.totalScrollY + i;
+ }
+ else if(loopView.totalScrollY + itemHeight*0.25 > bottom){
+ bottom = loopView.totalScrollY + i;
+ }
+
+ if (loopView.totalScrollY <= top){
+ a = 40F;
+ loopView.totalScrollY = (int)top;
+ } else if (loopView.totalScrollY >= bottom) {
+ loopView.totalScrollY = (int)bottom;
+ a = -40F;
+ }
+ }
+ if (a < 0.0F) {
+ a = a + 20F;
+ } else {
+ a = a - 20F;
+ }
+ loopView.handler.sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW);
+ }
+
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/LoopViewGestureListener.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/LoopViewGestureListener.java
new file mode 100644
index 0000000..eb50e44
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/LoopViewGestureListener.java
@@ -0,0 +1,18 @@
+package com.bigkoo.pickerview.lib;
+
+import android.view.MotionEvent;
+
+final class LoopViewGestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
+
+ final WheelView loopView;
+
+ LoopViewGestureListener(WheelView loopview) {
+ loopView = loopview;
+ }
+
+ @Override
+ public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ loopView.scrollBy(velocityY);
+ return true;
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/MessageHandler.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/MessageHandler.java
new file mode 100644
index 0000000..ce53ea4
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/MessageHandler.java
@@ -0,0 +1,34 @@
+package com.bigkoo.pickerview.lib;
+
+import android.os.Handler;
+import android.os.Message;
+
+final class MessageHandler extends Handler {
+ public static final int WHAT_INVALIDATE_LOOP_VIEW = 1000;
+ public static final int WHAT_SMOOTH_SCROLL = 2000;
+ public static final int WHAT_ITEM_SELECTED = 3000;
+
+ final WheelView loopview;
+
+ MessageHandler(WheelView loopview) {
+ this.loopview = loopview;
+ }
+
+ @Override
+ public final void handleMessage(Message msg) {
+ switch (msg.what) {
+ case WHAT_INVALIDATE_LOOP_VIEW:
+ loopview.invalidate();
+ break;
+
+ case WHAT_SMOOTH_SCROLL:
+ loopview.smoothScroll(WheelView.ACTION.FLING);
+ break;
+
+ case WHAT_ITEM_SELECTED:
+ loopview.onItemSelected();
+ break;
+ }
+ }
+
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/OnItemSelectedRunnable.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/OnItemSelectedRunnable.java
new file mode 100644
index 0000000..678a1b0
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/OnItemSelectedRunnable.java
@@ -0,0 +1,14 @@
+package com.bigkoo.pickerview.lib;
+
+final class OnItemSelectedRunnable implements Runnable {
+ final WheelView loopView;
+
+ OnItemSelectedRunnable(WheelView loopview) {
+ loopView = loopview;
+ }
+
+ @Override
+ public final void run() {
+ loopView.onItemSelectedListener.onItemSelected(loopView.getCurrentItem());
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/SmoothScrollTimerTask.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/SmoothScrollTimerTask.java
new file mode 100644
index 0000000..53d3035
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/SmoothScrollTimerTask.java
@@ -0,0 +1,61 @@
+package com.bigkoo.pickerview.lib;
+
+import java.util.TimerTask;
+
+/**
+ * @TODO<平滑滚动的实现>
+ * @author 小嵩
+ */
+final class SmoothScrollTimerTask extends TimerTask {
+
+ int realTotalOffset;
+ int realOffset;
+ int offset;
+ final WheelView loopView;
+
+ SmoothScrollTimerTask(WheelView loopview, int offset) {
+ this.loopView = loopview;
+ this.offset = offset;
+ realTotalOffset = Integer.MAX_VALUE;
+ realOffset = 0;
+ }
+
+ @Override
+ public final void run() {
+ if (realTotalOffset == Integer.MAX_VALUE) {
+ realTotalOffset = offset;
+ }
+ //把要滚动的范围细分成10小份,按10小份单位来重绘
+ realOffset = (int) ((float) realTotalOffset * 0.1F);
+
+ if (realOffset == 0) {
+ if (realTotalOffset < 0) {
+ realOffset = -1;
+ } else {
+ realOffset = 1;
+ }
+ }
+
+ if (Math.abs(realTotalOffset) <= 1) {
+ loopView.cancelFuture();
+ loopView.handler.sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED);
+ } else {
+ loopView.totalScrollY = loopView.totalScrollY + realOffset;
+
+ //这里如果不是循环模式,则点击空白位置需要回滚,不然就会出现选到-1 item的 情况
+ if (!loopView.isLoop) {
+ float itemHeight = loopView.itemHeight;
+ float top = (float) (-loopView.initPosition) * itemHeight;
+ float bottom = (float) (loopView.getItemsCount() - 1 - loopView.initPosition) * itemHeight;
+ if (loopView.totalScrollY <= top||loopView.totalScrollY >= bottom) {
+ loopView.totalScrollY = loopView.totalScrollY - realOffset;
+ loopView.cancelFuture();
+ loopView.handler.sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED);
+ return;
+ }
+ }
+ loopView.handler.sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW);
+ realTotalOffset = realTotalOffset - realOffset;
+ }
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/WheelView.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/WheelView.java
new file mode 100644
index 0000000..3321e6f
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/lib/WheelView.java
@@ -0,0 +1,779 @@
+package com.bigkoo.pickerview.lib;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.bigkoo.pickerview.R;
+import com.bigkoo.pickerview.adapter.WheelAdapter;
+import com.bigkoo.pickerview.listener.OnItemSelectedListener;
+import com.bigkoo.pickerview.model.IPickerViewData;
+
+import java.util.Locale;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 3d滚轮控件
+ */
+public class WheelView extends View {
+
+ public enum ACTION { // 点击,滑翔(滑到尽头),拖拽事件
+ CLICK, FLING, DAGGLE
+ }
+ public enum DividerType { // 分隔线类型
+ FILL, WRAP
+ }
+
+ private DividerType dividerType;//分隔线类型
+
+ Context context;
+
+ Handler handler;
+ private GestureDetector gestureDetector;
+ OnItemSelectedListener onItemSelectedListener;
+
+ private boolean isOptions = false;
+ private boolean isCenterLabel = true;
+
+ // Timer mTimer;
+ ScheduledExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor();
+ private ScheduledFuture> mFuture;
+
+ Paint paintOuterText;
+ Paint paintCenterText;
+ Paint paintIndicator;
+
+ WheelAdapter adapter;
+
+ private String label;//附加单位
+ int textSize;//选项的文字大小
+ int maxTextWidth;
+ int maxTextHeight;
+ float itemHeight;//每行高度
+
+ Typeface typeface = Typeface.MONOSPACE;//字体样式,默认是等宽字体
+
+ int textColorOut = 0xFFa8a8a8;
+ int textColorCenter = 0xFF2a2a2a;
+ int dividerColor = 0xFFd5d5d5;
+
+ // 条目间距倍数
+ float lineSpacingMultiplier = 1.6F;
+ boolean isLoop;
+
+ // 第一条线Y坐标值
+ float firstLineY;
+ //第二条线Y坐标
+ float secondLineY;
+ //中间label绘制的Y坐标
+ float centerY;
+
+ //滚动总高度y值
+ float totalScrollY;
+ //初始化默认选中项
+ int initPosition;
+ //选中的Item是第几个
+ private int selectedItem;
+ int preCurrentIndex;
+ //滚动偏移值,用于记录滚动了多少个item
+ int change;
+
+ // 绘制几个条目,实际上第一项和最后一项Y轴压缩成0%了,所以可见的数目实际为9
+ int itemsVisible = 11;
+
+ int measuredHeight;// WheelView 控件高度
+ int measuredWidth;// WheelView 控件宽度
+
+ // 半圆周长
+ int halfCircumference;
+ // 半径
+ int radius;
+
+ private int mOffset = 0;
+ private float previousY = 0;
+ long startTime = 0;
+
+ // 修改这个值可以改变滑行速度
+ private static final int VELOCITYFLING = 5;
+ int widthMeasureSpec;
+
+ private int mGravity = Gravity.CENTER;
+ private int drawCenterContentStart = 0;//中间选中文字开始绘制位置
+ private int drawOutContentStart = 0;//非中间文字开始绘制位置
+ private static final float SCALECONTENT = 0.8F;//非中间文字则用此控制高度,压扁形成3d错觉
+ private float CENTERCONTENTOFFSET ;//偏移量
+
+ public WheelView(Context context) {
+ this(context, null);
+ }
+
+ public WheelView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ /* textColorOut = getResources().getColor(R.color.pickerview_wheelview_textcolor_out);
+ textColorCenter =getResources().getColor(R.color.pickerview_wheelview_textcolor_center);
+ dividerColor = getResources().getColor(R.color.pickerview_wheelview_textcolor_out);*/
+
+ textSize = getResources().getDimensionPixelSize(R.dimen.pickerview_textsize);//默认大小
+
+ DisplayMetrics dm = getResources().getDisplayMetrics();
+ float density = dm.density; // 屏幕密度(0.75/1.0/1.5/2.0/3.0)
+
+ if (density<1){//根据密度不同进行适配
+ CENTERCONTENTOFFSET=2.4F;
+ }else if (1<=density&&density<2){
+ CENTERCONTENTOFFSET = 3.6F;
+ }else if (1<=density&&density<2){
+ CENTERCONTENTOFFSET = 4.5F;
+ }else if (2<=density&&density<3){
+ CENTERCONTENTOFFSET = 6.0F;
+ }else if (density>=3){
+ CENTERCONTENTOFFSET= density * 2.5F;
+ }
+
+
+ if (attrs != null) {
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.pickerview, 0, 0);
+ mGravity = a.getInt(R.styleable.pickerview_pickerview_gravity, Gravity.CENTER);
+ textColorOut = a.getColor(R.styleable.pickerview_pickerview_textColorOut, textColorOut);
+ textColorCenter = a.getColor(R.styleable.pickerview_pickerview_textColorCenter, textColorCenter);
+ dividerColor = a.getColor(R.styleable.pickerview_pickerview_dividerColor, dividerColor);
+ textSize = a.getDimensionPixelOffset(R.styleable.pickerview_pickerview_textSize, textSize);
+ lineSpacingMultiplier = a.getFloat(R.styleable.pickerview_pickerview_lineSpacingMultiplier, lineSpacingMultiplier);
+ a.recycle();//回收内存
+ }
+
+ judgeLineSpae();
+
+ initLoopView(context);
+ }
+
+ /**
+ * 判断间距是否在1.0-2.0之间
+ */
+ private void judgeLineSpae() {
+ if (lineSpacingMultiplier < 1.2f) {
+ lineSpacingMultiplier = 1.2f;
+ } else if (lineSpacingMultiplier > 2.0f) {
+ lineSpacingMultiplier = 2.0f;
+ }
+ }
+
+ private void initLoopView(Context context) {
+ this.context = context;
+ handler = new MessageHandler(this);
+ gestureDetector = new GestureDetector(context, new LoopViewGestureListener(this));
+ gestureDetector.setIsLongpressEnabled(false);
+
+ isLoop = true;
+
+ totalScrollY = 0;
+ initPosition = -1;
+
+ initPaints();
+
+ }
+
+ private void initPaints() {
+ paintOuterText = new Paint();
+ paintOuterText.setColor(textColorOut);
+ paintOuterText.setAntiAlias(true);
+ paintOuterText.setTypeface(typeface);
+ paintOuterText.setTextSize(textSize);
+
+ paintCenterText = new Paint();
+ paintCenterText.setColor(textColorCenter);
+ paintCenterText.setAntiAlias(true);
+ paintCenterText.setTextScaleX(1.1F);
+ paintCenterText.setTypeface(typeface);
+ paintCenterText.setTextSize(textSize);
+
+
+ paintIndicator = new Paint();
+ paintIndicator.setColor(dividerColor);
+ paintIndicator.setAntiAlias(true);
+
+ if (android.os.Build.VERSION.SDK_INT >= 11) {
+ setLayerType(LAYER_TYPE_SOFTWARE, null);
+ }
+ }
+
+ private void remeasure() {//重新测量
+ if (adapter == null) {
+ return;
+ }
+
+ measureTextWidthHeight();
+
+ //半圆的周长 = item高度乘以item数目-1
+ halfCircumference = (int) (itemHeight * (itemsVisible - 1));
+ //整个圆的周长除以PI得到直径,这个直径用作控件的总高度
+ measuredHeight = (int) ((halfCircumference * 2) / Math.PI);
+ //求出半径
+ radius = (int) (halfCircumference / Math.PI);
+ //控件宽度,这里支持weight
+ measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
+ //计算两条横线 和 选中项画笔的基线Y位置
+ firstLineY = (measuredHeight - itemHeight) / 2.0F;
+ secondLineY = (measuredHeight + itemHeight) / 2.0F;
+ centerY = secondLineY - (itemHeight-maxTextHeight)/2.0f - CENTERCONTENTOFFSET;
+
+ //初始化显示的item的position
+ if (initPosition == -1) {
+ if (isLoop) {
+ initPosition = (adapter.getItemsCount() + 1) / 2;
+ } else {
+ initPosition = 0;
+ }
+ }
+ preCurrentIndex = initPosition;
+ }
+
+ /**
+ * 计算最大length的Text的宽高度
+ */
+ private void measureTextWidthHeight() {
+ Rect rect = new Rect();
+ for (int i = 0; i < adapter.getItemsCount(); i++) {
+ String s1 = getContentText(adapter.getItem(i));
+ paintCenterText.getTextBounds(s1, 0, s1.length(), rect);
+
+ int textWidth = rect.width();
+
+ if (textWidth > maxTextWidth) {
+ maxTextWidth = textWidth;
+ }
+ paintCenterText.getTextBounds("\u661F\u671F", 0, 2, rect); // 星期的字符编码(以它为标准高度)
+
+ maxTextHeight = rect.height() + 2;
+
+ }
+ itemHeight = lineSpacingMultiplier * maxTextHeight;
+ }
+
+ void smoothScroll(ACTION action) {//平滑滚动的实现
+ cancelFuture();
+ if (action == ACTION.FLING || action == ACTION.DAGGLE) {
+ mOffset = (int) ((totalScrollY % itemHeight + itemHeight) % itemHeight);
+ if ((float) mOffset > itemHeight / 2.0F) {//如果超过Item高度的一半,滚动到下一个Item去
+ mOffset = (int) (itemHeight - (float) mOffset);
+ } else {
+ mOffset = -mOffset;
+ }
+ }
+ //停止的时候,位置有偏移,不是全部都能正确停止到中间位置的,这里把文字位置挪回中间去
+ mFuture = mExecutor.scheduleWithFixedDelay(new SmoothScrollTimerTask(this, mOffset), 0, 10, TimeUnit.MILLISECONDS);
+ }
+
+ protected final void scrollBy(float velocityY) {//滚动惯性的实现
+ cancelFuture();
+ mFuture = mExecutor.scheduleWithFixedDelay(new InertiaTimerTask(this, velocityY), 0, VELOCITYFLING, TimeUnit.MILLISECONDS);
+ }
+
+ public void cancelFuture() {
+ if (mFuture != null && !mFuture.isCancelled()) {
+ mFuture.cancel(true);
+ mFuture = null;
+ }
+ }
+
+ /**
+ * 设置是否循环滚动
+ *
+ * @param cyclic 是否循环
+ */
+ public final void setCyclic(boolean cyclic) {
+ isLoop = cyclic;
+ }
+
+ public final void setTypeface(Typeface font) {
+ typeface = font;
+ paintOuterText.setTypeface(typeface);
+ paintCenterText.setTypeface(typeface);
+ }
+
+ public final void setTextSize(float size) {
+ if (size > 0.0F ) {
+ textSize = (int) (context.getResources().getDisplayMetrics().density * size);
+ paintOuterText.setTextSize(textSize);
+ paintCenterText.setTextSize(textSize);
+ }
+ }
+
+ public final void setCurrentItem(int currentItem) {
+ //不添加这句,当这个wheelview不可见时,默认都是0,会导致获取到的时间错误
+ this.selectedItem = currentItem;
+ this.initPosition = currentItem;
+ totalScrollY = 0;//回归顶部,不然重设setCurrentItem的话位置会偏移的,就会显示出不对位置的数据
+ invalidate();
+ }
+
+ public final void setOnItemSelectedListener(OnItemSelectedListener OnItemSelectedListener) {
+ this.onItemSelectedListener = OnItemSelectedListener;
+ }
+
+ public final void setAdapter(WheelAdapter adapter) {
+ this.adapter = adapter;
+ remeasure();
+ invalidate();
+ }
+
+ public final WheelAdapter getAdapter() {
+ return adapter;
+ }
+
+ public final int getCurrentItem() {
+ return selectedItem;
+ }
+
+ protected final void onItemSelected() {
+ if (onItemSelectedListener != null) {
+ postDelayed(new OnItemSelectedRunnable(this), 200L);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (adapter == null) {
+ return;
+ }
+ //initPosition越界会造成preCurrentIndex的值不正确
+ if(initPosition<0)
+ {
+ initPosition = 0;
+ }
+ if(initPosition>=adapter.getItemsCount())
+ {
+ initPosition = adapter.getItemsCount()-1;
+ }
+ //可见的item数组
+ Object visibles[] = new Object[itemsVisible];
+ //滚动的Y值高度除去每行Item的高度,得到滚动了多少个item,即change数
+ change = (int)(totalScrollY / itemHeight);
+
+ try {
+ //滚动中实际的预选中的item(即经过了中间位置的item) = 滑动前的位置 + 滑动相对位置
+ preCurrentIndex = initPosition + change % adapter.getItemsCount();
+
+ } catch (ArithmeticException e) {
+ Log.e("WheelView","出错了!adapter.getItemsCount() == 0,联动数据不匹配");
+ }
+ if (!isLoop) {//不循环的情况
+ if (preCurrentIndex < 0) {
+ preCurrentIndex = 0;
+ }
+ if (preCurrentIndex > adapter.getItemsCount() - 1) {
+ preCurrentIndex = adapter.getItemsCount() - 1;
+ }
+ } else {//循环
+ if (preCurrentIndex < 0) {//举个例子:如果总数是5,preCurrentIndex = -1,那么preCurrentIndex按循环来说,其实是0的上面,也就是4的位置
+ preCurrentIndex = adapter.getItemsCount() + preCurrentIndex;
+ }
+ if (preCurrentIndex > adapter.getItemsCount() - 1) {//同理上面,自己脑补一下
+ preCurrentIndex = preCurrentIndex - adapter.getItemsCount();
+ }
+ }
+ //跟滚动流畅度有关,总滑动距离与每个item高度取余,即并不是一格格的滚动,每个item不一定滚到对应Rect里的,这个item对应格子的偏移值
+ float itemHeightOffset = (totalScrollY % itemHeight);
+
+ // 设置数组中每个元素的值
+ int counter = 0;
+ while (counter < itemsVisible) {
+ int index = preCurrentIndex - (itemsVisible / 2 - counter);//索引值,即当前在控件中间的item看作数据源的中间,计算出相对源数据源的index值
+ //判断是否循环,如果是循环数据源也使用相对循环的position获取对应的item值,如果不是循环则超出数据源范围使用""空白字符串填充,在界面上形成空白无数据的item项
+ if (isLoop) {
+ index = getLoopMappingIndex(index);
+ visibles[counter] = adapter.getItem(index);
+ } else if (index < 0) {
+ visibles[counter] = "";
+ } else if (index > adapter.getItemsCount() - 1) {
+ visibles[counter] = "";
+ } else {
+ visibles[counter] = adapter.getItem(index);
+ }
+
+ counter++;
+
+ }
+
+ //绘制中间两条横线
+ if (dividerType == DividerType.WRAP){//横线长度仅包裹内容
+ float startX;
+ float endX;
+
+ if (TextUtils.isEmpty(label)){//隐藏Label的情况
+ startX = (measuredWidth - maxTextWidth)/2 - 12;
+ }else {
+ startX = (measuredWidth - maxTextWidth)/4 - 12;
+ }
+
+ if (startX<=0){//如果超过了WheelView的边缘
+ startX = 10;
+ }
+ endX = measuredWidth - startX;
+ canvas.drawLine(startX, firstLineY, endX, firstLineY, paintIndicator);
+ canvas.drawLine(startX, secondLineY, endX, secondLineY, paintIndicator);
+ }else {
+ canvas.drawLine(0.0F, firstLineY, measuredWidth, firstLineY, paintIndicator);
+ canvas.drawLine(0.0F, secondLineY, measuredWidth, secondLineY, paintIndicator);
+ }
+
+ //只显示选中项Label文字的模式,并且Label文字不为空,则进行绘制
+ if (!TextUtils.isEmpty(label)&& isCenterLabel) {
+ //绘制文字,靠右并留出空隙
+ int drawRightContentStart = measuredWidth - getTextWidth(paintCenterText, label);
+ canvas.drawText(label, drawRightContentStart - CENTERCONTENTOFFSET, centerY, paintCenterText);
+ }
+
+ counter = 0;
+ while (counter < itemsVisible) {
+ canvas.save();
+ // 弧长 L = itemHeight * counter - itemHeightOffset
+ // 求弧度 α = L / r (弧长/半径) [0,π]
+ double radian = ((itemHeight * counter - itemHeightOffset)) / radius;
+ // 弧度转换成角度(把半圆以Y轴为轴心向右转90度,使其处于第一象限及第四象限
+ // angle [-90°,90°]
+ float angle = (float) (90D - (radian / Math.PI) * 180D);//item第一项,从90度开始,逐渐递减到 -90度
+
+ // 计算取值可能有细微偏差,保证负90°到90°以外的不绘制
+ if (angle >= 90F || angle <= -90F) {
+ canvas.restore();
+ } else {
+ //获取内容文字
+ String contentText;
+
+ //如果是label每项都显示的模式,并且item内容不为空、label 也不为空
+ if(!isCenterLabel&&!TextUtils.isEmpty(label) &&!TextUtils.isEmpty(getContentText(visibles[counter]))){
+ contentText = getContentText(visibles[counter])+label;
+ }else {
+ contentText = getContentText(visibles[counter]);
+ }
+
+ reMeasureTextSize(contentText);
+ //计算开始绘制的位置
+ measuredCenterContentStart(contentText);
+ measuredOutContentStart(contentText);
+ float translateY = (float) (radius - Math.cos(radian) * radius - (Math.sin(radian) * maxTextHeight) / 2D);
+ //根据Math.sin(radian)来更改canvas坐标系原点,然后缩放画布,使得文字高度进行缩放,形成弧形3d视觉差
+ canvas.translate(0.0F, translateY);
+ canvas.scale(1.0F, (float) Math.sin(radian));
+ if (translateY <= firstLineY && maxTextHeight + translateY >= firstLineY) {
+ // 条目经过第一条线
+ canvas.save();
+ canvas.clipRect(0, 0, measuredWidth, firstLineY - translateY);
+ canvas.scale(1.0F, (float) Math.sin(radian) * SCALECONTENT);
+ canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText);
+ canvas.restore();
+ canvas.save();
+ canvas.clipRect(0, firstLineY - translateY, measuredWidth, (int) (itemHeight));
+ canvas.scale(1.0F, (float) Math.sin(radian) * 1.0F);
+ canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTERCONTENTOFFSET, paintCenterText);
+ canvas.restore();
+ } else if (translateY <= secondLineY && maxTextHeight + translateY >= secondLineY) {
+ // 条目经过第二条线
+ canvas.save();
+ canvas.clipRect(0, 0, measuredWidth, secondLineY - translateY);
+ canvas.scale(1.0F, (float) Math.sin(radian) * 1.0F);
+ canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTERCONTENTOFFSET, paintCenterText);
+ canvas.restore();
+ canvas.save();
+ canvas.clipRect(0, secondLineY - translateY, measuredWidth, (int) (itemHeight));
+ canvas.scale(1.0F, (float) Math.sin(radian) * SCALECONTENT);
+ canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText);
+ canvas.restore();
+ } else if (translateY >= firstLineY && maxTextHeight + translateY <= secondLineY) {
+ // 中间条目
+ //canvas.clipRect(0, 0, measuredWidth, maxTextHeight);
+ //让文字居中
+ float Y = maxTextHeight - CENTERCONTENTOFFSET;//因为圆弧角换算的向下取值,导致角度稍微有点偏差,加上画笔的基线会偏上,因此需要偏移量修正一下
+ canvas.drawText(contentText, drawCenterContentStart, Y, paintCenterText);
+
+ int preSelectedItem = adapter.indexOf(visibles[counter]);
+
+ selectedItem = preSelectedItem;
+
+ } else {
+ // 其他条目
+ canvas.save();
+ canvas.clipRect(0, 0, measuredWidth, (int) (itemHeight));
+ canvas.scale(1.0F, (float) Math.sin(radian) * SCALECONTENT);
+ canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText);
+ canvas.restore();
+ }
+ canvas.restore();
+ paintCenterText.setTextSize(textSize);
+ }
+ counter++;
+ }
+ }
+
+ /**
+ * 根据文字的长度 重新设置文字的大小 让其能完全显示
+ * @param contentText
+ */
+ private void reMeasureTextSize(String contentText) {
+ Rect rect = new Rect();
+ paintCenterText.getTextBounds(contentText, 0, contentText.length(), rect);
+ int width = rect.width();
+ int size = textSize;
+ while (width > measuredWidth) {
+ size--;
+ //设置2条横线中间的文字大小
+ paintCenterText.setTextSize(size);
+ paintCenterText.getTextBounds(contentText, 0, contentText.length(), rect);
+ width = rect.width();
+ }
+ //设置2条横线外面的文字大小
+ paintOuterText.setTextSize(size);
+ }
+
+
+ //递归计算出对应的index
+ private int getLoopMappingIndex(int index) {
+ if (index < 0) {
+ index = index + adapter.getItemsCount();
+ index = getLoopMappingIndex(index);
+ } else if (index > adapter.getItemsCount() - 1) {
+ index = index - adapter.getItemsCount();
+ index = getLoopMappingIndex(index);
+ }
+ return index;
+ }
+
+ /**
+ * 根据传进来的对象获取getPickerViewText()方法,来获取需要显示的值
+ *
+ * @param item 数据源的item
+ * @return 对应显示的字符串
+ */
+ private String getContentText(Object item) {
+ if (item == null) {
+ return "";
+ } else if (item instanceof IPickerViewData) {
+ return ((IPickerViewData) item).getPickerViewText();
+ } else if (item instanceof Integer) {
+ //如果为整形则最少保留两位数.
+ return String.format(Locale.getDefault(), "%02d", (int) item);
+ }
+ return item.toString();
+ }
+
+ private void measuredCenterContentStart(String content) {
+ Rect rect = new Rect();
+ paintCenterText.getTextBounds(content, 0, content.length(), rect);
+ switch (mGravity) {
+ case Gravity.CENTER://显示内容居中
+ if (isOptions||label == null|| label.equals("")||!isCenterLabel) {
+ drawCenterContentStart = (int) ((measuredWidth - rect.width()) * 0.5);
+ } else {//只显示中间label时,时间选择器内容偏左一点,留出空间绘制单位标签
+ drawCenterContentStart = (int) ((measuredWidth - rect.width()) * 0.25);
+ }
+ break;
+ case Gravity.LEFT:
+ drawCenterContentStart = 0;
+ break;
+ case Gravity.RIGHT://添加偏移量
+ drawCenterContentStart = measuredWidth - rect.width() -(int)CENTERCONTENTOFFSET;
+ break;
+ }
+ }
+
+ private void measuredOutContentStart(String content) {
+ Rect rect = new Rect();
+ paintOuterText.getTextBounds(content, 0, content.length(), rect);
+ switch (mGravity) {
+ case Gravity.CENTER:
+ if (isOptions||label == null|| label.equals("")||!isCenterLabel) {
+ drawOutContentStart = (int) ((measuredWidth - rect.width()) * 0.5);
+ } else {//只显示中间label时,时间选择器内容偏左一点,留出空间绘制单位标签
+ drawOutContentStart = (int) ((measuredWidth - rect.width()) * 0.25);
+ }
+ break;
+ case Gravity.LEFT:
+ drawOutContentStart = 0;
+ break;
+ case Gravity.RIGHT:
+ drawOutContentStart = measuredWidth - rect.width()-(int)CENTERCONTENTOFFSET;
+ break;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ this.widthMeasureSpec = widthMeasureSpec;
+ remeasure();
+ setMeasuredDimension(measuredWidth, measuredHeight);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ boolean eventConsumed = gestureDetector.onTouchEvent(event);
+ switch (event.getAction()) {
+ //按下
+ case MotionEvent.ACTION_DOWN:
+ startTime = System.currentTimeMillis();
+ cancelFuture();
+ previousY = event.getRawY();
+ break;
+ //滑动中
+ case MotionEvent.ACTION_MOVE:
+
+ float dy = previousY - event.getRawY();
+ previousY = event.getRawY();
+ totalScrollY = totalScrollY + dy;
+
+ // 边界处理。
+ if (!isLoop) {
+ float top = -initPosition * itemHeight;
+ float bottom = (adapter.getItemsCount() - 1 - initPosition) * itemHeight;
+
+
+ if (totalScrollY - itemHeight * 0.25 < top) {
+ top = totalScrollY - dy;
+ } else if (totalScrollY + itemHeight * 0.25 > bottom) {
+ bottom = totalScrollY - dy;
+ }
+
+ if (totalScrollY < top) {
+ totalScrollY = (int) top;
+ } else if (totalScrollY > bottom) {
+ totalScrollY = (int) bottom;
+ }
+ }
+ break;
+ //完成滑动,手指离开屏幕
+ case MotionEvent.ACTION_UP:
+
+ default:
+ if (!eventConsumed) {//未消费掉事件
+
+ /**
+ * TODO<关于弧长的计算>
+ *
+ * 弧长公式: L = α*R
+ * 反余弦公式:arccos(cosα) = α
+ * 由于之前是有顺时针偏移90度,
+ * 所以实际弧度范围α2的值 :α2 = π/2-α (α=[0,π] α2 = [-π/2,π/2])
+ * 根据正弦余弦转换公式 cosα = sin(π/2-α)
+ * 代入,得: cosα = sin(π/2-α) = sinα2 = (R - y) / R
+ * 所以弧长 L = arccos(cosα)*R = arccos((R - y) / R)*R
+ */
+
+ float y = event.getY();
+ double L = Math.acos((radius - y) / radius) * radius;
+ //item0 有一半是在不可见区域,所以需要加上 itemHeight / 2
+ int circlePosition = (int) ((L + itemHeight / 2) / itemHeight);
+ float extraOffset = (totalScrollY % itemHeight + itemHeight) % itemHeight;
+ //已滑动的弧长值
+ mOffset = (int) ((circlePosition - itemsVisible / 2) * itemHeight - extraOffset);
+
+ if ((System.currentTimeMillis() - startTime) > 120) {
+ // 处理拖拽事件
+ smoothScroll(ACTION.DAGGLE);
+ } else {
+ // 处理条目点击事件
+ smoothScroll(ACTION.CLICK);
+ }
+ }
+ break;
+ }
+
+ invalidate();
+ return true;
+ }
+
+ /**
+ * 获取Item个数
+ *
+ * @return item个数
+ */
+ public int getItemsCount() {
+ return adapter != null ? adapter.getItemsCount() : 0;
+ }
+
+ /**
+ * 附加在右边的单位字符串
+ *
+ * @param label 单位
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public void isCenterLabel(Boolean isCenterLabel) {
+ this.isCenterLabel = isCenterLabel;
+ }
+
+ public void setGravity(int gravity) {
+ this.mGravity = gravity;
+ }
+
+ public int getTextWidth(Paint paint, String str) {//计算文字宽度
+ int iRet = 0;
+ if (str != null && str.length() > 0) {
+ int len = str.length();
+ float[] widths = new float[len];
+ paint.getTextWidths(str, widths);
+ for (int j = 0; j < len; j++) {
+ iRet += (int) Math.ceil(widths[j]);
+ }
+ }
+ return iRet;
+ }
+
+ public void setIsOptions(boolean options) {
+ isOptions = options;
+ }
+
+
+ public void setTextColorOut(int textColorOut) {
+ if (textColorOut != 0) {
+ this.textColorOut = textColorOut;
+ paintOuterText.setColor(this.textColorOut);
+ }
+ }
+
+ public void setTextColorCenter(int textColorCenter) {
+ if (textColorCenter != 0) {
+
+ this.textColorCenter = textColorCenter;
+ paintCenterText.setColor(this.textColorCenter);
+ }
+ }
+
+ public void setDividerColor(int dividerColor) {
+ if (dividerColor != 0) {
+ this.dividerColor = dividerColor;
+ paintIndicator.setColor(this.dividerColor);
+ }
+ }
+ public void setDividerType(DividerType dividerType) {
+ this.dividerType = dividerType;
+ }
+
+ public void setLineSpacingMultiplier(float lineSpacingMultiplier) {
+ if (lineSpacingMultiplier != 0) {
+
+
+ this.lineSpacingMultiplier = lineSpacingMultiplier;
+ judgeLineSpae();
+
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java
new file mode 100644
index 0000000..2c3bb26
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/CustomListener.java
@@ -0,0 +1,13 @@
+package com.bigkoo.pickerview.listener;
+
+import android.view.View;
+
+/**
+ * Created by KyuYi on 2017/3/2.
+ * E-Mail:kyu_yi@sina.com
+ * 功能:
+ */
+
+public interface CustomListener {
+ void customLayout(View v);
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java
new file mode 100644
index 0000000..a56a1c5
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java
@@ -0,0 +1,8 @@
+package com.bigkoo.pickerview.listener;
+
+/**
+ * Created by Sai on 15/8/9.
+ */
+public interface OnDismissListener {
+ public void onDismiss(Object o);
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnItemSelectedListener.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnItemSelectedListener.java
new file mode 100644
index 0000000..65daa28
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnItemSelectedListener.java
@@ -0,0 +1,6 @@
+package com.bigkoo.pickerview.listener;
+
+
+public interface OnItemSelectedListener {
+ void onItemSelected(int index);
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/model/IPickerViewData.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/model/IPickerViewData.java
new file mode 100644
index 0000000..9e79c78
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/model/IPickerViewData.java
@@ -0,0 +1,8 @@
+package com.bigkoo.pickerview.model;
+
+/**
+ * Created by Sai on 2016/7/13.
+ */
+public interface IPickerViewData {
+ String getPickerViewText();
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java
new file mode 100644
index 0000000..f10df16
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java
@@ -0,0 +1,26 @@
+package com.bigkoo.pickerview.utils;
+
+import android.view.Gravity;
+
+import com.bigkoo.pickerview.R;
+
+/**
+ * Created by Sai on 15/8/9.
+ */
+public class PickerViewAnimateUtil {
+ private static final int INVALID = -1;
+ /**
+ * Get default animation resource when not defined by the user
+ *
+ * @param gravity the gravity of the dialog
+ * @param isInAnimation determine if is in or out animation. true when is is
+ * @return the id of the animation resource
+ */
+ public static int getAnimationResource(int gravity, boolean isInAnimation) {
+ switch (gravity) {
+ case Gravity.BOTTOM:
+ return isInAnimation ? R.anim.pickerview_slide_in_bottom : R.anim.pickerview_slide_out_bottom;
+ }
+ return INVALID;
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java
new file mode 100644
index 0000000..3af05db
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java
@@ -0,0 +1,358 @@
+package com.bigkoo.pickerview.view;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+
+import com.bigkoo.pickerview.R;
+import com.bigkoo.pickerview.listener.OnDismissListener;
+import com.bigkoo.pickerview.utils.PickerViewAnimateUtil;
+
+/**
+ * Created by Sai on 15/11/22.
+ * 精仿iOSPickerViewController控件
+ */
+public class BasePickerView {
+ private final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM
+ );
+
+ private Context context;
+ protected ViewGroup contentContainer;
+ public ViewGroup decorView;//显示pickerview的根View,默认是activity的根view
+ private ViewGroup rootView;//附加View 的 根View
+ private ViewGroup dialogView;//附加Dialog 的 根View
+
+ protected int pickerview_timebtn_nor = 0xFF057dff;
+ protected int pickerview_timebtn_pre = 0xFFc2daf5;
+ protected int pickerview_bg_topbar = 0xFFf5f5f5;
+ protected int pickerview_topbar_title = 0xFF000000;
+ protected int bgColor_default = 0xFFFFFFFF;
+
+ private OnDismissListener onDismissListener;
+ private boolean dismissing;
+
+ private Animation outAnim;
+ private Animation inAnim;
+ private boolean isShowing;
+ private int gravity = Gravity.BOTTOM;
+
+
+ private Dialog mDialog;
+ private boolean cancelable;//是否能取消
+
+ protected View clickView;//是通过哪个View弹出的
+
+ private boolean isAnim = true;
+ public BasePickerView(Context context) {
+ this.context = context;
+
+ /*initViews();
+ init();
+ initEvents();*/
+ }
+
+ protected void initViews(int backgroudId) {
+ LayoutInflater layoutInflater = LayoutInflater.from(context);
+ if (isDialog()) {
+ //如果是对话框模式
+ dialogView = (ViewGroup) layoutInflater.inflate(R.layout.layout_basepickerview, null, false);
+ //设置界面的背景为透明
+ dialogView.setBackgroundColor(Color.TRANSPARENT);
+ //这个是真正要加载时间选取器的父布局
+ contentContainer = (ViewGroup) dialogView.findViewById(R.id.content_container);
+ //设置对话框 左右间距屏幕30
+ this.params.leftMargin = 30;
+ this.params.rightMargin = 30;
+ contentContainer.setLayoutParams(this.params);
+ //创建对话框
+ createDialog();
+ //给背景设置点击事件,这样当点击内容以外的地方会关闭界面
+ dialogView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ dismiss();
+ }
+ });
+ } else {
+ //如果只是要显示在屏幕的下方
+ //decorView是activity的根View
+ if (decorView == null) {
+ decorView = (ViewGroup) ((Activity) context).getWindow().getDecorView().findViewById(android.R.id.content);
+ }
+ //将控件添加到decorView中
+ rootView = (ViewGroup) layoutInflater.inflate(R.layout.layout_basepickerview, decorView, false);
+ rootView.setLayoutParams(new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
+ ));
+ if (backgroudId != 0) {
+ rootView.setBackgroundColor(backgroudId);
+ }
+ // rootView.setBackgroundColor(ContextCompat.getColor(context,backgroudId));
+ //这个是真正要加载时间选取器的父布局
+ contentContainer = (ViewGroup) rootView.findViewById(R.id.content_container);
+ contentContainer.setLayoutParams(params);
+ }
+ setKeyBackCancelable(true);
+ }
+
+ protected void init() {
+ inAnim = getInAnimation();
+ outAnim = getOutAnimation();
+ }
+
+ protected void initEvents() {
+ }
+
+
+ /**
+ * @param v (是通过哪个View弹出的)
+ * @param isAnim 是否显示动画效果
+ */
+ public void show(View v, boolean isAnim) {
+ this.clickView = v;
+ this.isAnim = isAnim;
+ show();
+ }
+
+ public void show(boolean isAnim) {
+ this.isAnim = isAnim;
+ show();
+ }
+
+ public void show(View v) {
+ this.clickView = v;
+ show();
+ }
+
+
+ /**
+ * 添加View到根视图
+ */
+ public void show() {
+ if (isDialog()) {
+ showDialog();
+ } else {
+ if (isShowing()) {
+ return;
+ }
+ isShowing = true;
+ onAttached(rootView);
+ rootView.requestFocus();
+ }
+ }
+
+
+ /**
+ * show的时候调用
+ *
+ * @param view 这个View
+ */
+ private void onAttached(View view) {
+ decorView.addView(view);
+ if(isAnim){
+ contentContainer.startAnimation(inAnim);
+ }
+ }
+
+
+ /**
+ * 检测该View是不是已经添加到根视图
+ *
+ * @return 如果视图已经存在该View返回true
+ */
+ public boolean isShowing() {
+ if (isDialog()) {
+ return false;
+ } else {
+ return rootView.getParent() != null || isShowing;
+ }
+
+ }
+
+ public void dismiss() {
+ if (isDialog()) {
+ dismissDialog();
+ } else {
+ if (dismissing) {
+ return;
+ }
+
+ if (isAnim){
+ //消失动画
+ outAnim.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ dismissImmediately();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+ });
+ contentContainer.startAnimation(outAnim);
+ } else {
+ dismissImmediately();
+ }
+ dismissing = true;
+ }
+
+
+ }
+
+ public void dismissImmediately() {
+
+ decorView.post(new Runnable() {
+ @Override
+ public void run() {
+ //从根视图移除
+ decorView.removeView(rootView);
+ isShowing = false;
+ dismissing = false;
+ if (onDismissListener != null) {
+ onDismissListener.onDismiss(BasePickerView.this);
+ }
+ }
+ });
+
+
+ }
+
+ public Animation getInAnimation() {
+ int res = PickerViewAnimateUtil.getAnimationResource(this.gravity, true);
+ return AnimationUtils.loadAnimation(context, res);
+ }
+
+ public Animation getOutAnimation() {
+ int res = PickerViewAnimateUtil.getAnimationResource(this.gravity, false);
+ return AnimationUtils.loadAnimation(context, res);
+ }
+
+ public BasePickerView setOnDismissListener(OnDismissListener onDismissListener) {
+ this.onDismissListener = onDismissListener;
+ return this;
+ }
+
+ public void setKeyBackCancelable(boolean isCancelable) {
+
+ ViewGroup View;
+ if (isDialog()) {
+ View = dialogView;
+ } else {
+ View = rootView;
+ }
+
+ View.setFocusable(isCancelable);
+ View.setFocusableInTouchMode(isCancelable);
+ if (isCancelable) {
+ View.setOnKeyListener(onKeyBackListener);
+ } else {
+ View.setOnKeyListener(null);
+ }
+ }
+
+ private View.OnKeyListener onKeyBackListener = new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == MotionEvent.ACTION_DOWN
+ && isShowing()) {
+ dismiss();
+ return true;
+ }
+ return false;
+ }
+ };
+
+ protected BasePickerView setOutSideCancelable(boolean isCancelable) {
+ if (rootView != null) {
+ View view = rootView.findViewById(R.id.outmost_container);
+
+ if (isCancelable) {
+ view.setOnTouchListener(onCancelableTouchListener);
+ } else {
+ view.setOnTouchListener(null);
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * 设置对话框模式是否可以点击外部取消
+ *
+ * @param cancelable
+ */
+ public void setDialogOutSideCancelable(boolean cancelable) {
+ this.cancelable = cancelable;
+ }
+
+
+ /**
+ * Called when the user touch on black overlay in order to dismiss the dialog
+ */
+ private final View.OnTouchListener onCancelableTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ dismiss();
+ }
+ return false;
+ }
+ };
+
+ public View findViewById(int id) {
+ return contentContainer.findViewById(id);
+ }
+
+ public void createDialog() {
+ if (dialogView != null) {
+ mDialog = new Dialog(context, R.style.custom_dialog2);
+ mDialog.setCancelable(cancelable);//不能点外面取消,也不 能点back取消
+ mDialog.setContentView(dialogView);
+
+ mDialog.getWindow().setWindowAnimations(R.style.pickerview_dialogAnim);
+ mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (onDismissListener != null) {
+ onDismissListener.onDismiss(BasePickerView.this);
+ }
+ }
+ });
+ }
+
+ }
+
+ public void showDialog() {
+ if (mDialog != null) {
+ mDialog.show();
+ }
+ }
+
+ public void dismissDialog() {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
+ }
+
+ public boolean isDialog() {
+ return false;
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java
new file mode 100644
index 0000000..9a94437
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java
@@ -0,0 +1,378 @@
+package com.bigkoo.pickerview.view;
+
+import android.graphics.Typeface;
+import android.view.View;
+
+import com.bigkoo.pickerview.R;
+import com.bigkoo.pickerview.adapter.ArrayWheelAdapter;
+import com.bigkoo.pickerview.lib.WheelView;
+import com.bigkoo.pickerview.listener.OnItemSelectedListener;
+
+import java.util.List;
+
+public class WheelOptions {
+ private View view;
+ private WheelView wv_option1;
+ private WheelView wv_option2;
+ private WheelView wv_option3;
+
+ private List mOptions1Items;
+ private List> mOptions2Items;
+ private List N_mOptions2Items;
+ private List>> mOptions3Items;
+ private List N_mOptions3Items;
+ private boolean linkage;
+ private OnItemSelectedListener wheelListener_option1;
+ private OnItemSelectedListener wheelListener_option2;
+
+ //文字的颜色和分割线的颜色
+ int textColorOut;
+ int textColorCenter;
+ int dividerColor;
+
+ private WheelView.DividerType dividerType;
+
+ // 条目间距倍数
+ float lineSpacingMultiplier = 1.6F;
+
+ public View getView() {
+ return view;
+ }
+
+ public void setView(View view) {
+ this.view = view;
+ }
+
+ public WheelOptions(View view, Boolean linkage) {
+ super();
+ this.linkage = linkage;
+ this.view = view;
+ wv_option1 = (WheelView) view.findViewById(R.id.options1);// 初始化时显示的数据
+ wv_option2 = (WheelView) view.findViewById(R.id.options2);
+ wv_option3 = (WheelView) view.findViewById(R.id.options3);
+ }
+
+
+ public void setPicker(List options1Items,
+ List> options2Items,
+ List>> options3Items) {
+ this.mOptions1Items = options1Items;
+ this.mOptions2Items = options2Items;
+ this.mOptions3Items = options3Items;
+ int len = ArrayWheelAdapter.DEFAULT_LENGTH;
+ if (this.mOptions3Items == null)
+ len = 8;
+ if (this.mOptions2Items == null)
+ len = 12;
+ // 选项1
+ wv_option1.setAdapter(new ArrayWheelAdapter(mOptions1Items, len));// 设置显示数据
+ wv_option1.setCurrentItem(0);// 初始化时显示的数据
+ // 选项2
+ if (mOptions2Items != null)
+ wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(0)));// 设置显示数据
+ wv_option2.setCurrentItem(wv_option1.getCurrentItem());// 初始化时显示的数据
+ // 选项3
+ if (mOptions3Items != null)
+ wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items.get(0).get(0)));// 设置显示数据
+ wv_option3.setCurrentItem(wv_option3.getCurrentItem());
+ wv_option1.setIsOptions(true);
+ wv_option2.setIsOptions(true);
+ wv_option3.setIsOptions(true);
+
+ if (this.mOptions2Items == null) {
+ wv_option2.setVisibility(View.GONE);
+ } else {
+ wv_option2.setVisibility(View.VISIBLE);
+ }
+ if (this.mOptions3Items == null) {
+ wv_option3.setVisibility(View.GONE);
+ } else {
+ wv_option3.setVisibility(View.VISIBLE);
+ }
+
+ // 联动监听器
+ wheelListener_option1 = new OnItemSelectedListener() {
+
+ @Override
+ public void onItemSelected(int index) {
+ int opt2Select = 0;
+ if (mOptions2Items != null) {
+ opt2Select = wv_option2.getCurrentItem();//上一个opt2的选中位置
+ //新opt2的位置,判断如果旧位置没有超过数据范围,则沿用旧位置,否则选中最后一项
+ opt2Select = opt2Select >= mOptions2Items.get(index).size() - 1 ? mOptions2Items.get(index).size() - 1 : opt2Select;
+
+ wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(index)));
+ wv_option2.setCurrentItem(opt2Select);
+ }
+ if (mOptions3Items != null) {
+ wheelListener_option2.onItemSelected(opt2Select);
+ }
+ }
+ };
+ wheelListener_option2 = new OnItemSelectedListener() {
+
+ @Override
+ public void onItemSelected(int index) {
+ if (mOptions3Items != null) {
+ int opt1Select = wv_option1.getCurrentItem();
+ opt1Select = opt1Select >= mOptions3Items.size() - 1 ? mOptions3Items.size() - 1 : opt1Select;
+ index = index >= mOptions2Items.get(opt1Select).size() - 1 ? mOptions2Items.get(opt1Select).size() - 1 : index;
+ int opt3 = wv_option3.getCurrentItem();//上一个opt3的选中位置
+ //新opt3的位置,判断如果旧位置没有超过数据范围,则沿用旧位置,否则选中最后一项
+ opt3 = opt3 >= mOptions3Items.get(opt1Select).get(index).size() - 1 ? mOptions3Items.get(opt1Select).get(index).size() - 1 : opt3;
+
+ wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items
+ .get(wv_option1.getCurrentItem()).get(index)));
+ wv_option3.setCurrentItem(opt3);
+
+ }
+ }
+ };
+
+ // 添加联动监听
+ if (options2Items != null && linkage)
+ wv_option1.setOnItemSelectedListener(wheelListener_option1);
+ if (options3Items != null && linkage)
+ wv_option2.setOnItemSelectedListener(wheelListener_option2);
+ }
+
+
+ //不联动情况下
+ public void setNPicker(List options1Items,
+ List options2Items,
+ List options3Items) {
+ this.mOptions1Items = options1Items;
+ this.N_mOptions2Items = options2Items;
+ this.N_mOptions3Items = options3Items;
+ int len = ArrayWheelAdapter.DEFAULT_LENGTH;
+ if (this.N_mOptions3Items == null)
+ len = 8;
+ if (this.N_mOptions2Items == null)
+ len = 12;
+ // 选项1
+ wv_option1.setAdapter(new ArrayWheelAdapter(mOptions1Items, len));// 设置显示数据
+ wv_option1.setCurrentItem(0);// 初始化时显示的数据
+ // 选项2
+ if (N_mOptions2Items != null)
+ wv_option2.setAdapter(new ArrayWheelAdapter(N_mOptions2Items));// 设置显示数据
+ wv_option2.setCurrentItem(wv_option1.getCurrentItem());// 初始化时显示的数据
+ // 选项3
+ if (N_mOptions3Items != null)
+ wv_option3.setAdapter(new ArrayWheelAdapter(N_mOptions3Items));// 设置显示数据
+ wv_option3.setCurrentItem(wv_option3.getCurrentItem());
+ wv_option1.setIsOptions(true);
+ wv_option2.setIsOptions(true);
+ wv_option3.setIsOptions(true);
+
+ if (this.N_mOptions2Items == null) {
+ wv_option2.setVisibility(View.GONE);
+ } else {
+ wv_option2.setVisibility(View.VISIBLE);
+ }
+ if (this.N_mOptions3Items == null) {
+ wv_option3.setVisibility(View.GONE);
+ } else {
+ wv_option3.setVisibility(View.VISIBLE);
+ }
+ }
+
+
+ public void setTextContentSize(int textSize) {
+ wv_option1.setTextSize(textSize);
+ wv_option2.setTextSize(textSize);
+ wv_option3.setTextSize(textSize);
+ }
+
+ private void setTextColorOut() {
+ wv_option1.setTextColorOut(textColorOut);
+ wv_option2.setTextColorOut(textColorOut);
+ wv_option3.setTextColorOut(textColorOut);
+
+ }
+
+ private void setTextColorCenter() {
+ wv_option1.setTextColorCenter(textColorCenter);
+ wv_option2.setTextColorCenter(textColorCenter);
+ wv_option3.setTextColorCenter(textColorCenter);
+
+ }
+
+ private void setDividerColor() {
+ wv_option1.setDividerColor(dividerColor);
+ wv_option2.setDividerColor(dividerColor);
+ wv_option3.setDividerColor(dividerColor);
+ }
+
+ private void setDividerType() {
+ wv_option1.setDividerType(dividerType);
+ wv_option2.setDividerType(dividerType);
+ wv_option3.setDividerType(dividerType);
+ }
+
+ private void setLineSpacingMultiplier() {
+ wv_option1.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_option2.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_option3.setLineSpacingMultiplier(lineSpacingMultiplier);
+
+ }
+
+ /**
+ * 设置选项的单位
+ *
+ * @param label1 单位
+ * @param label2 单位
+ * @param label3 单位
+ */
+ public void setLabels(String label1, String label2, String label3) {
+ if (label1 != null)
+ wv_option1.setLabel(label1);
+ if (label2 != null)
+ wv_option2.setLabel(label2);
+ if (label3 != null)
+ wv_option3.setLabel(label3);
+ }
+
+ /**
+ * 设置是否循环滚动
+ *
+ * @param cyclic 是否循环
+ */
+ public void setCyclic(boolean cyclic) {
+ wv_option1.setCyclic(cyclic);
+ wv_option2.setCyclic(cyclic);
+ wv_option3.setCyclic(cyclic);
+ }
+
+ /**
+ * 设置字体样式
+ *
+ * @param font 系统提供的几种样式
+ */
+ public void setTypeface (Typeface font) {
+ wv_option1.setTypeface(font);
+ wv_option2.setTypeface(font);
+ wv_option3.setTypeface(font);
+ }
+
+ /**
+ * 分别设置第一二三级是否循环滚动
+ *
+ * @param cyclic1,cyclic2,cyclic3 是否循环
+ */
+ public void setCyclic(boolean cyclic1, boolean cyclic2, boolean cyclic3) {
+ wv_option1.setCyclic(cyclic1);
+ wv_option2.setCyclic(cyclic2);
+ wv_option3.setCyclic(cyclic3);
+ }
+
+
+
+ /**
+ * 返回当前选中的结果对应的位置数组 因为支持三级联动效果,分三个级别索引,0,1,2。
+ * 在快速滑动未停止时,点击确定按钮,会进行判断,如果匹配数据越界,则设为0,防止index出错导致崩溃。
+ *
+ * @return 索引数组
+ */
+ public int[] getCurrentItems() {
+ int[] currentItems = new int[3];
+ currentItems[0] = wv_option1.getCurrentItem();
+
+ if (mOptions2Items!=null&&mOptions2Items.size()>0){//非空判断
+ currentItems[1] = wv_option2.getCurrentItem()>(mOptions2Items.get(currentItems[0]).size()-1)?0:wv_option2.getCurrentItem();
+ }else {
+ currentItems[1] = wv_option2.getCurrentItem();
+ }
+
+ if (mOptions3Items!=null&&mOptions3Items.size()>0){//非空判断
+ currentItems[2] = wv_option3.getCurrentItem()>(mOptions3Items.get(currentItems[0]).get(currentItems[1]).size()-1)?0:wv_option3.getCurrentItem();
+ }else {
+ currentItems[2] = wv_option3.getCurrentItem();
+ }
+
+ return currentItems;
+ }
+
+ public void setCurrentItems(int option1, int option2, int option3) {
+ if (linkage) {
+ itemSelected(option1, option2, option3);
+ }
+ wv_option1.setCurrentItem(option1);
+ wv_option2.setCurrentItem(option2);
+ wv_option3.setCurrentItem(option3);
+ }
+
+ private void itemSelected(int opt1Select, int opt2Select, int opt3Select) {
+ if (mOptions2Items != null) {
+ wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items
+ .get(opt1Select)));
+ wv_option2.setCurrentItem(opt2Select);
+ }
+ if (mOptions3Items != null) {
+ wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items
+ .get(opt1Select).get(
+ opt2Select)));
+ wv_option3.setCurrentItem(opt3Select);
+ }
+ }
+ /**
+ * 设置间距倍数,但是只能在1.2-2.0f之间
+ *
+ * @param lineSpacingMultiplier
+ */
+ public void setLineSpacingMultiplier(float lineSpacingMultiplier) {
+ this.lineSpacingMultiplier = lineSpacingMultiplier;
+ setLineSpacingMultiplier();
+ }
+
+ /**
+ * 设置分割线的颜色
+ *
+ * @param dividerColor
+ */
+ public void setDividerColor(int dividerColor) {
+ this.dividerColor = dividerColor;
+ setDividerColor();
+ }
+
+ /**
+ * 设置分割线的类型
+ *
+ * @param dividerType
+ */
+ public void setDividerType(WheelView.DividerType dividerType) {
+ this.dividerType = dividerType;
+ setDividerType();
+ }
+ /**
+ * 设置分割线之间的文字的颜色
+ *
+ * @param textColorCenter
+ */
+ public void setTextColorCenter(int textColorCenter) {
+ this.textColorCenter = textColorCenter;
+ setTextColorCenter();
+ }
+
+ /**
+ * 设置分割线以外文字的颜色
+ *
+ * @param textColorOut
+ */
+ public void setTextColorOut(int textColorOut) {
+ this.textColorOut = textColorOut;
+ setTextColorOut();
+ }
+
+ /**
+ * Label 是否只显示中间选中项的
+ *
+ * @param isCenterLabel
+ */
+
+ public void isCenterLabel(Boolean isCenterLabel) {
+ wv_option1.isCenterLabel(isCenterLabel);
+ wv_option2.isCenterLabel(isCenterLabel);
+ wv_option3.isCenterLabel(isCenterLabel);
+ }
+
+}
diff --git a/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java
new file mode 100644
index 0000000..da8a254
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java
@@ -0,0 +1,700 @@
+package com.bigkoo.pickerview.view;
+
+import android.view.View;
+
+import com.bigkoo.pickerview.R;
+import com.bigkoo.pickerview.adapter.NumericWheelAdapter;
+import com.bigkoo.pickerview.lib.WheelView;
+import com.bigkoo.pickerview.listener.OnItemSelectedListener;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+
+
+public class WheelTime {
+ public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ private View view;
+ private WheelView wv_year;
+ private WheelView wv_month;
+ private WheelView wv_day;
+ private WheelView wv_hours;
+ private WheelView wv_mins;
+ private WheelView wv_seconds;
+ private int gravity;
+
+ private boolean[] type;
+ private static final int DEFAULT_START_YEAR = 1900;
+ private static final int DEFAULT_END_YEAR = 2100;
+ private static final int DEFAULT_START_MONTH = 1;
+ private static final int DEFAULT_END_MONTH = 12;
+ private static final int DEFAULT_START_DAY = 1;
+ private static final int DEFAULT_END_DAY = 31;
+
+ private int startYear = DEFAULT_START_YEAR;
+ private int endYear = DEFAULT_END_YEAR;
+ private int startMonth = DEFAULT_START_MONTH;
+ private int endMonth = DEFAULT_END_MONTH;
+ private int startDay = DEFAULT_START_DAY;
+ private int endDay = DEFAULT_END_DAY; //表示31天的
+ private int currentYear;
+
+
+ // 根据屏幕密度来指定选择器字体的大小(不同屏幕可能不同)
+ private int textSize = 18;
+ //文字的颜色和分割线的颜色
+ int textColorOut;
+ int textColorCenter;
+ int dividerColor;
+ // 条目间距倍数
+ float lineSpacingMultiplier = 1.6F;
+
+ private WheelView.DividerType dividerType;
+
+ public WheelTime(View view) {
+ super();
+ this.view = view;
+ type = new boolean[]{true, true, true, true, true, true};
+ setView(view);
+ }
+
+ public WheelTime(View view, boolean[] type, int gravity, int textSize) {
+ super();
+ this.view = view;
+ this.type = type;
+ this.gravity = gravity;
+ this.textSize = textSize;
+ setView(view);
+ }
+
+ public void setPicker(int year, int month, int day) {
+ this.setPicker(year, month, day, 0, 0, 0);
+ }
+
+ public void setPicker(int year, final int month, int day, int h, int m, int s) {
+ // 添加大小月月份并将其转换为list,方便之后的判断
+ String[] months_big = {"1", "3", "5", "7", "8", "10", "12"};
+ String[] months_little = {"4", "6", "9", "11"};
+
+ final List list_big = Arrays.asList(months_big);
+ final List list_little = Arrays.asList(months_little);
+
+ /* final Context context = view.getContext();*/
+ currentYear = year;
+ // 年
+ wv_year = (WheelView) view.findViewById(R.id.year);
+ wv_year.setAdapter(new NumericWheelAdapter(startYear, endYear));// 设置"年"的显示数据
+ /*wv_year.setLabel(context.getString(R.string.pickerview_year));// 添加文字*/
+ wv_year.setCurrentItem(year - startYear);// 初始化时显示的数据
+ wv_year.setGravity(gravity);
+ // 月
+ wv_month = (WheelView) view.findViewById(R.id.month);
+ if (startYear == endYear) {//开始年等于终止年
+ wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
+ wv_month.setCurrentItem(month + 1 - startMonth);
+ } else if (year == startYear) {
+ //起始日期的月份控制
+ wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12));
+ wv_month.setCurrentItem(month + 1 - startMonth);
+ } else if (year == endYear) {
+ //终止日期的月份控制
+ wv_month.setAdapter(new NumericWheelAdapter(1, endMonth));
+ wv_month.setCurrentItem(month);
+ } else {
+ wv_month.setAdapter(new NumericWheelAdapter(1, 12));
+ wv_month.setCurrentItem(month);
+ }
+ /* wv_month.setLabel(context.getString(R.string.pickerview_month));*/
+
+ wv_month.setGravity(gravity);
+ // 日
+ wv_day = (WheelView) view.findViewById(R.id.day);
+
+ if (startYear == endYear && startMonth == endMonth) {
+ if (list_big.contains(String.valueOf(month + 1))) {
+ if (endDay > 31) {
+ endDay = 31;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
+ } else if (list_little.contains(String.valueOf(month + 1))) {
+ if (endDay > 30) {
+ endDay = 30;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
+ } else {
+ // 闰年
+ if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
+ if (endDay > 29) {
+ endDay = 29;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
+ } else {
+ if (endDay > 28) {
+ endDay = 28;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
+ }
+ }
+ wv_day.setCurrentItem(day - startDay);
+ } else if (year == startYear && month + 1 == startMonth) {
+ // 起始日期的天数控制
+ if (list_big.contains(String.valueOf(month + 1))) {
+
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, 31));
+ } else if (list_little.contains(String.valueOf(month + 1))) {
+
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, 30));
+ } else {
+ // 闰年
+ if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
+
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, 29));
+ } else {
+
+ wv_day.setAdapter(new NumericWheelAdapter(startDay, 28));
+ }
+ }
+ wv_day.setCurrentItem(day - startDay);
+ } else if (year == endYear && month + 1 == endMonth) {
+ // 终止日期的天数控制
+ if (list_big.contains(String.valueOf(month + 1))) {
+ if (endDay > 31) {
+ endDay = 31;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
+ } else if (list_little.contains(String.valueOf(month + 1))) {
+ if (endDay > 30) {
+ endDay = 30;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
+ } else {
+ // 闰年
+ if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
+ if (endDay > 29) {
+ endDay = 29;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
+ } else {
+ if (endDay > 28) {
+ endDay = 28;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
+ }
+ }
+ wv_day.setCurrentItem(day - 1);
+ } else {
+ // 判断大小月及是否闰年,用来确定"日"的数据
+ if (list_big.contains(String.valueOf(month + 1))) {
+
+ wv_day.setAdapter(new NumericWheelAdapter(1, 31));
+ } else if (list_little.contains(String.valueOf(month + 1))) {
+
+ wv_day.setAdapter(new NumericWheelAdapter(1, 30));
+ } else {
+ // 闰年
+ if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
+
+ wv_day.setAdapter(new NumericWheelAdapter(1, 29));
+ } else {
+
+ wv_day.setAdapter(new NumericWheelAdapter(1, 28));
+ }
+ }
+ wv_day.setCurrentItem(day - 1);
+ }
+
+ /* wv_day.setLabel(context.getString(R.string.pickerview_day));*/
+
+ wv_day.setGravity(gravity);
+ //时
+ wv_hours = (WheelView) view.findViewById(R.id.hour);
+ wv_hours.setAdapter(new NumericWheelAdapter(0, 23));
+ /* wv_hours.setLabel(context.getString(R.string.pickerview_hours));// 添加文字*/
+ wv_hours.setCurrentItem(h);
+ wv_hours.setGravity(gravity);
+ //分
+ wv_mins = (WheelView) view.findViewById(R.id.min);
+ wv_mins.setAdapter(new NumericWheelAdapter(0, 59));
+ /* wv_mins.setLabel(context.getString(R.string.pickerview_minutes));// 添加文字*/
+ wv_mins.setCurrentItem(m);
+ wv_mins.setGravity(gravity);
+ //秒
+ wv_seconds = (WheelView) view.findViewById(R.id.second);
+ wv_seconds.setAdapter(new NumericWheelAdapter(0, 59));
+ /* wv_seconds.setLabel(context.getString(R.string.pickerview_seconds));// 添加文字*/
+ wv_seconds.setCurrentItem(s);
+ wv_seconds.setGravity(gravity);
+
+ // 添加"年"监听
+ OnItemSelectedListener wheelListener_year = new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(int index) {
+ int year_num = index + startYear;
+ currentYear = year_num;
+ int currentMonthItem = wv_month.getCurrentItem();//记录上一次的item位置
+ // 判断大小月及是否闰年,用来确定"日"的数据
+ if (startYear == endYear) {
+ //重新设置月份
+ wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
+
+ if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
+ currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
+ wv_month.setCurrentItem(currentMonthItem);
+ }
+
+ int monthNum = currentMonthItem + startMonth;
+
+ if (startMonth == endMonth) {
+ //重新设置日
+ setReDay(year_num, monthNum, startDay, endDay, list_big, list_little);
+ } else if (monthNum == startMonth) {
+ //重新设置日
+ setReDay(year_num, monthNum, startDay, 31, list_big, list_little);
+ } else {
+ //重新设置日
+ setReDay(year_num, monthNum, 1, 31, list_big, list_little);
+ }
+ } else if (year_num == startYear) {//等于开始的年
+ //重新设置月份
+ wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12));
+
+ if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
+ currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
+ wv_month.setCurrentItem(currentMonthItem);
+ }
+
+ int month = currentMonthItem + startMonth;
+ if (month == startMonth) {
+
+ //重新设置日
+ setReDay(year_num, month, startDay, 31, list_big, list_little);
+ } else {
+ //重新设置日
+
+ setReDay(year_num, month, 1, 31, list_big, list_little);
+ }
+
+ } else if (year_num == endYear) {
+ //重新设置月份
+ wv_month.setAdapter(new NumericWheelAdapter(1, endMonth));
+ if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
+ currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
+ wv_month.setCurrentItem(currentMonthItem);
+ }
+ int monthNum = currentMonthItem + 1;
+
+ if (monthNum == endMonth) {
+ //重新设置日
+ setReDay(year_num, monthNum, 1, endDay, list_big, list_little);
+ } else {
+ //重新设置日
+ setReDay(year_num, monthNum, 1, 31, list_big, list_little);
+ }
+
+ } else {
+ //重新设置月份
+ wv_month.setAdapter(new NumericWheelAdapter(1, 12));
+ //重新设置日
+ setReDay(year_num, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little);
+
+ }
+
+ }
+ };
+ // 添加"月"监听
+ OnItemSelectedListener wheelListener_month = new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(int index) {
+ int month_num = index + 1;
+
+ if (startYear == endYear) {
+ month_num = month_num + startMonth - 1;
+ if (startMonth == endMonth) {
+ //重新设置日
+ setReDay(currentYear, month_num, startDay, endDay, list_big, list_little);
+ } else if (startMonth == month_num) {
+
+ //重新设置日
+ setReDay(currentYear, month_num, startDay, 31, list_big, list_little);
+ } else if (endMonth == month_num) {
+ setReDay(currentYear, month_num, 1, endDay, list_big, list_little);
+ } else {
+ setReDay(currentYear, month_num, 1, 31, list_big, list_little);
+ }
+ } else if (currentYear == startYear) {
+ month_num = month_num + startMonth - 1;
+ if (month_num == startMonth) {
+ //重新设置日
+ setReDay(currentYear, month_num, startDay, 31, list_big, list_little);
+ } else {
+ //重新设置日
+ setReDay(currentYear, month_num, 1, 31, list_big, list_little);
+ }
+
+ } else if (currentYear == endYear) {
+ if (month_num == endMonth) {
+ //重新设置日
+ setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, endDay, list_big, list_little);
+ } else {
+ setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little);
+ }
+
+ } else {
+ //重新设置日
+ setReDay(currentYear, month_num, 1, 31, list_big, list_little);
+
+ }
+
+
+ }
+ };
+ wv_year.setOnItemSelectedListener(wheelListener_year);
+ wv_month.setOnItemSelectedListener(wheelListener_month);
+ if (type.length != 6) {
+ throw new RuntimeException("type[] length is not 6");
+ }
+ wv_year.setVisibility(type[0] ? View.VISIBLE : View.GONE);
+ wv_month.setVisibility(type[1] ? View.VISIBLE : View.GONE);
+ wv_day.setVisibility(type[2] ? View.VISIBLE : View.GONE);
+ wv_hours.setVisibility(type[3] ? View.VISIBLE : View.GONE);
+ wv_mins.setVisibility(type[4] ? View.VISIBLE : View.GONE);
+ wv_seconds.setVisibility(type[5] ? View.VISIBLE : View.GONE);
+ setContentTextSize();
+ }
+
+
+ private void setReDay(int year_num, int monthNum, int startD, int endD, List list_big, List list_little) {
+ int currentItem = wv_day.getCurrentItem();
+
+ int maxItem;
+ if (list_big
+ .contains(String.valueOf(monthNum))) {
+ if (endD > 31) {
+ endD = 31;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
+ maxItem = endD;
+ } else if (list_little.contains(String.valueOf(monthNum))) {
+ if (endD > 30) {
+ endD = 30;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
+ maxItem = endD;
+ } else {
+ if ((year_num % 4 == 0 && year_num % 100 != 0)
+ || year_num % 400 == 0) {
+ if (endD > 29) {
+ endD = 29;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
+ maxItem = endD;
+ } else {
+ if (endD > 28) {
+ endD = 28;
+ }
+ wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
+ maxItem = endD;
+ }
+ }
+
+ if (currentItem > wv_day.getAdapter().getItemsCount() - 1) {
+ currentItem = wv_day.getAdapter().getItemsCount() - 1;
+ wv_day.setCurrentItem(currentItem);
+ }
+
+ }
+
+
+ private void setContentTextSize() {
+ wv_day.setTextSize(textSize);
+ wv_month.setTextSize(textSize);
+ wv_year.setTextSize(textSize);
+ wv_hours.setTextSize(textSize);
+ wv_mins.setTextSize(textSize);
+ wv_seconds.setTextSize(textSize);
+ }
+
+ private void setTextColorOut() {
+ wv_day.setTextColorOut(textColorOut);
+ wv_month.setTextColorOut(textColorOut);
+ wv_year.setTextColorOut(textColorOut);
+ wv_hours.setTextColorOut(textColorOut);
+ wv_mins.setTextColorOut(textColorOut);
+ wv_seconds.setTextColorOut(textColorOut);
+ }
+
+ private void setTextColorCenter() {
+ wv_day.setTextColorCenter(textColorCenter);
+ wv_month.setTextColorCenter(textColorCenter);
+ wv_year.setTextColorCenter(textColorCenter);
+ wv_hours.setTextColorCenter(textColorCenter);
+ wv_mins.setTextColorCenter(textColorCenter);
+ wv_seconds.setTextColorCenter(textColorCenter);
+ }
+
+ private void setDividerColor() {
+ wv_day.setDividerColor(dividerColor);
+ wv_month.setDividerColor(dividerColor);
+ wv_year.setDividerColor(dividerColor);
+ wv_hours.setDividerColor(dividerColor);
+ wv_mins.setDividerColor(dividerColor);
+ wv_seconds.setDividerColor(dividerColor);
+ }
+
+ private void setDividerType() {
+
+ wv_day.setDividerType(dividerType);
+ wv_month.setDividerType(dividerType);
+ wv_year.setDividerType(dividerType);
+ wv_hours.setDividerType(dividerType);
+ wv_mins.setDividerType(dividerType);
+ wv_seconds.setDividerType(dividerType);
+
+ }
+
+ private void setLineSpacingMultiplier() {
+ wv_day.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_month.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_year.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_hours.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_mins.setLineSpacingMultiplier(lineSpacingMultiplier);
+ wv_seconds.setLineSpacingMultiplier(lineSpacingMultiplier);
+ }
+
+ public void setLabels(String label_year, String label_month, String label_day, String label_hours, String label_mins, String label_seconds) {
+ if (label_year != null) {
+ wv_year.setLabel(label_year);
+ } else {
+ wv_year.setLabel(view.getContext().getString(R.string.pickerview_year));
+ }
+ if (label_month != null) {
+ wv_month.setLabel(label_month);
+ } else {
+ wv_month.setLabel(view.getContext().getString(R.string.pickerview_month));
+ }
+ if (label_day != null) {
+ wv_day.setLabel(label_day);
+ } else {
+ wv_day.setLabel(view.getContext().getString(R.string.pickerview_day));
+ }
+ if (label_hours != null) {
+ wv_hours.setLabel(label_hours);
+ } else {
+ wv_hours.setLabel(view.getContext().getString(R.string.pickerview_hours));
+ }
+ if (label_mins != null) {
+ wv_mins.setLabel(label_mins);
+ } else {
+ wv_mins.setLabel(view.getContext().getString(R.string.pickerview_minutes));
+ }
+ if (label_seconds != null) {
+ wv_seconds.setLabel(label_seconds);
+ } else {
+ wv_seconds.setLabel(view.getContext().getString(R.string.pickerview_seconds));
+ }
+
+ }
+
+
+ /**
+ * 设置是否循环滚动
+ *
+ * @param cyclic
+ */
+ public void setCyclic(boolean cyclic) {
+ wv_year.setCyclic(cyclic);
+ wv_month.setCyclic(cyclic);
+ wv_day.setCyclic(cyclic);
+ wv_hours.setCyclic(cyclic);
+ wv_mins.setCyclic(cyclic);
+ wv_seconds.setCyclic(cyclic);
+ }
+
+ public String getTime() {
+ StringBuffer sb = new StringBuffer();
+ if (currentYear == startYear) {
+ /* int i = wv_month.getCurrentItem() + startMonth;
+ System.out.println("i:" + i);*/
+ if ((wv_month.getCurrentItem() + startMonth) == startMonth) {
+ sb.append((wv_year.getCurrentItem() + startYear)).append("-")
+ .append((wv_month.getCurrentItem() + startMonth)).append("-")
+ .append((wv_day.getCurrentItem() + startDay)).append(" ")
+ .append(wv_hours.getCurrentItem()).append(":")
+ .append(wv_mins.getCurrentItem()).append(":")
+ .append(wv_seconds.getCurrentItem());
+ } else {
+ sb.append((wv_year.getCurrentItem() + startYear)).append("-")
+ .append((wv_month.getCurrentItem() + startMonth)).append("-")
+ .append((wv_day.getCurrentItem() + 1)).append(" ")
+ .append(wv_hours.getCurrentItem()).append(":")
+ .append(wv_mins.getCurrentItem()).append(":")
+ .append(wv_seconds.getCurrentItem());
+ }
+
+
+ } else {
+ sb.append((wv_year.getCurrentItem() + startYear)).append("-")
+ .append((wv_month.getCurrentItem() + 1)).append("-")
+ .append((wv_day.getCurrentItem() + 1)).append(" ")
+ .append(wv_hours.getCurrentItem()).append(":")
+ .append(wv_mins.getCurrentItem()).append(":")
+ .append(wv_seconds.getCurrentItem());
+ }
+
+ return sb.toString();
+ }
+
+ public View getView() {
+ return view;
+ }
+
+ public void setView(View view) {
+ this.view = view;
+ }
+
+ public int getStartYear() {
+ return startYear;
+ }
+
+ public void setStartYear(int startYear) {
+ this.startYear = startYear;
+ }
+
+ public int getEndYear() {
+ return endYear;
+ }
+
+ public void setEndYear(int endYear) {
+ this.endYear = endYear;
+ }
+
+
+ public void setRangDate(Calendar startDate, Calendar endDate) {
+
+ if (startDate == null && endDate != null) {
+ int year = endDate.get(Calendar.YEAR);
+ int month = endDate.get(Calendar.MONTH) + 1;
+ int day = endDate.get(Calendar.DAY_OF_MONTH);
+ if (year > startYear) {
+ this.endYear = year;
+ this.endMonth = month;
+ this.endDay = day;
+ } else if (year == startYear) {
+ if (month > startMonth) {
+ this.endYear = year;
+ this.endMonth = month;
+ this.endDay = day;
+ } else if (month == startMonth) {
+ if (month > startDay) {
+ this.endYear = year;
+ this.endMonth = month;
+ this.endDay = day;
+ }
+ }
+ }
+
+ } else if (startDate != null && endDate == null) {
+ int year = startDate.get(Calendar.YEAR);
+ int month = startDate.get(Calendar.MONTH) + 1;
+ int day = startDate.get(Calendar.DAY_OF_MONTH);
+ if (year < endYear) {
+ this.startMonth = month;
+ this.startDay = day;
+ this.startYear = year;
+ } else if (year == endYear) {
+ if (month < endMonth) {
+ this.startMonth = month;
+ this.startDay = day;
+ this.startYear = year;
+ } else if (month == endMonth) {
+ if (day < endDay) {
+ this.startMonth = month;
+ this.startDay = day;
+ this.startYear = year;
+ }
+ }
+ }
+
+ } else if (startDate != null && endDate != null) {
+ this.startYear = startDate.get(Calendar.YEAR);
+ this.endYear = endDate.get(Calendar.YEAR);
+ this.startMonth = startDate.get(Calendar.MONTH) + 1;
+ this.endMonth = endDate.get(Calendar.MONTH) + 1;
+ this.startDay = startDate.get(Calendar.DAY_OF_MONTH);
+ this.endDay = endDate.get(Calendar.DAY_OF_MONTH);
+
+
+ }
+
+
+ }
+
+
+ /**
+ * 设置间距倍数,但是只能在1.0-2.0f之间
+ *
+ * @param lineSpacingMultiplier
+ */
+ public void setLineSpacingMultiplier(float lineSpacingMultiplier) {
+ this.lineSpacingMultiplier = lineSpacingMultiplier;
+ setLineSpacingMultiplier();
+ }
+
+ /**
+ * 设置分割线的颜色
+ *
+ * @param dividerColor
+ */
+ public void setDividerColor(int dividerColor) {
+ this.dividerColor = dividerColor;
+ setDividerColor();
+ }
+
+ /**
+ * 设置分割线的类型
+ *
+ * @param dividerType
+ */
+ public void setDividerType(WheelView.DividerType dividerType) {
+ this.dividerType = dividerType;
+ setDividerType();
+ }
+
+ /**
+ * 设置分割线之间的文字的颜色
+ *
+ * @param textColorCenter
+ */
+ public void setTextColorCenter(int textColorCenter) {
+ this.textColorCenter = textColorCenter;
+ setTextColorCenter();
+ }
+
+ /**
+ * 设置分割线以外文字的颜色
+ *
+ * @param textColorOut
+ */
+ public void setTextColorOut(int textColorOut) {
+ this.textColorOut = textColorOut;
+ setTextColorOut();
+ }
+
+ /**
+ * Label 是否只显示中间选中项的
+ *
+ * @param isCenterLabel
+ */
+
+ public void isCenterLabel(Boolean isCenterLabel) {
+
+ wv_day.isCenterLabel(isCenterLabel);
+ wv_month.isCenterLabel(isCenterLabel);
+ wv_year.isCenterLabel(isCenterLabel);
+ wv_hours.isCenterLabel(isCenterLabel);
+ wv_mins.isCenterLabel(isCenterLabel);
+ wv_seconds.isCenterLabel(isCenterLabel);
+ }
+}
diff --git a/PersonalCenter/pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml b/PersonalCenter/pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml
new file mode 100644
index 0000000..9ab2df6
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/anim/pickerview_dialog_scale_in.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml b/PersonalCenter/pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml
new file mode 100644
index 0000000..3eb1e06
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/anim/pickerview_dialog_scale_out.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml b/PersonalCenter/pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml
new file mode 100644
index 0000000..212e266
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/anim/pickerview_slide_in_bottom.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml b/PersonalCenter/pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml
new file mode 100644
index 0000000..a2d0ce9
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/anim/pickerview_slide_out_bottom.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/drawable/selector_pickerview_btn.xml b/PersonalCenter/pickerview/src/main/res/drawable/selector_pickerview_btn.xml
new file mode 100644
index 0000000..9ebc219
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/drawable/selector_pickerview_btn.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/PersonalCenter/pickerview/src/main/res/layout/include_pickerview_topbar.xml b/PersonalCenter/pickerview/src/main/res/layout/include_pickerview_topbar.xml
new file mode 100644
index 0000000..272b761
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/layout/include_pickerview_topbar.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
diff --git a/PersonalCenter/pickerview/src/main/res/layout/layout_basepickerview.xml b/PersonalCenter/pickerview/src/main/res/layout/layout_basepickerview.xml
new file mode 100644
index 0000000..adbae30
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/layout/layout_basepickerview.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/layout/pickerview_options.xml b/PersonalCenter/pickerview/src/main/res/layout/pickerview_options.xml
new file mode 100644
index 0000000..4002203
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/layout/pickerview_options.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/layout/pickerview_time.xml b/PersonalCenter/pickerview/src/main/res/layout/pickerview_time.xml
new file mode 100644
index 0000000..9cb3348
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/layout/pickerview_time.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/values-en/strings.xml b/PersonalCenter/pickerview/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..6090da3
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values-en/strings.xml
@@ -0,0 +1,11 @@
+
+
+ Cancel
+ Confirm
+
+
+
+
+
+
+
diff --git a/PersonalCenter/pickerview/src/main/res/values/attrs.xml b/PersonalCenter/pickerview/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..c3f78a6
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values/attrs.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/values/colors.xml b/PersonalCenter/pickerview/src/main/res/values/colors.xml
new file mode 100644
index 0000000..cdc3058
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values/colors.xml
@@ -0,0 +1,14 @@
+
+
+ #057dff
+ #c2daf5
+ #f5f5f5
+
+ #000000
+ #a8a8a8
+ #2a2a2a
+ #d5d5d5
+ #60000000
+ #FFFFFFFF
+
+
diff --git a/PersonalCenter/pickerview/src/main/res/values/dimens.xml b/PersonalCenter/pickerview/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..63f8dd8
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values/dimens.xml
@@ -0,0 +1,13 @@
+
+
+ 44dp
+
+
+ 20dp
+
+
+ 17sp
+ 18sp
+
+ 20sp
+
diff --git a/PersonalCenter/pickerview/src/main/res/values/integers.xml b/PersonalCenter/pickerview/src/main/res/values/integers.xml
new file mode 100644
index 0000000..7e9e0a5
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values/integers.xml
@@ -0,0 +1,5 @@
+
+
+
+ 300
+
\ No newline at end of file
diff --git a/PersonalCenter/pickerview/src/main/res/values/strings.xml b/PersonalCenter/pickerview/src/main/res/values/strings.xml
new file mode 100644
index 0000000..28bcce9
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+
+ 取消
+ 确定
+ 年
+ 月
+ 日
+ 时
+ 分
+ 秒
+
diff --git a/PersonalCenter/pickerview/src/main/res/values/styles.xml b/PersonalCenter/pickerview/src/main/res/values/styles.xml
new file mode 100644
index 0000000..3af3819
--- /dev/null
+++ b/PersonalCenter/pickerview/src/main/res/values/styles.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
diff --git a/PersonalCenter/settings.gradle b/PersonalCenter/settings.gradle
index 039dc42..4e1e695 100644
--- a/PersonalCenter/settings.gradle
+++ b/PersonalCenter/settings.gradle
@@ -1 +1 @@
-include ':app', ':circledialog'
+include ':app', ':circledialog', ':pickerview'
--
1.9.0
|