├── .gradle
└── 2.2
│ └── taskArtifacts
│ ├── cache.properties
│ ├── cache.properties.lock
│ ├── fileHashes.bin
│ ├── fileSnapshots.bin
│ ├── outputFileStates.bin
│ └── taskArtifacts.bin
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── libraries
│ ├── appcompat_v7_23_1_0.xml
│ ├── support_annotations_23_1_0.xml
│ └── support_v4_23_1_0.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── workspace.xml
├── 1.png
├── Android-PickerView.iml
├── README.md
├── app
├── .gitignore
├── app.iml
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── bigkoo
│ │ └── pickerviewdemo
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── bigkoo
│ │ └── pickerviewdemo
│ │ ├── MainActivity.java
│ │ └── bean
│ │ ├── PickerViewData.java
│ │ ├── ProvinceBean.java
│ │ └── TimeBean.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ └── activity_main.xml
│ ├── menu
│ └── menu_main.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── build
└── intermediates
│ └── dex-cache
│ └── cache.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── pickerview
├── .gitignore
├── build.gradle
├── pickerview.iml
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── bigkoo
│ │ └── pickerview
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── bigkoo
│ │ └── pickerview
│ │ ├── OptionsPickerView.java
│ │ ├── TimePickerView.java
│ │ ├── adapter
│ │ ├── ArrayWheelAdapter.java
│ │ ├── NumericWheelAdapter.java
│ │ └── WheelAdapter.java
│ │ ├── lib
│ │ ├── InertiaTimerTask.java
│ │ ├── LoopViewGestureListener.java
│ │ ├── MessageHandler.java
│ │ ├── OnItemSelectedRunnable.java
│ │ ├── SmoothScrollTimerTask.java
│ │ └── WheelView.java
│ │ ├── listener
│ │ ├── OnDismissListener.java
│ │ └── OnItemSelectedListener.java
│ │ ├── model
│ │ └── IPickerViewData.java
│ │ ├── utils
│ │ └── PickerViewAnimateUtil.java
│ │ └── view
│ │ ├── BasePickerView.java
│ │ ├── WheelOptions.java
│ │ └── WheelTime.java
│ └── res
│ ├── anim
│ ├── slide_in_bottom.xml
│ └── slide_out_bottom.xml
│ ├── drawable
│ └── selector_pickerview_btn.xml
│ ├── layout
│ ├── include_pickerview_topbar.xml
│ ├── layout_basepickerview.xml
│ ├── pickerview_options.xml
│ └── pickerview_time.xml
│ └── values
│ ├── attrs.xml
│ ├── bools.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── integers.xml
│ └── strings.xml
├── preview
├── pickerdemo.gif
├── pickerdemo1x.gif
└── pickerdemo_zhangshangshenghuo.gif
└── settings.gradle
/.gradle/2.2/taskArtifacts/cache.properties:
--------------------------------------------------------------------------------
1 | #Mon Oct 24 17:44:51 CST 2016
2 |
--------------------------------------------------------------------------------
/.gradle/2.2/taskArtifacts/cache.properties.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/.gradle/2.2/taskArtifacts/cache.properties.lock
--------------------------------------------------------------------------------
/.gradle/2.2/taskArtifacts/fileHashes.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/.gradle/2.2/taskArtifacts/fileHashes.bin
--------------------------------------------------------------------------------
/.gradle/2.2/taskArtifacts/fileSnapshots.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/.gradle/2.2/taskArtifacts/fileSnapshots.bin
--------------------------------------------------------------------------------
/.gradle/2.2/taskArtifacts/outputFileStates.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/.gradle/2.2/taskArtifacts/outputFileStates.bin
--------------------------------------------------------------------------------
/.gradle/2.2/taskArtifacts/taskArtifacts.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/.gradle/2.2/taskArtifacts/taskArtifacts.bin
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | Android-PickerView
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
26 |
--------------------------------------------------------------------------------
/.idea/libraries/appcompat_v7_23_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/libraries/support_annotations_23_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/support_v4_23_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.8
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/1.png
--------------------------------------------------------------------------------
/Android-PickerView.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 仿滴滴时间选择控件
2 |
3 | ####国际案例,有图有真相:
4 |
5 | 
6 |
7 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.bigkoo.pickerviewdemo"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile project(':pickerview')
25 | // compile 'com.bigkoo:pickerview:2.1.0'
26 | compile 'com.android.support:appcompat-v7:23.1.0'
27 | }
28 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/Sai/Documents/software/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/bigkoo/pickerviewdemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerviewdemo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bigkoo/pickerviewdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerviewdemo;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.ArrayList;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import java.util.List;
8 |
9 | import android.app.Activity;
10 | import android.os.Bundle;
11 | import android.view.KeyEvent;
12 | import android.view.View;
13 | import android.view.View.OnClickListener;
14 | import android.widget.TextView;
15 |
16 | import com.bigkoo.pickerview.OptionsPickerView;
17 | import com.bigkoo.pickerview.TimePickerView;
18 | import com.bigkoo.pickerview.model.IPickerViewData;
19 | import com.bigkoo.pickerviewdemo.bean.PickerViewData;
20 | import com.bigkoo.pickerviewdemo.bean.ProvinceBean;
21 | import com.bigkoo.pickerviewdemo.bean.TimeBean;
22 |
23 |
24 | public class MainActivity extends Activity {
25 |
26 | private ArrayList options1Items = new ArrayList<>();
27 | private ArrayList> options2Items = new ArrayList<>();
28 | private ArrayList>> options3Items = new ArrayList<>();
29 | private TextView tvTime, tvOptions;
30 | TimePickerView pvTime;
31 | OptionsPickerView pvOptions;
32 | View vMasker;
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_main);
38 | vMasker=findViewById(R.id.vMasker);
39 | tvTime=(TextView) findViewById(R.id.tvTime);
40 | tvOptions=(TextView) findViewById(R.id.tvOptions);
41 | //时间选择器
42 | pvTime = new TimePickerView(this, TimePickerView.Type.MONTH_DAY_HOUR_MIN);
43 | //控制时间范围
44 | // Calendar calendar = Calendar.getInstance();
45 | // pvTime.setRange(calendar.get(Calendar.YEAR) - 20, calendar.get(Calendar.YEAR));//要在setTime 之前才有效果哦
46 | pvTime.setTime(new Date());
47 | pvTime.setCyclic(false);
48 | pvTime.setCancelable(true);
49 | //时间选择后回调
50 | pvTime.setOnTimeSelectListener(new TimePickerView.OnTimeSelectListener() {
51 |
52 | @Override
53 | public void onTimeSelect(Date date) {
54 | tvTime.setText(getTime(date));
55 | }
56 | });
57 | //弹出时间选择器
58 | tvTime.setOnClickListener(new OnClickListener() {
59 |
60 | @Override
61 | public void onClick(View v) {
62 | pvTime.show();
63 | }
64 | });
65 |
66 |
67 | //选项选择器
68 | pvOptions = new OptionsPickerView(this);
69 | //选项1
70 | options1Items.add(new TimeBean("现在"));
71 | options1Items.add(new TimeBean("今天"));
72 | options1Items.add(new TimeBean("明天"));
73 | options1Items.add(new TimeBean("后天"));
74 |
75 |
76 | //选项 1 2
77 | ArrayList options2Items_01=new ArrayList<>();
78 | options2Items_01.add("--");
79 |
80 | //22
81 | ArrayList options2Items_02=getTodayHourData();
82 | //32
83 | ArrayList options2Items_03=getHourData();
84 | //32
85 | ArrayList options2Items_04=getHourData();
86 |
87 | options2Items.add(options2Items_01);
88 | options2Items.add(options2Items_02);
89 | options2Items.add(options2Items_03);
90 | options2Items.add(options2Items_04);
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | //选项3
100 | ArrayList> options3Items_01 = new ArrayList<>();
101 | ArrayList> options3Items_02 = new ArrayList<>();
102 | ArrayList> options3Items_03 = new ArrayList<>();
103 | ArrayList> options3Items_04 = new ArrayList<>();
104 |
105 |
106 | ArrayList options3Items_01_01=new ArrayList<>();
107 | options3Items_01_01.add(new PickerViewData("--"));
108 | options3Items_01.add(options3Items_01_01);
109 | options3Items_02 =getmD2();
110 | options3Items_03 =getmD();
111 | options3Items_04 =getmD();
112 |
113 |
114 |
115 | options3Items.add(options3Items_01);
116 | options3Items.add(options3Items_02);
117 | options3Items.add(options3Items_03);
118 | options3Items.add(options3Items_04);
119 |
120 |
121 | //三级联动效果
122 | pvOptions.setPicker(options1Items, options2Items, options3Items, true);
123 | //设置选择的三级单位
124 | // pwOptions.setLabels("省", "市", "区");
125 | pvOptions.setTitle(" ");
126 | pvOptions.setCyclic(false, false, false);
127 | //设置默认选中的三级项目
128 | //监听确定选择按钮
129 | pvOptions.setSelectOptions(0, 0, 0);
130 | pvOptions.setOnoptionsSelectListener(new OptionsPickerView.OnOptionsSelectListener() {
131 |
132 | @Override
133 | public void onOptionsSelect(int options1, int option2, int options3) {
134 | //返回的分别是三个级别的选中位置
135 | String tx = options1Items.get(options1).getPickerViewText()
136 | + options2Items.get(options1).get(option2)
137 | + options3Items.get(options1).get(option2).get(options3).getPickerViewText();
138 | tvOptions.setText(tx);
139 | vMasker.setVisibility(View.GONE);
140 | }
141 | });
142 | //点击弹出选项选择器
143 | tvOptions.setOnClickListener(new View.OnClickListener() {
144 |
145 | @Override
146 | public void onClick(View v) {
147 | pvOptions.show();
148 | }
149 | });
150 | }
151 |
152 | public static String getTime(Date date) {
153 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
154 | return format.format(date);
155 | }
156 |
157 | @Override
158 | public boolean onKeyDown(int keyCode, KeyEvent event) {
159 | if (keyCode == KeyEvent.KEYCODE_BACK) {
160 | if(pvOptions.isShowing()||pvTime.isShowing()){
161 | pvOptions.dismiss();
162 | pvTime.dismiss();
163 | return true;
164 | }
165 | if(pvTime.isShowing()){
166 | pvTime.dismiss();
167 | return true;
168 | }
169 | }
170 | return super.onKeyDown(keyCode, event);
171 | }
172 |
173 | /**
174 | * 今天 点
175 | */
176 | private ArrayList getTodayHourData(){
177 | int max =currentHour();
178 | if (max<23&¤tMin()>45){
179 | max=max+1;
180 | }
181 | ArrayList lists=new ArrayList<>();
182 | for (int i=max;i<24;i++){
183 | lists.add(i+"点");
184 | }
185 | return lists;
186 | }
187 |
188 | /**
189 | * 明天 后天 点
190 | */
191 | private ArrayList getHourData(){
192 | ArrayList lists=new ArrayList<>();
193 | for (int i=0;i<24;i++){
194 | lists.add(i+"点");
195 | }
196 | return lists;
197 | }
198 |
199 | /**
200 | * 明天 后天 分
201 | */
202 | private ArrayList getMinData(){
203 | ArrayList dataArrayList=new ArrayList<>();
204 | for (int i=0;i<6;i++){
205 | dataArrayList.add(new PickerViewData((i*10)+"分"));
206 | }
207 | return dataArrayList;
208 | }
209 | /**
210 | * 明天 后天
211 | */
212 | private ArrayList> getmD(){
213 | ArrayList> d=new ArrayList<>();
214 | for (int i=0;i<24;i++){
215 | d.add(getMinData());
216 | }
217 | return d;
218 | }
219 |
220 | /**
221 | * 明天 后天 2222
222 | */
223 | private ArrayList> getmD2(){
224 | //14
225 | int max =currentHour();
226 | if (currentMin()>45){
227 | max=max+1;
228 | }
229 | int value =24-max;
230 | ArrayList> d=new ArrayList<>();
231 | for (int i=0;i getTodyMinData(){
246 |
247 | int min = currentMin();
248 | int current=0;
249 | if (min>35&&min<=45){
250 | current =0;
251 | }else if (min>45&&min<=55){
252 | current=1;
253 | } else if (min>55){
254 | current=2;
255 | }else if (min<=5){
256 | current=2;
257 | }else if (min>5&&min<=15){
258 | current=3;
259 | }else if (min>15&&min<=25){
260 | current=4;
261 | }else if (min>25&&min<=35){
262 | current=5;
263 | }
264 | int max =currentHour();
265 | if (max>23&& min>35){
266 | current=5;
267 | }
268 |
269 | ArrayList dataArrayList=new ArrayList<>();
270 | for (int i=current;i<6;i++){
271 | dataArrayList.add(new PickerViewData((i*10)+"分"));
272 | }
273 | return dataArrayList;
274 | }
275 |
276 | private int currentMin(){
277 | Calendar cal = Calendar.getInstance();
278 | return cal.get(Calendar.MINUTE);
279 | }
280 |
281 |
282 | private int currentHour(){
283 | Calendar cal = Calendar.getInstance();
284 | return cal.get(Calendar.HOUR_OF_DAY);
285 | }
286 |
287 | }
288 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bigkoo/pickerviewdemo/bean/PickerViewData.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerviewdemo.bean;
2 |
3 | import com.bigkoo.pickerview.model.IPickerViewData;
4 |
5 | /**
6 | * Created by Administrator on 2016/7/13.
7 | */
8 | public class PickerViewData implements IPickerViewData {
9 | private String content;
10 |
11 | public PickerViewData(String content) {
12 | this.content = content;
13 | }
14 |
15 | public void setContent(String content) {
16 | this.content = content;
17 | }
18 |
19 | @Override
20 | public String getPickerViewText() {
21 | return content;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bigkoo/pickerviewdemo/bean/ProvinceBean.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerviewdemo.bean;
2 |
3 | import com.bigkoo.pickerview.model.IPickerViewData;
4 |
5 | /**
6 | * Created by Sai on 15/11/22.
7 | */
8 | public class ProvinceBean implements IPickerViewData {
9 | private long id;
10 | private String name;
11 | private String description;
12 | private String others;
13 |
14 | public ProvinceBean(long id,String name,String description,String others){
15 | this.id = id;
16 | this.name = name;
17 | this.description = description;
18 | this.others = others;
19 | }
20 |
21 | public long getId() {
22 | return id;
23 | }
24 |
25 | public void setId(long id) {
26 | this.id = id;
27 | }
28 |
29 | public String getName() {
30 | return name;
31 | }
32 |
33 | public void setName(String name) {
34 | this.name = name;
35 | }
36 |
37 | public String getDescription() {
38 | return description;
39 | }
40 |
41 | public void setDescription(String description) {
42 | this.description = description;
43 | }
44 |
45 | public String getOthers() {
46 | return others;
47 | }
48 |
49 | public void setOthers(String others) {
50 | this.others = others;
51 | }
52 |
53 | //这个用来显示在PickerView上面的字符串,PickerView会通过IPickerViewData获取getPickerViewText方法显示出来。
54 | @Override
55 | public String getPickerViewText() {
56 | return name;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bigkoo/pickerviewdemo/bean/TimeBean.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerviewdemo.bean;
2 |
3 | import com.bigkoo.pickerview.model.IPickerViewData;
4 |
5 | /**
6 | * Author: 梁铖城
7 | * Email: 1038127753@qq.com
8 | * Date: 2015年11月21日15:28:25
9 | * Description: 开始或者结束轮训器
10 | */
11 | public class TimeBean implements IPickerViewData {
12 | private String time;
13 |
14 | public TimeBean(String time) {
15 | this.time = time;
16 | }
17 |
18 | public String getTime() {
19 | return time;
20 | }
21 |
22 | public void setTime(String time) {
23 | this.time = time;
24 | }
25 |
26 | @Override
27 | public String getPickerViewText() {
28 | return time;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
12 |
19 |
20 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PickerViewDemo
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.5.0'
9 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
10 | classpath 'com.github.dcendents:android-maven-plugin:1.2'
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/build/intermediates/dex-cache/cache.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
9 |
10 |
11 | -
16 |
17 |
18 | -
23 |
24 |
25 | -
30 |
31 |
32 | -
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 22 15:54:07 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Mon Oct 24 17:43:32 CST 2016
11 | ndk.dir=/Users/lcc/Library/Android/sdk/ndk-bundle
12 | sdk.dir=/Users/lcc/Library/Android/sdk
13 |
--------------------------------------------------------------------------------
/pickerview/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/pickerview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 | apply plugin: 'com.jfrog.bintray'
4 |
5 | version = "2.1.1"
6 |
7 | android {
8 | compileSdkVersion 23
9 | buildToolsVersion "23.0.2"
10 |
11 | defaultConfig {
12 | minSdkVersion 9
13 | targetSdkVersion 23
14 | versionCode 4
15 | versionName "2.1.1"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | lintOptions {
24 | abortOnError false
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(dir: 'libs', include: ['*.jar'])
30 | }
31 |
32 | def siteUrl = 'https://github.com/saiwu-bigkoo/Android-PickerView' // #CONFIG# // project homepage
33 | def gitUrl = 'https://github.com/saiwu-bigkoo/Android-PickerView.git' // #CONFIG# // project git
34 | group = "com.bigkoo"
35 |
36 | install {
37 | repositories.mavenInstaller {
38 | // This generates POM.xml with proper parameters
39 | pom {
40 | project {
41 | packaging 'aar'
42 | name 'PickerView For Android' // #CONFIG# // project title
43 | url siteUrl
44 | // Set your license
45 | licenses {
46 | license {
47 | name 'The Apache Software License, Version 2.0'
48 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
49 | }
50 | }
51 | developers {
52 | developer {
53 | id 'sai' // #CONFIG# // your user id (you can write your nickname)
54 | name 'sai.wu' // #CONFIG# // your user name
55 | email 'sai.wu@bigkoo.com' // #CONFIG# // your email
56 | }
57 | }
58 | scm {
59 | connection gitUrl
60 | developerConnection gitUrl
61 | url siteUrl
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
68 | task sourcesJar(type: Jar) {
69 | from android.sourceSets.main.java.srcDirs
70 | classifier = 'sources'
71 | }
72 |
73 | task javadoc(type: Javadoc) {
74 | source = android.sourceSets.main.java.srcDirs
75 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
76 | }
77 |
78 | task javadocJar(type: Jar, dependsOn: javadoc) {
79 | classifier = 'javadoc'
80 | from javadoc.destinationDir
81 | }
82 |
83 | artifacts {
84 | archives javadocJar
85 | archives sourcesJar
86 | }
87 |
88 | Properties properties = new Properties()
89 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
90 | bintray {
91 | user = properties.getProperty("bintray.user")
92 | key = properties.getProperty("bintray.apikey")
93 | configurations = ['archives']
94 | pkg {
95 | repo = "maven"
96 | name = "PickerView" // #CONFIG# project name in jcenter
97 | websiteUrl = siteUrl
98 | vcsUrl = gitUrl
99 | licenses = ["Apache-2.0"]
100 | publish = true
101 | }
102 | }
--------------------------------------------------------------------------------
/pickerview/pickerview.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/pickerview/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/Sai/Documents/software/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/pickerview/src/androidTest/java/com/bigkoo/pickerview/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/pickerview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/OptionsPickerView.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.widget.TextView;
7 |
8 | import com.bigkoo.pickerview.view.BasePickerView;
9 | import com.bigkoo.pickerview.model.IPickerViewData;
10 | import com.bigkoo.pickerview.view.WheelOptions;
11 |
12 | import java.util.ArrayList;
13 |
14 | /**
15 | * 条件选择器
16 | * Created by Sai on 15/11/22.
17 | */
18 | public class OptionsPickerView extends BasePickerView implements View.OnClickListener {
19 | WheelOptions wheelOptions;
20 | private View btnSubmit, btnCancel;
21 | private TextView tvTitle;
22 | private OnOptionsSelectListener optionsSelectListener;
23 | private static final String TAG_SUBMIT = "submit";
24 | private static final String TAG_CANCEL = "cancel";
25 | public OptionsPickerView(Context context) {
26 | super(context);
27 | LayoutInflater.from(context).inflate(R.layout.pickerview_options, contentContainer);
28 | // -----确定和取消按钮
29 | btnSubmit = findViewById(R.id.btnSubmit);
30 | btnSubmit.setTag(TAG_SUBMIT);
31 | btnCancel = findViewById(R.id.btnCancel);
32 | btnCancel.setTag(TAG_CANCEL);
33 | btnSubmit.setOnClickListener(this);
34 | btnCancel.setOnClickListener(this);
35 | //顶部标题
36 | tvTitle = (TextView) findViewById(R.id.tvTitle);
37 | // ----转轮
38 | final View optionspicker = findViewById(R.id.optionspicker);
39 | wheelOptions = new WheelOptions(optionspicker);
40 | }
41 | public void setPicker(ArrayList optionsItems) {
42 | wheelOptions.setPicker(optionsItems, null, null, false);
43 | }
44 |
45 | public void setPicker(ArrayList options1Items,
46 | ArrayList> options2Items, boolean linkage) {
47 | wheelOptions.setPicker(options1Items, options2Items, null, linkage);
48 | }
49 |
50 | public void setPicker(ArrayList options1Items,
51 | ArrayList> options2Items,
52 | ArrayList>> options3Items,
53 | boolean linkage) {
54 | wheelOptions.setPicker(options1Items, options2Items, options3Items,
55 | linkage);
56 | }
57 | /**
58 | * 设置选中的item位置
59 | * @param option1 位置
60 | */
61 | public void setSelectOptions(int option1){
62 | wheelOptions.setCurrentItems(option1, 0, 0);
63 | }
64 | /**
65 | * 设置选中的item位置
66 | * @param option1 位置
67 | * @param option2 位置
68 | */
69 | public void setSelectOptions(int option1, int option2){
70 | wheelOptions.setCurrentItems(option1, option2, 0);
71 | }
72 | /**
73 | * 设置选中的item位置
74 | * @param option1 位置
75 | * @param option2 位置
76 | * @param option3 位置
77 | */
78 | public void setSelectOptions(int option1, int option2, int option3){
79 | wheelOptions.setCurrentItems(option1, option2, option3);
80 | }
81 | /**
82 | * 设置选项的单位
83 | * @param label1 单位
84 | */
85 | public void setLabels(String label1){
86 | wheelOptions.setLabels(label1, null, null);
87 | }
88 | /**
89 | * 设置选项的单位
90 | * @param label1 单位
91 | * @param label2 单位
92 | */
93 | public void setLabels(String label1,String label2){
94 | wheelOptions.setLabels(label1, label2, null);
95 | }
96 | /**
97 | * 设置选项的单位
98 | * @param label1 单位
99 | * @param label2 单位
100 | * @param label3 单位
101 | */
102 | public void setLabels(String label1,String label2,String label3){
103 | wheelOptions.setLabels(label1, label2, label3);
104 | }
105 | /**
106 | * 设置是否循环滚动
107 | * @param cyclic 是否循环
108 | */
109 | public void setCyclic(boolean cyclic){
110 | wheelOptions.setCyclic(cyclic);
111 | }
112 | public void setCyclic(boolean cyclic1,boolean cyclic2,boolean cyclic3) {
113 | wheelOptions.setCyclic(cyclic1,cyclic2,cyclic3);
114 | }
115 |
116 | @Override
117 | public void onClick(View v) {
118 | String tag=(String) v.getTag();
119 | if(tag.equals(TAG_CANCEL)) {
120 | dismiss();
121 | }
122 | else {
123 | if(optionsSelectListener!=null) {
124 | int[] optionsCurrentItems=wheelOptions.getCurrentItems();
125 | optionsSelectListener.onOptionsSelect(optionsCurrentItems[0], optionsCurrentItems[1], optionsCurrentItems[2]);
126 | }
127 | dismiss();
128 | }
129 | }
130 |
131 | public interface OnOptionsSelectListener {
132 | void onOptionsSelect(int options1, int option2, int options3);
133 | }
134 |
135 | public void setOnoptionsSelectListener(
136 | OnOptionsSelectListener optionsSelectListener) {
137 | this.optionsSelectListener = optionsSelectListener;
138 | }
139 |
140 | public void setTitle(String title){
141 | tvTitle.setText(title);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/TimePickerView.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.widget.TextView;
7 |
8 | import com.bigkoo.pickerview.view.BasePickerView;
9 | import com.bigkoo.pickerview.view.WheelTime;
10 |
11 | import java.text.ParseException;
12 | import java.util.Calendar;
13 | import java.util.Date;
14 |
15 | /**
16 | * 时间选择器
17 | * Created by Sai on 15/11/22.
18 | */
19 | public class TimePickerView extends BasePickerView implements View.OnClickListener {
20 | public enum Type {
21 | ALL, YEAR_MONTH_DAY, HOURS_MINS, MONTH_DAY_HOUR_MIN , YEAR_MONTH
22 | }// 四种选择模式,年月日时分,年月日,时分,月日时分
23 |
24 | WheelTime wheelTime;
25 | private View btnSubmit, btnCancel;
26 | private TextView tvTitle;
27 | private static final String TAG_SUBMIT = "submit";
28 | private static final String TAG_CANCEL = "cancel";
29 | private OnTimeSelectListener timeSelectListener;
30 |
31 | public TimePickerView(Context context, Type type) {
32 | super(context);
33 |
34 | LayoutInflater.from(context).inflate(R.layout.pickerview_time, contentContainer);
35 | // -----确定和取消按钮
36 | btnSubmit = findViewById(R.id.btnSubmit);
37 | btnSubmit.setTag(TAG_SUBMIT);
38 | btnCancel = findViewById(R.id.btnCancel);
39 | btnCancel.setTag(TAG_CANCEL);
40 | btnSubmit.setOnClickListener(this);
41 | btnCancel.setOnClickListener(this);
42 | //顶部标题
43 | tvTitle = (TextView) findViewById(R.id.tvTitle);
44 | // ----时间转轮
45 | final View timepickerview = findViewById(R.id.timepicker);
46 | wheelTime = new WheelTime(timepickerview, type);
47 |
48 | //默认选中当前时间
49 | Calendar calendar = Calendar.getInstance();
50 | calendar.setTimeInMillis(System.currentTimeMillis());
51 | int year = calendar.get(Calendar.YEAR);
52 | int month = calendar.get(Calendar.MONTH);
53 | int day = calendar.get(Calendar.DAY_OF_MONTH);
54 | int hours = calendar.get(Calendar.HOUR_OF_DAY);
55 | int minute = calendar.get(Calendar.MINUTE);
56 | wheelTime.setPicker(year, month, day, hours, minute);
57 |
58 | }
59 |
60 | /**
61 | * 设置可以选择的时间范围
62 | * 要在setTime之前调用才有效果
63 | * @param startYear 开始年份
64 | * @param endYear 结束年份
65 | */
66 | public void setRange(int startYear, int endYear) {
67 | wheelTime.setStartYear(startYear);
68 | wheelTime.setEndYear(endYear);
69 | }
70 |
71 | /**
72 | * 设置选中时间
73 | * @param date 时间
74 | */
75 | public void setTime(Date date) {
76 | Calendar calendar = Calendar.getInstance();
77 | if (date == null)
78 | calendar.setTimeInMillis(System.currentTimeMillis());
79 | else
80 | calendar.setTime(date);
81 | int year = calendar.get(Calendar.YEAR);
82 | int month = calendar.get(Calendar.MONTH);
83 | int day = calendar.get(Calendar.DAY_OF_MONTH);
84 | int hours = calendar.get(Calendar.HOUR_OF_DAY);
85 | int minute = calendar.get(Calendar.MINUTE);
86 | wheelTime.setPicker(year, month, day, hours, minute);
87 | }
88 |
89 | // /**
90 | // * 指定选中的时间,显示选择器
91 | // *
92 | // * @param date
93 | // */
94 | // public void show(Date date) {
95 | // Calendar calendar = Calendar.getInstance();
96 | // if (date == null)
97 | // calendar.setTimeInMillis(System.currentTimeMillis());
98 | // else
99 | // calendar.setTime(date);
100 | // int year = calendar.get(Calendar.YEAR);
101 | // int month = calendar.get(Calendar.MONTH);
102 | // int day = calendar.get(Calendar.DAY_OF_MONTH);
103 | // int hours = calendar.get(Calendar.HOUR_OF_DAY);
104 | // int minute = calendar.get(Calendar.MINUTE);
105 | // wheelTime.setPicker(year, month, day, hours, minute);
106 | // show();
107 | // }
108 |
109 | /**
110 | * 设置是否循环滚动
111 | * @param cyclic 是否循环
112 | */
113 | public void setCyclic(boolean cyclic) {
114 | wheelTime.setCyclic(cyclic);
115 | }
116 |
117 | @Override
118 | public void onClick(View v) {
119 | String tag = (String) v.getTag();
120 | if (tag.equals(TAG_CANCEL)) {
121 | dismiss();
122 | return;
123 | } else {
124 | if (timeSelectListener != null) {
125 | try {
126 | Date date = WheelTime.dateFormat.parse(wheelTime.getTime());
127 | timeSelectListener.onTimeSelect(date);
128 | } catch (ParseException e) {
129 | e.printStackTrace();
130 | }
131 | }
132 | dismiss();
133 | return;
134 | }
135 | }
136 |
137 | public interface OnTimeSelectListener {
138 | void onTimeSelect(Date date);
139 | }
140 |
141 | public void setOnTimeSelectListener(OnTimeSelectListener timeSelectListener) {
142 | this.timeSelectListener = timeSelectListener;
143 | }
144 |
145 | public void setTitle(String title){
146 | tvTitle.setText(title);
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/adapter/ArrayWheelAdapter.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.adapter;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * The simple Array wheel adapter
7 | * @param the element type
8 | */
9 | public class ArrayWheelAdapter implements WheelAdapter {
10 |
11 | /** The default items length */
12 | public static final int DEFAULT_LENGTH = 4;
13 |
14 | // items
15 | private ArrayList items;
16 | // length
17 | private int length;
18 |
19 | /**
20 | * Constructor
21 | * @param items the items
22 | * @param length the max items length
23 | */
24 | public ArrayWheelAdapter(ArrayList items, int length) {
25 | this.items = items;
26 | this.length = length;
27 | }
28 |
29 | /**
30 | * Contructor
31 | * @param items the items
32 | */
33 | public ArrayWheelAdapter(ArrayList items) {
34 | this(items, DEFAULT_LENGTH);
35 | }
36 |
37 | @Override
38 | public Object getItem(int index) {
39 | if (index >= 0 && index < items.size()) {
40 | return items.get(index);
41 | }
42 | return "";
43 | }
44 |
45 | @Override
46 | public int getItemsCount() {
47 | return items.size();
48 | }
49 |
50 | @Override
51 | public int indexOf(Object o){
52 | return items.indexOf(o);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/adapter/NumericWheelAdapter.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.adapter;
2 |
3 |
4 | /**
5 | * Numeric Wheel adapter.
6 | */
7 | public class NumericWheelAdapter implements WheelAdapter {
8 |
9 | /** The default min value */
10 | public static final int DEFAULT_MAX_VALUE = 9;
11 |
12 | /** The default max value */
13 | private static final int DEFAULT_MIN_VALUE = 0;
14 |
15 | // Values
16 | private int minValue;
17 | private int maxValue;
18 |
19 | /**
20 | * Default constructor
21 | */
22 | public NumericWheelAdapter() {
23 | this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE);
24 | }
25 |
26 | /**
27 | * Constructor
28 | * @param minValue the wheel min value
29 | * @param maxValue the wheel max value
30 | */
31 | public NumericWheelAdapter(int minValue, int maxValue) {
32 | this.minValue = minValue;
33 | this.maxValue = maxValue;
34 | }
35 |
36 | @Override
37 | public Object getItem(int index) {
38 | if (index >= 0 && index < getItemsCount()) {
39 | int value = minValue + index;
40 | return value;
41 | }
42 | return 0;
43 | }
44 |
45 | @Override
46 | public int getItemsCount() {
47 | return maxValue - minValue + 1;
48 | }
49 |
50 | @Override
51 | public int indexOf(Object o){
52 | return (int)o - minValue;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/adapter/WheelAdapter.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.adapter;
2 |
3 | public interface WheelAdapter {
4 | /**
5 | * Gets items count
6 | * @return the count of wheel items
7 | */
8 | int getItemsCount();
9 |
10 | /**
11 | * Gets a wheel item by index.
12 | * @param index the item index
13 | * @return the wheel item text or null
14 | */
15 | T getItem(int index);
16 |
17 | /**
18 | * Gets maximum item length. It is used to determine the wheel width.
19 | * If -1 is returned there will be used the default wheel width.
20 | * @param o
21 | * @return the maximum item length or -1
22 | */
23 | int indexOf(T o);
24 | }
25 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/lib/InertiaTimerTask.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.lib;
2 |
3 | import java.util.TimerTask;
4 |
5 | final class InertiaTimerTask extends TimerTask {
6 |
7 | float a;
8 | final float velocityY;
9 | final WheelView loopView;
10 |
11 | InertiaTimerTask(WheelView loopview, float velocityY) {
12 | super();
13 | loopView = loopview;
14 | this.velocityY = velocityY;
15 | a = Integer.MAX_VALUE;
16 | }
17 |
18 | @Override
19 | public final void run() {
20 | if (a == Integer.MAX_VALUE) {
21 | if (Math.abs(velocityY) > 2000F) {
22 | if (velocityY > 0.0F) {
23 | a = 2000F;
24 | } else {
25 | a = -2000F;
26 | }
27 | } else {
28 | a = velocityY;
29 | }
30 | }
31 | if (Math.abs(a) >= 0.0F && Math.abs(a) <= 20F) {
32 | loopView.cancelFuture();
33 | loopView.handler.sendEmptyMessage(MessageHandler.WHAT_SMOOTH_SCROLL);
34 | return;
35 | }
36 | int i = (int) ((a * 10F) / 1000F);
37 | loopView.totalScrollY = loopView.totalScrollY - i;
38 | if (!loopView.isLoop) {
39 | float itemHeight = loopView.itemHeight;
40 | float top = (-loopView.initPosition) * itemHeight;
41 | float bottom = (loopView.getItemsCount() - 1 - loopView.initPosition) * itemHeight;
42 | if(loopView.totalScrollY - itemHeight*0.3 < top){
43 | top = loopView.totalScrollY + i;
44 | }
45 | else if(loopView.totalScrollY + itemHeight*0.3 > bottom){
46 | bottom = loopView.totalScrollY + i;
47 | }
48 |
49 | if (loopView.totalScrollY <= top){
50 | a = 40F;
51 | loopView.totalScrollY = (int)top;
52 | } else if (loopView.totalScrollY >= bottom) {
53 | loopView.totalScrollY = (int)bottom;
54 | a = -40F;
55 | }
56 | }
57 | if (a < 0.0F) {
58 | a = a + 20F;
59 | } else {
60 | a = a - 20F;
61 | }
62 | loopView.handler.sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW);
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/lib/LoopViewGestureListener.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.lib;
2 |
3 | import android.view.MotionEvent;
4 |
5 | final class LoopViewGestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
6 |
7 | final WheelView loopView;
8 |
9 | LoopViewGestureListener(WheelView loopview) {
10 | loopView = loopview;
11 | }
12 |
13 | @Override
14 | public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
15 | loopView.scrollBy(velocityY);
16 | return true;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/lib/MessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.lib;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | final class MessageHandler extends Handler {
7 | public static final int WHAT_INVALIDATE_LOOP_VIEW = 1000;
8 | public static final int WHAT_SMOOTH_SCROLL = 2000;
9 | public static final int WHAT_ITEM_SELECTED = 3000;
10 |
11 | final WheelView loopview;
12 |
13 | MessageHandler(WheelView loopview) {
14 | this.loopview = loopview;
15 | }
16 |
17 | @Override
18 | public final void handleMessage(Message msg) {
19 | switch (msg.what) {
20 | case WHAT_INVALIDATE_LOOP_VIEW:
21 | loopview.invalidate();
22 | break;
23 |
24 | case WHAT_SMOOTH_SCROLL:
25 | loopview.smoothScroll(WheelView.ACTION.FLING);
26 | break;
27 |
28 | case WHAT_ITEM_SELECTED:
29 | loopview.onItemSelected();
30 | break;
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/lib/OnItemSelectedRunnable.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.lib;
2 |
3 | final class OnItemSelectedRunnable implements Runnable {
4 | final WheelView loopView;
5 |
6 | OnItemSelectedRunnable(WheelView loopview) {
7 | loopView = loopview;
8 | }
9 |
10 | @Override
11 | public final void run() {
12 | loopView.onItemSelectedListener.onItemSelected(loopView.getCurrentItem());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/lib/SmoothScrollTimerTask.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.lib;
2 |
3 | import java.util.TimerTask;
4 |
5 | final class SmoothScrollTimerTask extends TimerTask {
6 |
7 | int realTotalOffset;
8 | int realOffset;
9 | int offset;
10 | final WheelView loopView;
11 |
12 | SmoothScrollTimerTask(WheelView loopview, int offset) {
13 | this.loopView = loopview;
14 | this.offset = offset;
15 | realTotalOffset = Integer.MAX_VALUE;
16 | realOffset = 0;
17 | }
18 |
19 | @Override
20 | public final void run() {
21 | if (realTotalOffset == Integer.MAX_VALUE) {
22 | realTotalOffset = offset;
23 | }
24 | //把要滚动的范围细分成十小份,按是小份单位来重绘
25 | realOffset = (int) ((float) realTotalOffset * 0.1F);
26 |
27 | if (realOffset == 0) {
28 | if (realTotalOffset < 0) {
29 | realOffset = -1;
30 | } else {
31 | realOffset = 1;
32 | }
33 | }
34 |
35 | if (Math.abs(realTotalOffset) <= 1) {
36 | loopView.cancelFuture();
37 | loopView.handler.sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED);
38 | } else {
39 | loopView.totalScrollY = loopView.totalScrollY + realOffset;
40 |
41 | //这里如果不是循环模式,则点击空白位置需要回滚,不然就会出现选到-1 item的 情况
42 | if (!loopView.isLoop) {
43 | float itemHeight = loopView.itemHeight;
44 | float top = (float) (-loopView.initPosition) * itemHeight;
45 | float bottom = (float) (loopView.getItemsCount() - 1 - loopView.initPosition) * itemHeight;
46 | if (loopView.totalScrollY <= top||loopView.totalScrollY >= bottom) {
47 | loopView.totalScrollY = loopView.totalScrollY - realOffset;
48 | loopView.cancelFuture();
49 | loopView.handler.sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED);
50 | return;
51 | }
52 | }
53 | loopView.handler.sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW);
54 | realTotalOffset = realTotalOffset - realOffset;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/lib/WheelView.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.lib;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.graphics.Rect;
8 | import android.graphics.Typeface;
9 | import android.os.Handler;
10 | import android.util.AttributeSet;
11 | import android.view.GestureDetector;
12 | import android.view.Gravity;
13 | import android.view.MotionEvent;
14 | import android.view.View;
15 |
16 | import com.bigkoo.pickerview.R;
17 | import com.bigkoo.pickerview.adapter.WheelAdapter;
18 | import com.bigkoo.pickerview.listener.OnItemSelectedListener;
19 | import com.bigkoo.pickerview.model.IPickerViewData;
20 |
21 | import java.lang.reflect.InvocationTargetException;
22 | import java.lang.reflect.Method;
23 | import java.util.concurrent.Executors;
24 | import java.util.concurrent.ScheduledExecutorService;
25 | import java.util.concurrent.ScheduledFuture;
26 | import java.util.concurrent.TimeUnit;
27 |
28 | /**
29 | * 3d滚轮控件
30 | */
31 | public class WheelView extends View {
32 |
33 | public enum ACTION {
34 | // 点击,滑翔(滑到尽头),拖拽事件
35 | CLICK, FLING, DAGGLE
36 | }
37 |
38 | Context context;
39 |
40 | Handler handler;
41 | private GestureDetector gestureDetector;
42 | OnItemSelectedListener onItemSelectedListener;
43 |
44 | // Timer mTimer;
45 | ScheduledExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor();
46 | private ScheduledFuture> mFuture;
47 |
48 | Paint paintOuterText;
49 | Paint paintCenterText;
50 | Paint paintIndicator;
51 |
52 | WheelAdapter adapter;
53 |
54 | private String label;//附加单位
55 | int textSize;//选项的文字大小
56 | boolean customTextSize;//自定义文字大小,为true则用于使setTextSize函数无效,只能通过xml修改
57 | int maxTextWidth;
58 | int maxTextHeight;
59 | float itemHeight;//每行高度
60 |
61 | int textColorOut;
62 | int textColorCenter;
63 | int dividerColor;
64 |
65 | // 条目间距倍数
66 | static final float lineSpacingMultiplier = 1.8F;
67 | boolean isLoop;
68 |
69 | // 第一条线Y坐标值
70 | float firstLineY;
71 | //第二条线Y坐标
72 | float secondLineY;
73 | //中间Y坐标
74 | float centerY;
75 |
76 | //滚动总高度y值
77 | int totalScrollY;
78 | //初始化默认选中第几个
79 | int initPosition;
80 | //选中的Item是第几个
81 | private int selectedItem;
82 | int preCurrentIndex;
83 | //滚动偏移值,用于记录滚动了多少个item
84 | int change;
85 |
86 | // 显示几个条目
87 | int itemsVisible = 11;
88 |
89 | int measuredHeight;
90 | int measuredWidth;
91 |
92 | // 半圆周长
93 | int halfCircumference;
94 | // 半径
95 | int radius;
96 |
97 | private int mOffset = 0;
98 | private float previousY = 0;
99 | long startTime = 0;
100 |
101 | // 修改这个值可以改变滑行速度
102 | private static final int VELOCITYFLING = 5;
103 | int widthMeasureSpec;
104 |
105 | private int mGravity = Gravity.CENTER;
106 | private int drawCenterContentStart = 0;//中间选中文字开始绘制位置
107 | private int drawOutContentStart = 0;//非中间文字开始绘制位置
108 | private static final float SCALECONTENT = 0.8F;//非中间文字则用此控制高度,压扁形成3d错觉
109 | private static final float CENTERCONTENTOFFSET = 6;//中间文字文字居中需要此偏移值
110 |
111 | public WheelView(Context context) {
112 | this(context, null);
113 | }
114 |
115 | public WheelView(Context context, AttributeSet attrs) {
116 | super(context, attrs);
117 | textColorOut = getResources().getColor(R.color.pickerview_wheelview_textcolor_out);
118 | textColorCenter = getResources().getColor(R.color.pickerview_wheelview_textcolor_center);
119 | dividerColor = getResources().getColor(R.color.pickerview_wheelview_textcolor_divider);
120 | //配合customTextSize使用,customTextSize为true才会发挥效果
121 | textSize = getResources().getDimensionPixelSize(R.dimen.pickerview_textsize);
122 | customTextSize = getResources().getBoolean(R.bool.pickerview_customTextSize);
123 | if (attrs != null) {
124 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.pickerview, 0, 0);
125 | mGravity = a.getInt(R.styleable.pickerview_pickerview_gravity, Gravity.CENTER);
126 | textColorOut = a.getColor(R.styleable.pickerview_pickerview_textColorOut, textColorOut);
127 | textColorCenter = a.getColor(R.styleable.pickerview_pickerview_textColorCenter, textColorCenter);
128 | dividerColor = a.getColor(R.styleable.pickerview_pickerview_dividerColor, dividerColor);
129 | textSize = a.getDimensionPixelOffset(R.styleable.pickerview_pickerview_textSize, textSize);
130 | }
131 | initLoopView(context);
132 | }
133 |
134 | private void initLoopView(Context context) {
135 | this.context = context;
136 | handler = new MessageHandler(this);
137 | gestureDetector = new GestureDetector(context, new LoopViewGestureListener(this));
138 | gestureDetector.setIsLongpressEnabled(false);
139 | isLoop = true;
140 | totalScrollY = 0;
141 | initPosition = -1;
142 | initPaints();
143 |
144 | }
145 |
146 | private void initPaints() {
147 | paintOuterText = new Paint();
148 | paintOuterText.setColor(textColorOut);
149 | paintOuterText.setAntiAlias(true);
150 | paintOuterText.setTypeface(Typeface.MONOSPACE);
151 | paintOuterText.setTextSize(textSize);
152 | paintCenterText = new Paint();
153 | paintCenterText.setColor(textColorCenter);
154 | paintCenterText.setAntiAlias(true);
155 | paintCenterText.setTextScaleX(1.1F);
156 | paintCenterText.setTypeface(Typeface.MONOSPACE);
157 | paintCenterText.setTextSize(textSize);
158 |
159 | paintIndicator = new Paint();
160 | paintIndicator.setColor(dividerColor);
161 | paintIndicator.setAntiAlias(true);
162 |
163 | if (android.os.Build.VERSION.SDK_INT >= 11) {
164 | setLayerType(LAYER_TYPE_SOFTWARE, null);
165 | }
166 | }
167 |
168 | private void remeasure() {
169 | if (adapter == null) {
170 | return;
171 | }
172 |
173 | measureTextWidthHeight();
174 | //最大Text的高度乘间距倍数得到 可见文字实际的总高度,半圆的周长
175 | halfCircumference = (int) (itemHeight * (itemsVisible - 1));
176 | //整个圆的周长除以PI得到直径,这个直径用作控件的总高度
177 | measuredHeight = (int) ((halfCircumference * 2) / Math.PI);
178 | //求出半径
179 | radius = (int) (halfCircumference / Math.PI);
180 | //控件宽度,这里支持weight
181 | measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
182 | //计算两条横线和控件中间点的Y位置
183 | firstLineY = (measuredHeight - itemHeight) / 2.0F;
184 | secondLineY = (measuredHeight + itemHeight) / 2.0F;
185 | centerY = (measuredHeight + maxTextHeight) / 2.0F - CENTERCONTENTOFFSET;
186 | //初始化显示的item的position,根据是否loop
187 | if (initPosition == -1) {
188 | if (isLoop) {
189 | initPosition = (adapter.getItemsCount() + 1) / 2;
190 | } else {
191 | initPosition = 0;
192 | }
193 | }
194 |
195 | preCurrentIndex = initPosition;
196 | }
197 |
198 | /**
199 | * 计算最大len的Text的宽高度
200 | */
201 | private void measureTextWidthHeight() {
202 | Rect rect = new Rect();
203 | for (int i = 0; i < adapter.getItemsCount(); i++) {
204 | String s1 = getContentText(adapter.getItem(i));
205 | paintCenterText.getTextBounds(s1, 0, s1.length(), rect);
206 | int textWidth = rect.width();
207 | if (textWidth > maxTextWidth) {
208 | maxTextWidth = textWidth;
209 | }
210 | // 星期
211 | paintCenterText.getTextBounds("\u661F\u671F", 0, 2, rect);
212 | int textHeight = rect.height();
213 | if (textHeight > maxTextHeight) {
214 | maxTextHeight = textHeight;
215 | }
216 | }
217 | itemHeight = lineSpacingMultiplier * maxTextHeight;
218 | }
219 |
220 | void smoothScroll(ACTION action) {
221 | cancelFuture();
222 | if (action == ACTION.FLING || action == ACTION.DAGGLE) {
223 | mOffset = (int) ((totalScrollY % itemHeight + itemHeight) % itemHeight);
224 | if ((float) mOffset > itemHeight / 2.0F) {
225 | mOffset = (int) (itemHeight - (float) mOffset);
226 | } else {
227 | mOffset = -mOffset;
228 | }
229 | }
230 | //停止的时候,位置有偏移,不是全部都能正确停止到中间位置的,这里把文字位置挪回中间去
231 | mFuture = mExecutor.scheduleWithFixedDelay(new SmoothScrollTimerTask(this, mOffset), 0, 10, TimeUnit.MILLISECONDS);
232 | }
233 |
234 | protected final void scrollBy(float velocityY) {
235 | cancelFuture();
236 |
237 | mFuture = mExecutor.scheduleWithFixedDelay(new InertiaTimerTask(this, velocityY), 0, VELOCITYFLING, TimeUnit.MILLISECONDS);
238 | }
239 |
240 | public void cancelFuture() {
241 | if (mFuture != null && !mFuture.isCancelled()) {
242 | mFuture.cancel(true);
243 | mFuture = null;
244 | }
245 | }
246 |
247 | /**
248 | * 设置是否循环滚动
249 | * @param cyclic 是否循环
250 | */
251 | public final void setCyclic(boolean cyclic) {
252 | isLoop = cyclic;
253 | }
254 |
255 | public final void setTextSize(float size) {
256 | if (size > 0.0F && !customTextSize) {
257 | textSize = (int) (context.getResources().getDisplayMetrics().density * size);
258 | paintOuterText.setTextSize(textSize);
259 | paintCenterText.setTextSize(textSize);
260 | }
261 | }
262 |
263 | public final void setCurrentItem(int currentItem) {
264 | this.initPosition = currentItem;
265 | totalScrollY = 0;//回归顶部,不然重设setCurrentItem的话位置会偏移的,就会显示出不对位置的数据
266 | invalidate();
267 | }
268 |
269 | public final void setOnItemSelectedListener(OnItemSelectedListener OnItemSelectedListener) {
270 | this.onItemSelectedListener = OnItemSelectedListener;
271 | }
272 |
273 | public final void setAdapter(WheelAdapter adapter) {
274 | this.adapter = adapter;
275 | remeasure();
276 | invalidate();
277 | }
278 |
279 | public final WheelAdapter getAdapter() {
280 | return adapter;
281 | }
282 |
283 | public final int getCurrentItem() {
284 | return selectedItem;
285 | }
286 |
287 | protected final void onItemSelected() {
288 | if (onItemSelectedListener != null) {
289 | postDelayed(new OnItemSelectedRunnable(this), 200L);
290 | }
291 | }
292 |
293 | @Override
294 | protected void onDraw(Canvas canvas) {
295 | if (adapter == null) {
296 | return;
297 | }
298 | //可见的item数组
299 | Object visibles[] = new Object[itemsVisible];
300 | //滚动的Y值高度除去每行Item的高度,得到滚动了多少个item,即change数
301 | change = (int) (totalScrollY / itemHeight);
302 | try {
303 | //滚动中实际的预选中的item(即经过了中间位置的item) = 滑动前的位置 + 滑动相对位置
304 | preCurrentIndex = initPosition + change % adapter.getItemsCount();
305 | } catch (ArithmeticException e) {
306 | System.out.println("出错了!adapter.getItemsCount() == 0,联动数据不匹配");
307 | }
308 | //不循环的情况
309 | if (!isLoop) {
310 | if (preCurrentIndex < 0) {
311 | preCurrentIndex = 0;
312 | }
313 | if (preCurrentIndex > adapter.getItemsCount() - 1) {
314 | preCurrentIndex = adapter.getItemsCount() - 1;
315 | }
316 | } else {
317 | //循环
318 | if (preCurrentIndex < 0) {//举个例子:如果总数是5,preCurrentIndex = -1,那么preCurrentIndex按循环来说,其实是0的上面,也就是4的位置
319 | preCurrentIndex = adapter.getItemsCount() + preCurrentIndex;
320 | }
321 | if (preCurrentIndex > adapter.getItemsCount() - 1) {//同理上面,自己脑补一下
322 | preCurrentIndex = preCurrentIndex - adapter.getItemsCount();
323 | }
324 | }
325 |
326 | //跟滚动流畅度有关,总滑动距离与每个item高度取余,即并不是一格格的滚动,
327 | //每个item不一定滚到对应Rect里的,这个item对应格子的偏移值
328 | int itemHeightOffset = (int) (totalScrollY % itemHeight);
329 | // 设置数组中每个元素的值
330 | int counter = 0;
331 | while (counter < itemsVisible) {
332 | int index = preCurrentIndex - (itemsVisible / 2 - counter);//索引值,即当前在控件中间的item看作数据源的中间,计算出相对源数据源的index值
333 |
334 | //判断是否循环,如果是循环数据源也使用相对循环的position获取对应的item值,如果不是循环则超出数据源范围使用""空白字符串填充,在界面上形成空白无数据的item项
335 | if (isLoop) {
336 | index = getLoopMappingIndex(index);
337 | visibles[counter] = adapter.getItem(index);
338 | } else if (index < 0) {
339 | visibles[counter] = "";
340 | } else if (index > adapter.getItemsCount() - 1) {
341 | visibles[counter] = "";
342 | } else {
343 | visibles[counter] = adapter.getItem(index);
344 | }
345 |
346 | counter++;
347 | }
348 |
349 | //中间两条横线
350 | canvas.drawLine(0.0F, firstLineY, measuredWidth, firstLineY, paintIndicator);
351 | canvas.drawLine(0.0F, secondLineY, measuredWidth, secondLineY, paintIndicator);
352 | //单位的Label
353 | if (label != null) {
354 | int drawRightContentStart = measuredWidth - getTextWidth(paintCenterText, label);
355 | //靠右并留出空隙
356 | canvas.drawText(label, drawRightContentStart - CENTERCONTENTOFFSET, centerY, paintCenterText);
357 | }
358 | counter = 0;
359 | while (counter < itemsVisible) {
360 | canvas.save();
361 | // L(弧长)=α(弧度)* r(半径) (弧度制)
362 | // 求弧度--> (L * π ) / (π * r) (弧长X派/半圆周长)
363 | float itemHeight = maxTextHeight * lineSpacingMultiplier;
364 | double radian = ((itemHeight * counter - itemHeightOffset) * Math.PI) / halfCircumference;
365 | // 弧度转换成角度(把半圆以Y轴为轴心向右转90度,使其处于第一象限及第四象限
366 | float angle = (float) (90D - (radian / Math.PI) * 180D);
367 | // 九十度以上的不绘制
368 | if (angle >= 90F || angle <= -90F) {
369 | canvas.restore();
370 | } else {
371 | String contentText = getContentText(visibles[counter]);
372 | //计算开始绘制的位置
373 | measuredCenterContentStart(contentText);
374 | measuredOutContentStart(contentText);
375 | float translateY = (float) (radius - Math.cos(radian) * radius - (Math.sin(radian) * maxTextHeight) / 2D);
376 | //根据Math.sin(radian)来更改canvas坐标系原点,然后缩放画布,使得文字高度进行缩放,形成弧形3d视觉差
377 | canvas.translate(0.0F, translateY);
378 | canvas.scale(1.0F, (float) Math.sin(radian));
379 | if (translateY <= firstLineY && maxTextHeight + translateY >= firstLineY) {
380 | // 条目经过第一条线
381 | canvas.save();
382 | canvas.clipRect(0, 0, measuredWidth, firstLineY - translateY);
383 | canvas.scale(1.0F, (float) Math.sin(radian) * SCALECONTENT);
384 | canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText);
385 | canvas.restore();
386 | canvas.save();
387 | canvas.clipRect(0, firstLineY - translateY, measuredWidth, (int) (itemHeight));
388 | canvas.scale(1.0F, (float) Math.sin(radian) * 1F);
389 | canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTERCONTENTOFFSET, paintCenterText);
390 | canvas.restore();
391 | } else if (translateY <= secondLineY && maxTextHeight + translateY >= secondLineY) {
392 | // 条目经过第二条线
393 | canvas.save();
394 | canvas.clipRect(0, 0, measuredWidth, secondLineY - translateY);
395 | canvas.scale(1.0F, (float) Math.sin(radian) * 1.0F);
396 | canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTERCONTENTOFFSET, paintCenterText);
397 | canvas.restore();
398 | canvas.save();
399 | canvas.clipRect(0, secondLineY - translateY, measuredWidth, (int) (itemHeight));
400 | canvas.scale(1.0F, (float) Math.sin(radian) * SCALECONTENT);
401 | canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText);
402 | canvas.restore();
403 | } else if (translateY >= firstLineY && maxTextHeight + translateY <= secondLineY) {
404 | // 中间条目
405 | canvas.clipRect(0, 0, measuredWidth, (int) (itemHeight));
406 | canvas.drawText(contentText, drawCenterContentStart, maxTextHeight - CENTERCONTENTOFFSET, paintCenterText);
407 | int preSelectedItem = adapter.indexOf(visibles[counter]);
408 | if (preSelectedItem != -1) {
409 | selectedItem = preSelectedItem;
410 | }
411 | } else {
412 | // 其他条目
413 | canvas.save();
414 | canvas.clipRect(0, 0, measuredWidth, (int) (itemHeight));
415 | canvas.scale(1.0F, (float) Math.sin(radian) * SCALECONTENT);
416 | canvas.drawText(contentText, drawOutContentStart, maxTextHeight, paintOuterText);
417 | canvas.restore();
418 | }
419 | canvas.restore();
420 | }
421 | counter++;
422 | }
423 | }
424 |
425 | //递归计算出对应的index
426 | private int getLoopMappingIndex(int index) {
427 | if (index < 0) {
428 | index = index + adapter.getItemsCount();
429 | index = getLoopMappingIndex(index);
430 | } else if (index > adapter.getItemsCount() - 1) {
431 | index = index - adapter.getItemsCount();
432 | index = getLoopMappingIndex(index);
433 | }
434 | return index;
435 | }
436 |
437 | /**
438 | * 根据传进来的对象获取getPickerViewText()方法,来获取需要显示的值
439 | * @param item 数据源的item
440 | * @return 对应显示的字符串
441 | */
442 | private String getContentText(Object item) {
443 | if (item == null) {
444 | return "";
445 | }
446 | else if (item instanceof IPickerViewData) {
447 | return ((IPickerViewData) item).getPickerViewText();
448 | }
449 | return item.toString();
450 | }
451 |
452 | private void measuredCenterContentStart(String content) {
453 | Rect rect = new Rect();
454 | paintCenterText.getTextBounds(content, 0, content.length(), rect);
455 | switch (mGravity) {
456 | case Gravity.CENTER:
457 | drawCenterContentStart = (int) ((measuredWidth - rect.width()) * 0.5);
458 | break;
459 | case Gravity.LEFT:
460 | drawCenterContentStart = 0;
461 | break;
462 | case Gravity.RIGHT:
463 | drawCenterContentStart = measuredWidth - rect.width();
464 | break;
465 | }
466 | }
467 |
468 | private void measuredOutContentStart(String content) {
469 | Rect rect = new Rect();
470 | paintOuterText.getTextBounds(content, 0, content.length(), rect);
471 | switch (mGravity) {
472 | case Gravity.CENTER:
473 | drawOutContentStart = (int) ((measuredWidth - rect.width()) * 0.5);
474 | break;
475 | case Gravity.LEFT:
476 | drawOutContentStart = 0;
477 | break;
478 | case Gravity.RIGHT:
479 | drawOutContentStart = measuredWidth - rect.width();
480 | break;
481 | }
482 | }
483 |
484 | @Override
485 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
486 | this.widthMeasureSpec = widthMeasureSpec;
487 | remeasure();
488 | setMeasuredDimension(measuredWidth, measuredHeight);
489 | }
490 |
491 | @Override
492 | public boolean onTouchEvent(MotionEvent event) {
493 | boolean eventConsumed = gestureDetector.onTouchEvent(event);
494 | switch (event.getAction()) {
495 | case MotionEvent.ACTION_DOWN:
496 | startTime = System.currentTimeMillis();
497 | cancelFuture();
498 | previousY = event.getRawY();
499 | break;
500 |
501 | case MotionEvent.ACTION_MOVE:
502 | float dy = previousY - event.getRawY();
503 | previousY = event.getRawY();
504 | totalScrollY = (int) (totalScrollY + dy);
505 |
506 | // 边界处理。
507 | if (!isLoop) {
508 | float top = -initPosition * itemHeight;
509 | float bottom = (adapter.getItemsCount() - 1 - initPosition) * itemHeight;
510 | if (totalScrollY - itemHeight * 0.3 < top) {
511 | top = totalScrollY - dy;
512 | } else if (totalScrollY + itemHeight * 0.3 > bottom) {
513 | bottom = totalScrollY - dy;
514 | }
515 |
516 | if (totalScrollY < top) {
517 | totalScrollY = (int) top;
518 | } else if (totalScrollY > bottom) {
519 | totalScrollY = (int) bottom;
520 | }
521 | }
522 | break;
523 |
524 | case MotionEvent.ACTION_UP:
525 | default:
526 | if (!eventConsumed) {
527 | float y = event.getY();
528 | double l = Math.acos((radius - y) / radius) * radius;
529 | int circlePosition = (int) ((l + itemHeight / 2) / itemHeight);
530 |
531 | float extraOffset = (totalScrollY % itemHeight + itemHeight) % itemHeight;
532 | mOffset = (int) ((circlePosition - itemsVisible / 2) * itemHeight - extraOffset);
533 |
534 | if ((System.currentTimeMillis() - startTime) > 120) {
535 | // 处理拖拽事件
536 | smoothScroll(ACTION.DAGGLE);
537 | } else {
538 | // 处理条目点击事件
539 | smoothScroll(ACTION.CLICK);
540 | }
541 | }
542 | break;
543 | }
544 | invalidate();
545 |
546 | return true;
547 | }
548 |
549 | /**
550 | * 获取Item个数
551 | * @return item个数
552 | */
553 | public int getItemsCount() {
554 | return adapter != null ? adapter.getItemsCount() : 0;
555 | }
556 |
557 | /**
558 | * 附加在右边的单位字符串
559 | * @param label 单位
560 | */
561 | public void setLabel(String label) {
562 | this.label = label;
563 | }
564 |
565 | public void setGravity(int gravity) {
566 | this.mGravity = gravity;
567 | }
568 |
569 | public int getTextWidth(Paint paint, String str) {
570 | int iRet = 0;
571 | if (str != null && str.length() > 0) {
572 | int len = str.length();
573 | float[] widths = new float[len];
574 | paint.getTextWidths(str, widths);
575 | for (int j = 0; j < len; j++) {
576 | iRet += (int) Math.ceil(widths[j]);
577 | }
578 | }
579 | return iRet;
580 | }
581 | }
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnDismissListener.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.listener;
2 |
3 | /**
4 | * Created by Sai on 15/8/9.
5 | */
6 | public interface OnDismissListener {
7 | public void onDismiss(Object o);
8 | }
9 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/listener/OnItemSelectedListener.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.listener;
2 |
3 |
4 | public interface OnItemSelectedListener {
5 | void onItemSelected(int index);
6 | }
7 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/model/IPickerViewData.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.model;
2 |
3 | /**
4 | * Created by Sai on 2016/7/13.
5 | */
6 | public interface IPickerViewData {
7 | String getPickerViewText();
8 | }
9 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/utils/PickerViewAnimateUtil.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.utils;
2 |
3 | import android.view.Gravity;
4 |
5 | import com.bigkoo.pickerview.R;
6 |
7 | /**
8 | * Created by Sai on 15/8/9.
9 | */
10 | public class PickerViewAnimateUtil {
11 | private static final int INVALID = -1;
12 | /**
13 | * Get default animation resource when not defined by the user
14 | *
15 | * @param gravity the gravity of the dialog
16 | * @param isInAnimation determine if is in or out animation. true when is is
17 | * @return the id of the animation resource
18 | */
19 | public static int getAnimationResource(int gravity, boolean isInAnimation) {
20 | switch (gravity) {
21 | case Gravity.BOTTOM:
22 | return isInAnimation ? R.anim.slide_in_bottom : R.anim.slide_out_bottom;
23 | }
24 | return INVALID;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/view/BasePickerView.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.view;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.view.Gravity;
6 | import android.view.LayoutInflater;
7 | import android.view.MotionEvent;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.view.animation.Animation;
11 | import android.view.animation.AnimationUtils;
12 | import android.widget.FrameLayout;
13 |
14 | import com.bigkoo.pickerview.utils.PickerViewAnimateUtil;
15 | import com.bigkoo.pickerview.R;
16 | import com.bigkoo.pickerview.listener.OnDismissListener;
17 |
18 | /**
19 | * Created by Sai on 15/11/22.
20 | * 精仿iOSPickerViewController控件
21 | */
22 | public class BasePickerView {
23 | private final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
24 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM
25 | );
26 |
27 | private Context context;
28 | protected ViewGroup contentContainer;
29 | private ViewGroup decorView;//activity的根View
30 | private ViewGroup rootView;//附加View 的 根View
31 |
32 | private OnDismissListener onDismissListener;
33 | private boolean dismissing;
34 |
35 | private Animation outAnim;
36 | private Animation inAnim;
37 | private boolean isShowing;
38 | private int gravity = Gravity.BOTTOM;
39 |
40 | public BasePickerView(Context context){
41 | this.context = context;
42 |
43 | initViews();
44 | init();
45 | initEvents();
46 | }
47 |
48 | protected void initViews(){
49 | LayoutInflater layoutInflater = LayoutInflater.from(context);
50 | decorView = (ViewGroup) ((Activity)context).getWindow().getDecorView().findViewById(android.R.id.content);
51 | rootView = (ViewGroup) layoutInflater.inflate(R.layout.layout_basepickerview, decorView, false);
52 | rootView.setLayoutParams(new FrameLayout.LayoutParams(
53 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
54 | ));
55 | contentContainer = (ViewGroup) rootView.findViewById(R.id.content_container);
56 | contentContainer.setLayoutParams(params);
57 | }
58 |
59 | protected void init() {
60 | inAnim = getInAnimation();
61 | outAnim = getOutAnimation();
62 | }
63 | protected void initEvents() {
64 | }
65 | /**
66 | * show的时候调用
67 | *
68 | * @param view 这个View
69 | */
70 | private void onAttached(View view) {
71 | decorView.addView(view);
72 | contentContainer.startAnimation(inAnim);
73 | }
74 | /**
75 | * 添加这个View到Activity的根视图
76 | */
77 | public void show() {
78 | if (isShowing()) {
79 | return;
80 | }
81 | isShowing = true;
82 | onAttached(rootView);
83 | }
84 | /**
85 | * 检测该View是不是已经添加到根视图
86 | * @return 如果视图已经存在该View返回true
87 | */
88 | public boolean isShowing() {
89 | return rootView.getParent() != null || isShowing;
90 | }
91 |
92 | public void dismiss() {
93 | if (dismissing) {
94 | return;
95 | }
96 |
97 | dismissing = true;
98 |
99 | //消失动画
100 | outAnim.setAnimationListener(new Animation.AnimationListener() {
101 | @Override
102 | public void onAnimationStart(Animation animation) {
103 |
104 | }
105 |
106 | @Override
107 | public void onAnimationEnd(Animation animation) {
108 | decorView.post(new Runnable() {
109 | @Override
110 | public void run() {
111 | dismissImmediately();
112 | }
113 | });
114 | }
115 |
116 | @Override
117 | public void onAnimationRepeat(Animation animation) {
118 |
119 | }
120 | });
121 | contentContainer.startAnimation(outAnim);
122 | }
123 |
124 | public void dismissImmediately() {
125 | //从activity根视图移除
126 | decorView.removeView(rootView);
127 | isShowing = false;
128 | dismissing = false;
129 | if (onDismissListener != null) {
130 | onDismissListener.onDismiss(BasePickerView.this);
131 | }
132 |
133 | }
134 | public Animation getInAnimation() {
135 | int res = PickerViewAnimateUtil.getAnimationResource(this.gravity, true);
136 | return AnimationUtils.loadAnimation(context, res);
137 | }
138 |
139 | public Animation getOutAnimation() {
140 | int res = PickerViewAnimateUtil.getAnimationResource(this.gravity, false);
141 | return AnimationUtils.loadAnimation(context, res);
142 | }
143 |
144 | public BasePickerView setOnDismissListener(OnDismissListener onDismissListener) {
145 | this.onDismissListener = onDismissListener;
146 | return this;
147 | }
148 |
149 | public BasePickerView setCancelable(boolean isCancelable) {
150 | View view = rootView.findViewById(R.id.outmost_container);
151 |
152 | if (isCancelable) {
153 | view.setOnTouchListener(onCancelableTouchListener);
154 | }
155 | else{
156 | view.setOnTouchListener(null);
157 | }
158 | return this;
159 | }
160 | /**
161 | * Called when the user touch on black overlay in order to dismiss the dialog
162 | */
163 | private final View.OnTouchListener onCancelableTouchListener = new View.OnTouchListener() {
164 | @Override
165 | public boolean onTouch(View v, MotionEvent event) {
166 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
167 | dismiss();
168 | }
169 | return false;
170 | }
171 | };
172 |
173 | public View findViewById(int id){
174 | return contentContainer.findViewById(id);
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelOptions.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.view;
2 |
3 | import java.util.ArrayList;
4 | import android.view.View;
5 |
6 | import com.bigkoo.pickerview.R;
7 | import com.bigkoo.pickerview.adapter.ArrayWheelAdapter;
8 | import com.bigkoo.pickerview.lib.WheelView;
9 | import com.bigkoo.pickerview.listener.OnItemSelectedListener;
10 |
11 | public class WheelOptions {
12 | private View view;
13 | private WheelView wv_option1;
14 | private WheelView wv_option2;
15 | private WheelView wv_option3;
16 |
17 | private ArrayList mOptions1Items;
18 | private ArrayList> mOptions2Items;
19 | private ArrayList>> mOptions3Items;
20 |
21 | private boolean linkage = false;
22 | private OnItemSelectedListener wheelListener_option1;
23 | private OnItemSelectedListener wheelListener_option2;
24 |
25 | public View getView() {
26 | return view;
27 | }
28 |
29 | public void setView(View view) {
30 | this.view = view;
31 | }
32 |
33 | public WheelOptions(View view) {
34 | super();
35 | this.view = view;
36 | setView(view);
37 | }
38 |
39 | public void setPicker(ArrayList optionsItems) {
40 | setPicker(optionsItems, null, null, false);
41 | }
42 |
43 | public void setPicker(ArrayList options1Items,
44 | ArrayList> options2Items, boolean linkage) {
45 | setPicker(options1Items, options2Items, null, linkage);
46 | }
47 |
48 | public void setPicker(ArrayList options1Items,
49 | ArrayList> options2Items,
50 | ArrayList>> options3Items,
51 | boolean linkage) {
52 | this.linkage = linkage;
53 | this.mOptions1Items = options1Items;
54 | this.mOptions2Items = options2Items;
55 | this.mOptions3Items = options3Items;
56 | int len = ArrayWheelAdapter.DEFAULT_LENGTH;
57 | if (this.mOptions3Items == null)
58 | len = 8;
59 | if (this.mOptions2Items == null)
60 | len = 12;
61 | // 选项1
62 | wv_option1 = (WheelView) view.findViewById(R.id.options1);
63 | wv_option1.setAdapter(new ArrayWheelAdapter(mOptions1Items, len));// 设置显示数据
64 | wv_option1.setCurrentItem(0);// 初始化时显示的数据
65 | // 选项2
66 | wv_option2 = (WheelView) view.findViewById(R.id.options2);
67 | if (mOptions2Items != null)
68 | wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(0)));// 设置显示数据
69 | wv_option2.setCurrentItem(wv_option1.getCurrentItem());// 初始化时显示的数据
70 | // 选项3
71 | wv_option3 = (WheelView) view.findViewById(R.id.options3);
72 | if (mOptions3Items != null)
73 | wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items.get(0).get(0)));// 设置显示数据
74 | wv_option3.setCurrentItem(wv_option3.getCurrentItem());// 初始化时显示的数据
75 |
76 | int textSize = 25;
77 |
78 | wv_option1.setTextSize(textSize);
79 | wv_option2.setTextSize(textSize);
80 | wv_option3.setTextSize(textSize);
81 |
82 | if (this.mOptions2Items == null)
83 | wv_option2.setVisibility(View.GONE);
84 | if (this.mOptions3Items == null)
85 | wv_option3.setVisibility(View.GONE);
86 |
87 | // 联动监听器
88 | wheelListener_option1 = new OnItemSelectedListener() {
89 |
90 | @Override
91 | public void onItemSelected(int index) {
92 | int opt2Select = 0;
93 | if (mOptions2Items != null) {
94 | opt2Select = wv_option2.getCurrentItem();//上一个opt2的选中位置
95 | //新opt2的位置,判断如果旧位置没有超过数据范围,则沿用旧位置,否则选中最后一项
96 | opt2Select = opt2Select >= mOptions2Items.get(index).size() - 1 ? mOptions2Items.get(index).size() - 1 : opt2Select;
97 |
98 | wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items.get(index)));
99 | wv_option2.setCurrentItem(opt2Select);
100 | }
101 | if (mOptions3Items != null) {
102 | wheelListener_option2.onItemSelected(opt2Select);
103 | }
104 | }
105 | };
106 | wheelListener_option2 = new OnItemSelectedListener() {
107 |
108 | @Override
109 | public void onItemSelected(int index) {
110 | if (mOptions3Items != null) {
111 | int opt1Select = wv_option1.getCurrentItem();
112 | opt1Select = opt1Select >= mOptions3Items.size() - 1 ? mOptions3Items.size() - 1 : opt1Select;
113 | index = index >= mOptions2Items.get(opt1Select).size() - 1 ? mOptions2Items.get(opt1Select).size() - 1 : index;
114 | int opt3 = wv_option3.getCurrentItem();//上一个opt3的选中位置
115 | //新opt3的位置,判断如果旧位置没有超过数据范围,则沿用旧位置,否则选中最后一项
116 | opt3 = opt3 >= mOptions3Items.get(opt1Select).get(index).size() - 1 ? mOptions3Items.get(opt1Select).get(index).size() - 1 : opt3;
117 |
118 | wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items.get(wv_option1.getCurrentItem()).get(index)));
119 | wv_option3.setCurrentItem(opt3);
120 |
121 | }
122 | }
123 | };
124 |
125 | // // 添加联动监听
126 | if (options2Items != null && linkage)
127 | wv_option1.setOnItemSelectedListener(wheelListener_option1);
128 | if (options3Items != null && linkage)
129 | wv_option2.setOnItemSelectedListener(wheelListener_option2);
130 | }
131 |
132 | /**
133 | * 设置选项的单位
134 | * @param label1 单位
135 | * @param label2 单位
136 | * @param label3 单位
137 | */
138 | public void setLabels(String label1, String label2, String label3) {
139 | if (label1 != null)
140 | wv_option1.setLabel(label1);
141 | if (label2 != null)
142 | wv_option2.setLabel(label2);
143 | if (label3 != null)
144 | wv_option3.setLabel(label3);
145 | }
146 |
147 | /**
148 | * 设置是否循环滚动
149 | * @param cyclic 是否循环
150 | */
151 | public void setCyclic(boolean cyclic) {
152 | wv_option1.setCyclic(cyclic);
153 | wv_option2.setCyclic(cyclic);
154 | wv_option3.setCyclic(cyclic);
155 | }
156 |
157 | /**
158 | * 分别设置第一二三级是否循环滚动
159 | * @param cyclic1,cyclic2,cyclic3 是否循环
160 | */
161 | public void setCyclic(boolean cyclic1,boolean cyclic2,boolean cyclic3) {
162 | wv_option1.setCyclic(cyclic1);
163 | wv_option2.setCyclic(cyclic2);
164 | wv_option3.setCyclic(cyclic3);
165 | }
166 | /**
167 | * 设置第二级是否循环滚动
168 | * @param cyclic 是否循环
169 | */
170 | public void setOption2Cyclic(boolean cyclic) {
171 | wv_option2.setCyclic(cyclic);
172 | }
173 |
174 | /**
175 | * 设置第三级是否循环滚动
176 | * @param cyclic 是否循环
177 | */
178 | public void setOption3Cyclic(boolean cyclic) {
179 | wv_option3.setCyclic(cyclic);
180 | }
181 |
182 | /**
183 | * 返回当前选中的结果对应的位置数组 因为支持三级联动效果,分三个级别索引,0,1,2
184 | * @return 索引数组
185 | */
186 | public int[] getCurrentItems() {
187 | int[] currentItems = new int[3];
188 | currentItems[0] = wv_option1.getCurrentItem();
189 | currentItems[1] = wv_option2.getCurrentItem();
190 | currentItems[2] = wv_option3.getCurrentItem();
191 | return currentItems;
192 | }
193 |
194 | public void setCurrentItems(int option1, int option2, int option3) {
195 | if(linkage){
196 | itemSelected(option1, option2, option3);
197 | }
198 | wv_option1.setCurrentItem(option1);
199 | wv_option2.setCurrentItem(option2);
200 | wv_option3.setCurrentItem(option3);
201 | }
202 |
203 | private void itemSelected(int opt1Select, int opt2Select, int opt3Select) {
204 | if (mOptions2Items != null) {
205 | wv_option2.setAdapter(new ArrayWheelAdapter(mOptions2Items
206 | .get(opt1Select)));
207 | wv_option2.setCurrentItem(opt2Select);
208 | }
209 | if (mOptions3Items != null) {
210 | wv_option3.setAdapter(new ArrayWheelAdapter(mOptions3Items
211 | .get(opt1Select).get(
212 | opt2Select)));
213 | wv_option3.setCurrentItem(opt3Select);
214 | }
215 | }
216 |
217 |
218 | }
219 |
--------------------------------------------------------------------------------
/pickerview/src/main/java/com/bigkoo/pickerview/view/WheelTime.java:
--------------------------------------------------------------------------------
1 | package com.bigkoo.pickerview.view;
2 |
3 | import java.text.DateFormat;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | import com.bigkoo.pickerview.R;
9 | import com.bigkoo.pickerview.TimePickerView.Type;
10 | import com.bigkoo.pickerview.adapter.NumericWheelAdapter;
11 | import com.bigkoo.pickerview.lib.WheelView;
12 | import com.bigkoo.pickerview.listener.OnItemSelectedListener;
13 |
14 | import android.content.Context;
15 | import android.view.View;
16 |
17 |
18 | public class WheelTime {
19 | public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
20 | private View view;
21 | private WheelView wv_year;
22 | private WheelView wv_month;
23 | private WheelView wv_day;
24 | private WheelView wv_hours;
25 | private WheelView wv_mins;
26 |
27 | private Type type;
28 | public static final int DEFULT_START_YEAR = 1990;
29 | public static final int DEFULT_END_YEAR = 2100;
30 | private int startYear = DEFULT_START_YEAR;
31 | private int endYear = DEFULT_END_YEAR;
32 |
33 |
34 |
35 | public WheelTime(View view) {
36 | super();
37 | this.view = view;
38 | type = Type.ALL;
39 | setView(view);
40 | }
41 | public WheelTime(View view,Type type) {
42 | super();
43 | this.view = view;
44 | this.type = type;
45 | setView(view);
46 | }
47 | public void setPicker(int year ,int month,int day){
48 | this.setPicker(year, month, day, 0, 0);
49 | }
50 |
51 | public void setPicker(int year ,int month ,int day,int h,int m) {
52 | // 添加大小月月份并将其转换为list,方便之后的判断
53 | String[] months_big = { "1", "3", "5", "7", "8", "10", "12" };
54 | String[] months_little = { "4", "6", "9", "11" };
55 |
56 | final List list_big = Arrays.asList(months_big);
57 | final List list_little = Arrays.asList(months_little);
58 |
59 | Context context = view.getContext();
60 | // 年
61 | wv_year = (WheelView) view.findViewById(R.id.year);
62 | wv_year.setAdapter(new NumericWheelAdapter(startYear, endYear));// 设置"年"的显示数据
63 | wv_year.setLabel(context.getString(R.string.pickerview_year));// 添加文字
64 | wv_year.setCurrentItem(year - startYear);// 初始化时显示的数据
65 |
66 | // 月
67 | wv_month = (WheelView) view.findViewById(R.id.month);
68 | wv_month.setAdapter(new NumericWheelAdapter(1, 12));
69 | wv_month.setLabel(context.getString(R.string.pickerview_month));
70 | wv_month.setCurrentItem(month);
71 |
72 | // 日
73 | wv_day = (WheelView) view.findViewById(R.id.day);
74 | // 判断大小月及是否闰年,用来确定"日"的数据
75 | if (list_big.contains(String.valueOf(month + 1))) {
76 | wv_day.setAdapter(new NumericWheelAdapter(1, 31));
77 | } else if (list_little.contains(String.valueOf(month + 1))) {
78 | wv_day.setAdapter(new NumericWheelAdapter(1, 30));
79 | } else {
80 | // 闰年
81 | if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
82 | wv_day.setAdapter(new NumericWheelAdapter(1, 29));
83 | else
84 | wv_day.setAdapter(new NumericWheelAdapter(1, 28));
85 | }
86 | wv_day.setLabel(context.getString(R.string.pickerview_day));
87 | wv_day.setCurrentItem(day - 1);
88 |
89 |
90 | wv_hours = (WheelView)view.findViewById(R.id.hour);
91 | wv_hours.setAdapter(new NumericWheelAdapter(0, 23));
92 | wv_hours.setLabel(context.getString(R.string.pickerview_hours));// 添加文字
93 | wv_hours.setCurrentItem(h);
94 |
95 | wv_mins = (WheelView)view.findViewById(R.id.min);
96 | wv_mins.setAdapter(new NumericWheelAdapter(0, 59));
97 | wv_mins.setLabel(context.getString(R.string.pickerview_minutes));// 添加文字
98 | wv_mins.setCurrentItem(m);
99 |
100 | // 添加"年"监听
101 | OnItemSelectedListener wheelListener_year = new OnItemSelectedListener() {
102 | @Override
103 | public void onItemSelected(int index) {
104 | int year_num = index + startYear;
105 | // 判断大小月及是否闰年,用来确定"日"的数据
106 | int maxItem = 30;
107 | if (list_big
108 | .contains(String.valueOf(wv_month.getCurrentItem() + 1))) {
109 | wv_day.setAdapter(new NumericWheelAdapter(1, 31));
110 | maxItem = 31;
111 | } else if (list_little.contains(String.valueOf(wv_month
112 | .getCurrentItem() + 1))) {
113 | wv_day.setAdapter(new NumericWheelAdapter(1, 30));
114 | maxItem = 30;
115 | } else {
116 | if ((year_num % 4 == 0 && year_num % 100 != 0)
117 | || year_num % 400 == 0){
118 | wv_day.setAdapter(new NumericWheelAdapter(1, 29));
119 | maxItem = 29;
120 | }
121 | else{
122 | wv_day.setAdapter(new NumericWheelAdapter(1, 28));
123 | maxItem = 28;
124 | }
125 | }
126 | if (wv_day.getCurrentItem() > maxItem - 1){
127 | wv_day.setCurrentItem(maxItem - 1);
128 | }
129 | }
130 | };
131 | // 添加"月"监听
132 | OnItemSelectedListener wheelListener_month = new OnItemSelectedListener() {
133 | @Override
134 | public void onItemSelected(int index) {
135 | int month_num = index + 1;
136 | int maxItem = 30;
137 | // 判断大小月及是否闰年,用来确定"日"的数据
138 | if (list_big.contains(String.valueOf(month_num))) {
139 | wv_day.setAdapter(new NumericWheelAdapter(1, 31));
140 | maxItem = 31;
141 | } else if (list_little.contains(String.valueOf(month_num))) {
142 | wv_day.setAdapter(new NumericWheelAdapter(1, 30));
143 | maxItem = 30;
144 | } else {
145 | if (((wv_year.getCurrentItem() + startYear) % 4 == 0 && (wv_year
146 | .getCurrentItem() + startYear) % 100 != 0)
147 | || (wv_year.getCurrentItem() + startYear) % 400 == 0){
148 | wv_day.setAdapter(new NumericWheelAdapter(1, 29));
149 | maxItem = 29;
150 | }
151 | else{
152 | wv_day.setAdapter(new NumericWheelAdapter(1, 28));
153 | maxItem = 28;
154 | }
155 | }
156 | if (wv_day.getCurrentItem() > maxItem - 1){
157 | wv_day.setCurrentItem(maxItem - 1);
158 | }
159 |
160 | }
161 | };
162 | wv_year.setOnItemSelectedListener(wheelListener_year);
163 | wv_month.setOnItemSelectedListener(wheelListener_month);
164 |
165 | // 根据屏幕密度来指定选择器字体的大小(不同屏幕可能不同)
166 | int textSize = 6;
167 | switch(type){
168 | case ALL:
169 | textSize = textSize * 3;
170 | break;
171 | case YEAR_MONTH_DAY:
172 | textSize = textSize * 4;
173 | wv_hours.setVisibility(View.GONE);
174 | wv_mins.setVisibility(View.GONE);
175 | break;
176 | case HOURS_MINS:
177 | textSize = textSize * 4;
178 | wv_year.setVisibility(View.GONE);
179 | wv_month.setVisibility(View.GONE);
180 | wv_day.setVisibility(View.GONE);
181 | break;
182 | case MONTH_DAY_HOUR_MIN:
183 | textSize = textSize * 3;
184 | wv_year.setVisibility(View.GONE);
185 | break;
186 | case YEAR_MONTH:
187 | textSize = textSize * 4;
188 | wv_day.setVisibility(View.GONE);
189 | wv_hours.setVisibility(View.GONE);
190 | wv_mins.setVisibility(View.GONE);
191 | }
192 | wv_day.setTextSize(textSize);
193 | wv_month.setTextSize(textSize);
194 | wv_year.setTextSize(textSize);
195 | wv_hours.setTextSize(textSize);
196 | wv_mins.setTextSize(textSize);
197 |
198 | }
199 |
200 | /**
201 | * 设置是否循环滚动
202 | * @param cyclic
203 | */
204 | public void setCyclic(boolean cyclic){
205 | wv_year.setCyclic(cyclic);
206 | wv_month.setCyclic(cyclic);
207 | wv_day.setCyclic(cyclic);
208 | wv_hours.setCyclic(cyclic);
209 | wv_mins.setCyclic(cyclic);
210 | }
211 | public String getTime() {
212 | StringBuffer sb = new StringBuffer();
213 | sb.append((wv_year.getCurrentItem() + startYear)).append("-")
214 | .append((wv_month.getCurrentItem() + 1)).append("-")
215 | .append((wv_day.getCurrentItem() + 1)).append(" ")
216 | .append(wv_hours.getCurrentItem()).append(":")
217 | .append(wv_mins.getCurrentItem());
218 | return sb.toString();
219 | }
220 |
221 | public View getView() {
222 | return view;
223 | }
224 |
225 | public void setView(View view) {
226 | this.view = view;
227 | }
228 |
229 | public int getStartYear() {
230 | return startYear;
231 | }
232 |
233 | public void setStartYear(int startYear) {
234 | this.startYear = startYear;
235 | }
236 |
237 | public int getEndYear() {
238 | return endYear;
239 | }
240 |
241 | public void setEndYear(int endYear) {
242 | this.endYear = endYear;
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/anim/slide_in_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/anim/slide_out_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/drawable/selector_pickerview_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/layout/include_pickerview_topbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
29 |
30 |
42 |
43 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/layout/layout_basepickerview.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/layout/pickerview_options.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
25 |
26 |
31 |
32 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/layout/pickerview_time.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
24 |
25 |
30 |
31 |
36 |
37 |
42 |
43 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/values/bools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #057dff
4 | #c2daf5
5 | #f5f5f5
6 | #000000
7 | #a8a8a8
8 | #2a2a2a
9 | #d5d5d5
10 |
11 | #60000000
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 44dp
4 |
5 | 10dp
6 |
7 | 30dp
8 |
9 | 16sp
10 | 16sp
11 |
12 | 18sp
13 |
14 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 300
5 |
--------------------------------------------------------------------------------
/pickerview/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 取消
4 | 确定
5 | 年
6 | 月
7 | 日
8 | 时
9 | 分
10 | 秒
11 |
12 |
--------------------------------------------------------------------------------
/preview/pickerdemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/preview/pickerdemo.gif
--------------------------------------------------------------------------------
/preview/pickerdemo1x.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/preview/pickerdemo1x.gif
--------------------------------------------------------------------------------
/preview/pickerdemo_zhangshangshenghuo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangchengcheng/Android-PickerView/37e5eb80bc50a124d79fe5c3a1f1e16f44639475/preview/pickerdemo_zhangshangshenghuo.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':pickerview'
2 |
--------------------------------------------------------------------------------