├── .gitignore
├── CHANGE.md
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── city.json
│ └── city2.json
│ ├── java
│ └── cn
│ │ └── qqtheme
│ │ └── androidpicker
│ │ ├── AddressInitTask.java
│ │ ├── AssetsUtils.java
│ │ └── MainActivity.java
│ └── res
│ ├── anim
│ ├── popup_in.xml
│ └── popup_out.xml
│ ├── layout
│ └── activity_main.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ └── values
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── cn
│ │ └── qqtheme
│ │ └── framework
│ │ ├── AppConfig.java
│ │ ├── adapter
│ │ └── FileAdapter.java
│ │ ├── entity
│ │ └── FileItem.java
│ │ ├── picker
│ │ ├── AddressPicker.java
│ │ ├── ChineseZodiacPicker.java
│ │ ├── ColorPicker.java
│ │ ├── ConstellationPicker.java
│ │ ├── DatePicker.java
│ │ ├── FilePicker.java
│ │ ├── NumberPicker.java
│ │ ├── OptionPicker.java
│ │ ├── SexPicker.java
│ │ ├── TimePicker.java
│ │ └── WheelPicker.java
│ │ ├── popup
│ │ ├── BottomPopup.java
│ │ ├── ConfirmPopup.java
│ │ └── Popup.java
│ │ ├── tool
│ │ └── ScreenHelper.java
│ │ ├── util
│ │ ├── CompatUtils.java
│ │ ├── ConvertUtils.java
│ │ ├── DateUtils.java
│ │ ├── FileUtils.java
│ │ ├── LogUtils.java
│ │ └── StorageUtils.java
│ │ └── widget
│ │ ├── ColorPanelView.java
│ │ ├── MarqueeTextView.java
│ │ └── WheelView.java
│ └── res
│ ├── drawable-hdpi
│ ├── color_picker_cursor_bottom.png
│ ├── color_picker_cursor_top.png
│ ├── file_picker_file.png
│ ├── file_picker_folder.png
│ ├── file_picker_home.png
│ └── file_picker_updir.png
│ └── values
│ └── styles.xml
├── publish.cmd
├── screenshots
├── address.gif
├── address.png
├── chinesezodiac.gif
├── color.gif
├── constellation.gif
├── date.gif
├── dir.gif
├── file.gif
├── number.gif
├── option.gif
└── time.gif
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | /*.iml
2 | /*/*.iml
3 | /.idea
4 | bin/
5 | gen/
6 | .gradle/
7 | build/
8 | /*/build/
9 | local.properties
10 | proguard/
11 | *.log
12 |
--------------------------------------------------------------------------------
/CHANGE.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## [1.0.3] - 2016.01.19
4 | * 日期时间、地址、单项、数字等选择器支持伪循环滚动。
5 |
6 | ## [1.0.2] - 2016.01.15
7 | * 年或月变动时,保持之前选择的日不动:如果之前选择的日是之前年月的最大日,则日自动为该年月的最大日。
8 |
9 | ## [1.0.1] - 2016.01.14
10 | * 精简文件选择器的数据适配器;
11 | * 修改窗口动画的设置方式;
12 | * 添加选择器顶部确定、取消按钮所在容器的背景色设置。
13 |
14 | ## [1.0.0] - 2016.01.13
15 | * 发布到jcenter,支持远程maven依赖。
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Summary
2 | [](https://github.com/gzu-liyujiang/AndroidPicker)
3 | [](https://bintray.com/gzu-liyujiang/maven/AndroidPicker/_latestVersion)
4 | [Jcenter版本列表](http://jcenter.bintray.com/cn/qqtheme/framework/AndroidPicker/) [版本迭代日志](/CHANGE.md)
5 | 安卓选择器类库,包括日期选择器、时间选择器、单项选择器、城市选择器、颜色选择器、文件选择器、目录选择器、数字选择器、星座选择器、生肖选择器等。
6 | 欢迎大伙儿在[issues](https://github.com/gzu-liyujiang/AndroidPicker/issues)提交你的意见或建议
7 |
8 | 项目分支说明:
9 | [Branch_OldAndroidPicker](https://github.com/gzu-liyujiang/AndroidPicker/tree/Branch_OldAndroidPicker)-基于android-wheel的旧版选择器,不再维护;
10 | [Branch_MultiPart](https://github.com/gzu-liyujiang/AndroidPicker/tree/Branch_MultiPart)-WheelPicker、ColorPicker及FilePicker是分开的三个模块;
11 | [master](https://github.com/gzu-liyujiang/AndroidPicker/tree/master)-默认的最新分支,WheelPicker、ColorPicker及FilePicker合并为一个模块。
12 |
13 | # Install
14 | “app”是测试用例;“library”包括WheelPicker、ColorPicker、FilePicker,
15 | WheelPicker包括DatePicker、TimePicker、OptionPicker、AddressPicker、NumberPicker等,
16 | 如果需要所有的的选择器的话,建议依赖“AndroidPicker”。
17 | ```
18 | dependencies {
19 | compile 'cn.qqtheme.framework:AndroidPicker:latest.integration'
20 | //compile 'cn.qqtheme.framework:WheelPicker:latest.integration'
21 | //compile 'cn.qqtheme.framework:ColorPicker:latest.integration'
22 | //compile 'cn.qqtheme.framework:FilePicker:latest.integration'
23 | }
24 | ```
25 | 也可以手动下载本项目,复制“library”命名为“AndroidPicker”,然后:
26 | ```
27 | dependencies {
28 | compile project('AndroidPicker')
29 | }
30 | ```
31 |
32 | ### 窗口进入退出动画(可选,默认动画为淡入淡出)
33 | ```xml
34 |
35 |
39 |
40 | ```
41 | ```java
42 | picker.setAnimationStyle(R.style.Animation_CustomPopup);
43 | ```
44 |
45 | # Sample
46 | 日期选择器:
47 | ```java
48 | DatePicker picker = new DatePicker(this);
49 | picker.setRange(1990, 2015);//年份范围
50 | picker.setOnDatePickListener(new DatePicker.OnYearMonthDayPickListener() {
51 | @Override
52 | public void onDatePicked(String year, String month, String day) {
53 | showToast(year + "-" + month + "-" + day);
54 | }
55 | });
56 | picker.show();
57 | ```
58 |
59 | 时间选择器:
60 | ```java
61 | //默认选中当前时间
62 | TimePicker picker = new TimePicker(this);
63 | picker.setTopLineVisible(false);
64 | picker.setOnTimePickListener(new TimePicker.OnTimePickListener() {
65 | @Override
66 | public void onTimePicked(String hour, String minute) {
67 | showToast(hour + ":" + minute);
68 | }
69 | });
70 | picker.show();
71 | ```
72 |
73 | 单项选择器(可用于性别、学历、职业、星座等选择):
74 | ```java
75 | OptionPicker picker = new OptionPicker(this, new String[]{
76 | "第一项", "第二项", "这是一个很长很长很长很长很长很长很长很长很长的很长很长的很长很长的项"
77 | });
78 | picker.setOffset(2);
79 | picker.setSelectedIndex(1);
80 | picker.setTextSize(11);
81 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
82 | @Override
83 | public void onOptionPicked(String option) {
84 | showToast(option);
85 | }
86 | });
87 | picker.show();
88 | ```
89 |
90 | 数字选择器(可用于身高、体重、年龄等选择):
91 | ```java
92 | NumberPicker picker = new NumberPicker(this);
93 | picker.setOffset(2);//偏移量
94 | picker.setRange(145, 200);//数字范围
95 | picker.setSelectedItem(172);
96 | picker.setLabel("厘米");
97 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
98 | @Override
99 | public void onOptionPicked(String option) {
100 | showToast(option);
101 | }
102 | });
103 | picker.show();
104 | ```
105 |
106 | 地址选择器(含省级、地级、县级):
107 | ```java
108 | ArrayList data = new ArrayList();
109 | String json = AssetsUtils.readText(this, "city.json");
110 | data.addAll(JSON.parseArray(json, AddressPicker.Province.class));
111 | AddressPicker picker = new AddressPicker(this, result);
112 | picker.setSelectedItem("贵州", "贵阳", "花溪");
113 | picker.setOnAddressPickListener(new AddressPicker.OnAddressPickListener() {
114 | @Override
115 | public void onAddressPicked(String province, String city, String county) {
116 | showToast(province + city + county);
117 | }
118 | });
119 | picker.show();
120 | ```
121 |
122 | 地址选择器(含地级、县级):
123 | ```java
124 | ArrayList data = new ArrayList();
125 | String json = AssetsUtils.readText(this, "city2.json");
126 | data.addAll(JSON.parseArray(json, AddressPicker.Province.class));
127 | AddressPicker picker = new AddressPicker(this, data);
128 | picker.setHideProvince(true);
129 | picker.setOnAddressPickListener(new AddressPicker.OnAddressPickListener() {
130 | @Override
131 | public void onAddressPicked(String province, String city, String county) {
132 | showToast(province + city + county);
133 | }
134 | });
135 | picker.show();
136 | ```
137 |
138 | 星座选择器:
139 | ```java
140 | ConstellationPicker picker = new ConstellationPicker(this);
141 | picker.setTopBackgroundColor(0xFFEEEEEE);
142 | picker.setTopLineVisible(false);
143 | picker.setCancelTextColor(0xFF33B5E5);
144 | picker.setSubmitTextColor(0xFF33B5E5);
145 | picker.setTextColor(0xFFFF0000, 0xFFCCCCCC);
146 | picker.setLineColor(0xFFEE0000);
147 | picker.setSelectedItem("射手");
148 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
149 | @Override
150 | public void onOptionPicked(String option) {
151 | showToast(option);
152 | }
153 | });
154 | picker.show();
155 | ```
156 |
157 | 生肖选择器:
158 | ```java
159 | ChineseZodiacPicker picker = new ChineseZodiacPicker(this);
160 | picker.setLineVisible(false);
161 | picker.setSelectedItem("羊");
162 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
163 | @Override
164 | public void onOptionPicked(String option) {
165 | showToast(option);
166 | }
167 | });
168 | picker.show();
169 | ```
170 |
171 | 颜色选择器:
172 | ```java
173 | ColorPicker picker = new ColorPicker(this);
174 | picker.setInitColor(0xFFDD00DD);
175 | picker.setOnColorPickListener(new ColorPicker.OnColorPickListener() {
176 | @Override
177 | public void onColorPicked(int pickedColor) {
178 | showToast(ConvertUtils.toColorString(pickedColor));
179 | }
180 | });
181 | picker.show();
182 | ```
183 |
184 | 文件选择器(需要权限android.permission.READ_EXTERNAL_STORAGE):
185 | ```java
186 | FilePicker picker = new FilePicker(this);
187 | picker.setShowHideDir(false);
188 | picker.setRootPath(StorageUtils.getRootPath(this) + "Download/");
189 | //picker.setAllowExtensions(new String[]{".apk"});
190 | picker.setMode(FilePicker.Mode.File);
191 | picker.setOnFilePickListener(new FilePicker.OnFilePickListener() {
192 | @Override
193 | public void onFilePicked(String currentPath) {
194 | showToast(currentPath);
195 | }
196 | });
197 | picker.show();
198 | ```
199 |
200 | 目录选择器(需要权限android.permission.READ_EXTERNAL_STORAGE):
201 | ```java
202 | FilePicker picker = new FilePicker(this);
203 | picker.setMode(FilePicker.Mode.Directory);
204 | picker.setOnFilePickListener(new FilePicker.OnFilePickListener() {
205 | @Override
206 | public void onFilePicked(String currentPath) {
207 | showToast(currentPath);
208 | }
209 | });
210 | picker.show();
211 | ```
212 |
213 | # Thanks
214 | 库项目修改了使用以下项目:
215 | https://github.com/wangjiegulu/WheelView
216 | https://github.com/jbruchanov/AndroidColorPicker
217 | 示例项目直接使用了以下项目:
218 | https://github.com/alibaba/fastjson
219 |
220 | # Screenshots
221 | 
222 | 
223 | 
224 | 
225 | 
226 | 
227 | 
228 | 
229 | 
230 | 
231 | 
232 |
233 | # Contact
234 |
235 |
236 |
237 |
238 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /*.iml
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | buildTypes {
6 | release {
7 | //是否zip优化
8 | zipAlignEnabled true
9 | //是否移除无用的资源
10 | shrinkResources true
11 | //是否混淆
12 | minifyEnabled true
13 | //混淆配置文件
14 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
15 | }
16 | }
17 |
18 | }
19 |
20 | dependencies {
21 | compile 'com.alibaba:fastjson:1.1.46.android'
22 | //compile project(':library')
23 | compile 'cn.qqtheme.framework:AndroidPicker:latest.integration'
24 | }
25 |
--------------------------------------------------------------------------------
/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 D:\android-develop\android-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/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/assets/city2.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "cities": [
4 | {
5 | "counties": [
6 | {
7 | "areaName": "南明区 ",
8 | "areaId": "520102"
9 | },
10 | {
11 | "areaName": "云岩区",
12 | "areaId": "520103"
13 | },
14 | {
15 | "areaName": "花溪区 ",
16 | "areaId": "520111"
17 | },
18 | {
19 | "areaName": "乌当区 ",
20 | "areaId": "520112"
21 | },
22 | {
23 | "areaName": "白云区",
24 | "areaId": "520113"
25 | },
26 | {
27 | "areaName": "观山湖区",
28 | "areaId": "520115"
29 | },
30 | {
31 | "areaName": "开阳县",
32 | "areaId": "520121"
33 | },
34 | {
35 | "areaName": "息烽县",
36 | "areaId": "520122"
37 | },
38 | {
39 | "areaName": "修文县 ",
40 | "areaId": "520123"
41 | },
42 | {
43 | "areaName": "清镇市",
44 | "areaId": "520181"
45 | }
46 | ],
47 | "areaName": "贵阳市 ",
48 | "areaId": "520100"
49 | },
50 | {
51 | "counties": [
52 | {
53 | "areaName": "钟山区",
54 | "areaId": "520201"
55 | },
56 | {
57 | "areaName": "六枝特区 ",
58 | "areaId": "520203"
59 | },
60 | {
61 | "areaName": "水城县 ",
62 | "areaId": "520221"
63 | },
64 | {
65 | "areaName": "盘县 ",
66 | "areaId": "520222"
67 | }
68 | ],
69 | "areaName": "六盘水市",
70 | "areaId": "520200"
71 | },
72 | {
73 | "counties": [
74 | {
75 | "areaName": "红花岗区 ",
76 | "areaId": "520302"
77 | },
78 | {
79 | "areaName": "汇川区 ",
80 | "areaId": "520303"
81 | },
82 | {
83 | "areaName": "遵义县 ",
84 | "areaId": "520321"
85 | },
86 | {
87 | "areaName": "桐梓县",
88 | "areaId": "520322"
89 | },
90 | {
91 | "areaName": "绥阳县",
92 | "areaId": "520323"
93 | },
94 | {
95 | "areaName": "正安县",
96 | "areaId": "520324"
97 | },
98 | {
99 | "areaName": "道真仡佬族苗族自治县",
100 | "areaId": "520325"
101 | },
102 | {
103 | "areaName": "务川仡佬族苗族自治县 ",
104 | "areaId": "520326"
105 | },
106 | {
107 | "areaName": "凤冈县 ",
108 | "areaId": "520327"
109 | },
110 | {
111 | "areaName": "湄潭县 ",
112 | "areaId": "520328"
113 | },
114 | {
115 | "areaName": "余庆县 ",
116 | "areaId": "520329"
117 | },
118 | {
119 | "areaName": "习水县 ",
120 | "areaId": "520330"
121 | },
122 | {
123 | "areaName": "赤水市",
124 | "areaId": "520381"
125 | },
126 | {
127 | "areaName": "仁怀市",
128 | "areaId": "520382"
129 | }
130 | ],
131 | "areaName": "遵义市 ",
132 | "areaId": "520300"
133 | },
134 | {
135 | "counties": [
136 | {
137 | "areaName": "西秀区 ",
138 | "areaId": "520402"
139 | },
140 | {
141 | "areaName": "平坝区 ",
142 | "areaId": "520403"
143 | },
144 | {
145 | "areaName": "普定县 ",
146 | "areaId": "520422"
147 | },
148 | {
149 | "areaName": "镇宁布依族苗族自治县 ",
150 | "areaId": "520423"
151 | },
152 | {
153 | "areaName": "关岭布依族苗族自治县 ",
154 | "areaId": "520424"
155 | },
156 | {
157 | "areaName": "紫云苗族布依族自治县",
158 | "areaId": "520425"
159 | }
160 | ],
161 | "areaName": "安顺市 ",
162 | "areaId": "520400"
163 | },
164 | {
165 | "counties": [
166 | {
167 | "areaName": "七星关区 ",
168 | "areaId": "520502"
169 | },
170 | {
171 | "areaName": "大方县",
172 | "areaId": "520521"
173 | },
174 | {
175 | "areaName": "黔西县 ",
176 | "areaId": "520522"
177 | },
178 | {
179 | "areaName": "金沙县 ",
180 | "areaId": "520523"
181 | },
182 | {
183 | "areaName": "织金县 ",
184 | "areaId": "520524"
185 | },
186 | {
187 | "areaName": "纳雍县 ",
188 | "areaId": "520525"
189 | },
190 | {
191 | "areaName": "威宁彝族回族苗族自治县 ",
192 | "areaId": "520526"
193 | },
194 | {
195 | "areaName": " 赫章县 ",
196 | "areaId": "520527"
197 | }
198 | ],
199 | "areaName": "毕节市 ",
200 | "areaId": "520500"
201 | },
202 | {
203 | "counties": [
204 | {
205 | "areaName": "碧江区 ",
206 | "areaId": "520602"
207 | },
208 | {
209 | "areaName": "万山区",
210 | "areaId": "520603"
211 | },
212 | {
213 | "areaName": "江口县 ",
214 | "areaId": "520621"
215 | },
216 | {
217 | "areaName": "玉屏侗族自治县",
218 | "areaId": "520622"
219 | },
220 | {
221 | "areaName": "石阡县 ",
222 | "areaId": "520623"
223 | },
224 | {
225 | "areaName": "思南县 ",
226 | "areaId": "520624"
227 | },
228 | {
229 | "areaName": "印江土家族苗族自治县 ",
230 | "areaId": "520625"
231 | },
232 | {
233 | "areaName": "德江县 ",
234 | "areaId": "520626"
235 | },
236 | {
237 | "areaName": "沿河土家族自治县 ",
238 | "areaId": "520627"
239 | },
240 | {
241 | "areaName": "松桃苗族自治县",
242 | "areaId": "520628"
243 | }
244 | ],
245 | "areaName": "铜仁市",
246 | "areaId": "520600"
247 | },
248 | {
249 | "counties": [
250 | {
251 | "areaName": "兴义市 ",
252 | "areaId": "522301"
253 | },
254 | {
255 | "areaName": "兴仁县 ",
256 | "areaId": "522322"
257 | },
258 | {
259 | "areaName": "普安县 ",
260 | "areaId": "522323"
261 | },
262 | {
263 | "areaName": "晴隆县 ",
264 | "areaId": "522324"
265 | },
266 | {
267 | "areaName": "贞丰县 ",
268 | "areaId": "522325"
269 | },
270 | {
271 | "areaName": "望谟县 ",
272 | "areaId": "522326"
273 | },
274 | {
275 | "areaName": "册亨县 ",
276 | "areaId": "522327"
277 | },
278 | {
279 | "areaName": "安龙县 ",
280 | "areaId": "522328"
281 | }
282 | ],
283 | "areaName": "黔西南布依族苗族自治州",
284 | "areaId": "522300"
285 | },
286 | {
287 | "counties": [
288 | {
289 | "areaName": "凯里市 ",
290 | "areaId": "522601"
291 | },
292 | {
293 | "areaName": "黄平县 ",
294 | "areaId": "522622"
295 | },
296 | {
297 | "areaName": "施秉县",
298 | "areaId": "522623"
299 | },
300 | {
301 | "areaName": "三穗县",
302 | "areaId": "522624"
303 | },
304 | {
305 | "areaName": "镇远县 ",
306 | "areaId": "522625"
307 | },
308 | {
309 | "areaName": "岑巩县",
310 | "areaId": "522626"
311 | },
312 | {
313 | "areaName": "天柱县 ",
314 | "areaId": "522627"
315 | },
316 | {
317 | "areaName": "锦屏县",
318 | "areaId": "522628"
319 | },
320 | {
321 | "areaName": "剑河县 ",
322 | "areaId": "522629"
323 | },
324 | {
325 | "areaName": "台江县 ",
326 | "areaId": "522630"
327 | },
328 | {
329 | "areaName": "黎平县 ",
330 | "areaId": "522631"
331 | },
332 | {
333 | "areaName": "榕江县 ",
334 | "areaId": "522632"
335 | },
336 | {
337 | "areaName": "从江县 ",
338 | "areaId": "522633"
339 | },
340 | {
341 | "areaName": "雷山县 ",
342 | "areaId": "522634"
343 | },
344 | {
345 | "areaName": "麻江县",
346 | "areaId": "522635"
347 | },
348 | {
349 | "areaName": "丹寨县",
350 | "areaId": "522636"
351 | }
352 | ],
353 | "areaName": "黔东南苗族侗族自治州",
354 | "areaId": "522600"
355 | },
356 | {
357 | "counties": [
358 | {
359 | "areaName": "都匀市 ",
360 | "areaId": "522701"
361 | },
362 | {
363 | "areaName": "福泉市 ",
364 | "areaId": "522702"
365 | },
366 | {
367 | "areaName": "荔波县 ",
368 | "areaId": "522722"
369 | },
370 | {
371 | "areaName": "贵定县 ",
372 | "areaId": "522723"
373 | },
374 | {
375 | "areaName": "瓮安县",
376 | "areaId": "522725"
377 | },
378 | {
379 | "areaName": "独山县 ",
380 | "areaId": "522726"
381 | },
382 | {
383 | "areaName": "平塘县",
384 | "areaId": "522727"
385 | },
386 | {
387 | "areaName": "罗甸县",
388 | "areaId": "522728"
389 | },
390 | {
391 | "areaName": "长顺县 ",
392 | "areaId": "522729"
393 | },
394 | {
395 | "areaName": "龙里县",
396 | "areaId": "522730"
397 | },
398 | {
399 | "areaName": "惠水县 ",
400 | "areaId": "522731"
401 | },
402 | {
403 | "areaName": "三都水族自治县 ",
404 | "areaId": "522732"
405 | }
406 | ],
407 | "areaName": "黔南布依族苗族自治州 ",
408 | "areaId": "522700"
409 | },
410 | {
411 | "counties": [
412 | {
413 | "areaName": "贵安新区",
414 | "areaId": "529900"
415 | }
416 | ],
417 | "areaName": "贵安新区",
418 | "areaId": "529900"
419 | }
420 | ],
421 | "areaName": "贵州省 ",
422 | "areaId": "520000"
423 | }
424 | ]
--------------------------------------------------------------------------------
/app/src/main/java/cn/qqtheme/androidpicker/AddressInitTask.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.androidpicker;
2 |
3 | import android.app.Activity;
4 | import android.app.ProgressDialog;
5 | import android.os.AsyncTask;
6 | import android.widget.Toast;
7 |
8 | import com.alibaba.fastjson.JSON;
9 |
10 | import java.util.ArrayList;
11 |
12 | import cn.qqtheme.framework.picker.AddressPicker;
13 |
14 | /**
15 | * 获取地址数据并显示地址选择器
16 | *
17 | * @author 李玉江[QQ:1032694760]
18 | * @version 2015/12/15
19 | */
20 | public class AddressInitTask extends AsyncTask> {
21 | private Activity activity;
22 | private ProgressDialog dialog;
23 | private String selectedProvince = "", selectedCity = "", selectedCounty = "";
24 |
25 | public AddressInitTask(Activity activity) {
26 | this.activity = activity;
27 | dialog = ProgressDialog.show(activity, null, "正在初始化数据...", true, true);
28 | }
29 |
30 | @Override
31 | protected ArrayList doInBackground(String... params) {
32 | if (params != null) {
33 | switch (params.length) {
34 | case 1:
35 | selectedProvince = params[0];
36 | break;
37 | case 2:
38 | selectedProvince = params[0];
39 | selectedCity = params[1];
40 | break;
41 | case 3:
42 | selectedProvince = params[0];
43 | selectedCity = params[1];
44 | selectedCounty = params[2];
45 | break;
46 | default:
47 | break;
48 | }
49 | }
50 | ArrayList data = new ArrayList();
51 | try {
52 | String json = AssetsUtils.readText(activity, "city.json");
53 | data.addAll(JSON.parseArray(json, AddressPicker.Province.class));
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | return data;
58 | }
59 |
60 | @Override
61 | protected void onPostExecute(ArrayList result) {
62 | dialog.dismiss();
63 | if (result.size() > 0) {
64 | AddressPicker picker = new AddressPicker(activity, result);
65 | picker.setSelectedItem(selectedProvince, selectedCity, selectedCounty);
66 | picker.setOnAddressPickListener(new AddressPicker.OnAddressPickListener() {
67 | @Override
68 | public void onAddressPicked(String province, String city, String county) {
69 | Toast.makeText(activity, province + city + county, Toast.LENGTH_LONG).show();
70 | }
71 | });
72 | picker.show();
73 | } else {
74 | Toast.makeText(activity, "数据初始化失败", Toast.LENGTH_SHORT).show();
75 | }
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/qqtheme/androidpicker/AssetsUtils.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.androidpicker;
2 |
3 | import android.content.Context;
4 |
5 | import java.io.BufferedReader;
6 | import java.io.InputStream;
7 | import java.io.InputStreamReader;
8 |
9 | import cn.qqtheme.framework.util.LogUtils;
10 |
11 | /**
12 | * 操作安装包中的“assets”目录下的文件
13 | *
14 | * @author 李玉江[QQ :1023694760]
15 | * @version 2013 -11-2
16 | */
17 | public class AssetsUtils {
18 |
19 | /**
20 | * read file content
21 | *
22 | * @param context the context
23 | * @param assetPath the asset path
24 | * @return String string
25 | */
26 | public static String readText(Context context, String assetPath) {
27 | LogUtils.debug("read assets file as text: " + assetPath);
28 | try {
29 | StringBuilder sb = new StringBuilder();
30 | InputStream is = context.getAssets().open(assetPath);
31 | BufferedReader br = new BufferedReader(new InputStreamReader(is,
32 | "utf-8"));
33 | while (br.ready()) {
34 | String line = br.readLine();
35 | if (line != null) {
36 | // 读出来文件末尾多了“null”?
37 | sb.append(line).append("\n");
38 | }
39 | }
40 | br.close();
41 | is.close();
42 | return sb.toString();
43 | } catch (Exception e) {
44 | LogUtils.error(e);
45 | return "";
46 | }
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/qqtheme/androidpicker/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.androidpicker;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.Toast;
9 |
10 | import com.alibaba.fastjson.JSON;
11 |
12 | import java.util.ArrayList;
13 |
14 | import cn.qqtheme.framework.picker.AddressPicker;
15 | import cn.qqtheme.framework.picker.ChineseZodiacPicker;
16 | import cn.qqtheme.framework.picker.ColorPicker;
17 | import cn.qqtheme.framework.picker.ConstellationPicker;
18 | import cn.qqtheme.framework.picker.DatePicker;
19 | import cn.qqtheme.framework.picker.FilePicker;
20 | import cn.qqtheme.framework.picker.NumberPicker;
21 | import cn.qqtheme.framework.picker.OptionPicker;
22 | import cn.qqtheme.framework.picker.SexPicker;
23 | import cn.qqtheme.framework.picker.TimePicker;
24 | import cn.qqtheme.framework.util.ConvertUtils;
25 | import cn.qqtheme.framework.util.StorageUtils;
26 |
27 | public class MainActivity extends Activity {
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | setContentView(R.layout.activity_main);
33 | }
34 |
35 | @Override
36 | public void onBackPressed() {
37 | System.exit(0);
38 | android.os.Process.killProcess(android.os.Process.myPid());
39 | finish();
40 | }
41 |
42 | private void showToast(String msg) {
43 | Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
44 | }
45 |
46 | public void onAnimationStyle(View view) {
47 | NumberPicker picker = new NumberPicker(this);
48 | picker.setAnimationStyle(R.style.Animation_CustomPopup);
49 | picker.setOffset(2);//偏移量
50 | picker.setRange(40, 100);//数字范围
51 | picker.setSelectedItem(65);
52 | picker.setLabel("Kg");
53 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
54 | @Override
55 | public void onOptionPicked(String option) {
56 | showToast(option);
57 | }
58 | });
59 | picker.show();
60 | }
61 |
62 | public void onYearMonthDayPicker(View view) {
63 | DatePicker picker = new DatePicker(this);
64 | picker.setRange(2000, 2016);
65 | picker.setSelectedItem(2015, 10, 10);
66 | picker.setOnDatePickListener(new DatePicker.OnYearMonthDayPickListener() {
67 | @Override
68 | public void onDatePicked(String year, String month, String day) {
69 | showToast(year + "-" + month + "-" + day);
70 | }
71 | });
72 | picker.show();
73 | }
74 |
75 | public void onYearMonthPicker(View view) {
76 | DatePicker picker = new DatePicker(this, DatePicker.Mode.YEAR_MONTH);
77 | picker.setRange(1990, 2015);
78 | picker.setOnDatePickListener(new DatePicker.OnYearMonthPickListener() {
79 | @Override
80 | public void onDatePicked(String year, String month) {
81 | showToast(year + "-" + month);
82 | }
83 | });
84 | picker.show();
85 | }
86 |
87 | public void onMonthDayPicker(View view) {
88 | DatePicker picker = new DatePicker(this, DatePicker.Mode.MONTH_DAY);
89 | picker.setOnDatePickListener(new DatePicker.OnMonthDayPickListener() {
90 | @Override
91 | public void onDatePicked(String month, String day) {
92 | showToast(month + "-" + day);
93 | }
94 | });
95 | picker.show();
96 | }
97 |
98 | public void onTimePicker(View view) {
99 | //默认选中当前时间
100 | TimePicker picker = new TimePicker(this);
101 | picker.setTopLineVisible(false);
102 | picker.setOnTimePickListener(new TimePicker.OnTimePickListener() {
103 | @Override
104 | public void onTimePicked(String hour, String minute) {
105 | showToast(hour + ":" + minute);
106 | }
107 | });
108 | picker.show();
109 | }
110 |
111 | public void onOptionPicker(View view) {
112 | OptionPicker picker = new OptionPicker(this, new String[]{
113 | "第一项", "第二项", "这是一个很长很长很长很长很长很长很长很长很长的很长很长的很长很长的项"
114 | });
115 | picker.setOffset(2);
116 | picker.setSelectedIndex(1);
117 | picker.setTextSize(11);
118 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
119 | @Override
120 | public void onOptionPicked(String option) {
121 | showToast(option);
122 | }
123 | });
124 | picker.show();
125 | }
126 |
127 | public void onConstellationPicker(View view) {
128 | ConstellationPicker picker = new ConstellationPicker(this);
129 | picker.setTopBackgroundColor(0xFFEEEEEE);
130 | picker.setTopLineVisible(false);
131 | picker.setCancelTextColor(0xFF33B5E5);
132 | picker.setSubmitTextColor(0xFF33B5E5);
133 | picker.setTextColor(0xFFFF0000, 0xFFCCCCCC);
134 | picker.setLineColor(0xFFEE0000);
135 | picker.setSelectedItem("射手");
136 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
137 | @Override
138 | public void onOptionPicked(String option) {
139 | showToast(option);
140 | }
141 | });
142 | picker.show();
143 | }
144 |
145 | public void onChineseZodiacPicker(View view) {
146 | ChineseZodiacPicker picker = new ChineseZodiacPicker(this);
147 | picker.setLineVisible(false);
148 | picker.setSelectedItem("羊");
149 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
150 | @Override
151 | public void onOptionPicked(String option) {
152 | showToast(option);
153 | }
154 | });
155 | picker.show();
156 | }
157 |
158 | public void onNumberPicker(View view) {
159 | NumberPicker picker = new NumberPicker(this);
160 | picker.setOffset(2);//偏移量
161 | picker.setRange(145, 200);//数字范围
162 | picker.setSelectedItem(172);
163 | picker.setLabel("厘米");
164 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
165 | @Override
166 | public void onOptionPicked(String option) {
167 | showToast(option);
168 | }
169 | });
170 | picker.show();
171 | }
172 |
173 | public void onSexPicker(View view) {
174 | SexPicker picker = new SexPicker(this);
175 | //picker.onlyMaleAndFemale();
176 | picker.setOnOptionPickListener(new OptionPicker.OnOptionPickListener() {
177 | @Override
178 | public void onOptionPicked(String option) {
179 | showToast(option);
180 | }
181 | });
182 | picker.show();
183 | }
184 |
185 | public void onAddressPicker(View view) {
186 | new AddressInitTask(this).execute("贵州", "毕节", "纳雍");
187 | }
188 |
189 | public void onAddress2Picker(View view) {
190 | try {
191 | ArrayList data = new ArrayList();
192 | String json = AssetsUtils.readText(this, "city2.json");
193 | data.addAll(JSON.parseArray(json, AddressPicker.Province.class));
194 | AddressPicker picker = new AddressPicker(this, data);
195 | picker.setHideProvince(true);
196 | picker.setSelectedItem("贵州", "贵阳", "花溪");
197 | picker.setOnAddressPickListener(new AddressPicker.OnAddressPickListener() {
198 | @Override
199 | public void onAddressPicked(String province, String city, String county) {
200 | showToast(province + city + county);
201 | }
202 | });
203 | picker.show();
204 | } catch (Exception e) {
205 | showToast(e.toString());
206 | }
207 | }
208 |
209 | public void onColorPicker(View view) {
210 | ColorPicker picker = new ColorPicker(this);
211 | picker.setInitColor(0xDD00DD);
212 | picker.setOnColorPickListener(new ColorPicker.OnColorPickListener() {
213 | @Override
214 | public void onColorPicked(int pickedColor) {
215 | showToast(ConvertUtils.toColorString(pickedColor));
216 | }
217 | });
218 | picker.show();
219 | }
220 |
221 | public void onFilePicker(View view) {
222 | FilePicker picker = new FilePicker(this);
223 | picker.setShowHideDir(false);
224 | picker.setRootPath(StorageUtils.getRootPath(this) + "Download/");
225 | //picker.setAllowExtensions(new String[]{".apk"});
226 | picker.setMode(FilePicker.Mode.File);
227 | picker.setOnFilePickListener(new FilePicker.OnFilePickListener() {
228 | @Override
229 | public void onFilePicked(String currentPath) {
230 | showToast(currentPath);
231 | }
232 | });
233 | picker.show();
234 | }
235 |
236 | public void onDirPicker(View view) {
237 | FilePicker picker = new FilePicker(this);
238 | picker.setMode(FilePicker.Mode.Directory);
239 | picker.setOnFilePickListener(new FilePicker.OnFilePickListener() {
240 | @Override
241 | public void onFilePicked(String currentPath) {
242 | showToast(currentPath);
243 | }
244 | });
245 | picker.show();
246 | }
247 |
248 | public void onContact(View view) {
249 | Intent intent = new Intent(Intent.ACTION_SENDTO);
250 | intent.setData(Uri.parse("mailto:liyujiang_tk@yeah.net"));
251 | intent.putExtra(Intent.EXTRA_CC, new String[]
252 | {"1032694760@qq.com"});
253 | intent.putExtra(Intent.EXTRA_EMAIL, "");
254 | intent.putExtra(Intent.EXTRA_TEXT, "欢迎提供意您的见或建议");
255 | startActivity(Intent.createChooser(intent, "选择邮件客户端"));
256 | }
257 |
258 | }
259 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/popup_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/popup_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
16 |
17 |
22 |
23 |
28 |
29 |
34 |
35 |
40 |
41 |
46 |
47 |
52 |
53 |
58 |
59 |
64 |
65 |
70 |
71 |
76 |
77 |
82 |
83 |
88 |
89 |
94 |
95 |
100 |
101 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdsjlzx/AndroidPicker/5740268ab0a5da357f0b1d5bd13cbd54202df95c/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AndroidPicker
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | //参考:https://raw.github.com/dm77/barcodescanner/master/build.gradle
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath "com.android.tools.build:gradle:${GRADLE_BUILD_VERSION}"
9 | classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:${GRADLE_BINTRAY_VERSION}"
10 | }
11 | }
12 |
13 | allprojects {
14 | group = PROJ_GROUP
15 | version = PROJ_VERSION
16 |
17 | repositories {
18 | jcenter() //bintray的maven库
19 | mavenCentral() //sonatype的maven库
20 | flatDir {
21 | dirs 'libs' //本地.aar文件
22 | }
23 | }
24 |
25 | ext {
26 | isLibrary = false
27 | pomGroup = PROJ_GROUP
28 | pomArtifactId = "library"
29 | pomVersion = PROJ_VERSION
30 | pomDescription = 'This is library description'
31 | }
32 |
33 | }
34 |
35 | subprojects {
36 | afterEvaluate { Project project ->
37 | ext.pluginContainer = project.getPlugins()
38 | def hasAppPlugin = ext.pluginContainer.hasPlugin("com.android.application")
39 | def hasLibPlugin = ext.pluginContainer.hasPlugin("com.android.library")
40 | if (hasAppPlugin || hasLibPlugin) {
41 | android {
42 | compileSdkVersion COMPILE_SDK_VERSION as int
43 | buildToolsVersion BUILD_TOOL_VERSION
44 |
45 | defaultConfig {
46 | minSdkVersion MIN_SDK_VERSION as int
47 | targetSdkVersion COMPILE_SDK_VERSION as int
48 | versionCode VERSION_CODE as int
49 | versionName VERSION_NAME
50 | }
51 |
52 | buildTypes {
53 | release {
54 | debuggable false
55 | minifyEnabled false
56 | proguardFile getDefaultProguardFile('proguard-android.txt')
57 | }
58 | debug {
59 | debuggable true
60 | minifyEnabled false
61 | }
62 | }
63 |
64 | lintOptions {
65 | abortOnError false
66 | }
67 |
68 | packagingOptions {
69 | exclude 'META-INF/DEPENDENCIES.txt'
70 | exclude 'META-INF/LICENSE.txt'
71 | exclude 'META-INF/NOTICE.txt'
72 | exclude 'META-INF/NOTICE'
73 | exclude 'META-INF/LICENSE'
74 | exclude 'META-INF/DEPENDENCIES'
75 | exclude 'META-INF/notice.txt'
76 | exclude 'META-INF/license.txt'
77 | exclude 'META-INF/dependencies.txt'
78 | exclude 'META-INF/LGPL2.1'
79 | exclude 'META-INF/ASL2.0'
80 | }
81 |
82 | }
83 |
84 | dependencies {
85 | compile "com.android.support:support-v4:${BUILD_TOOL_VERSION}"
86 | compile "com.android.support:support-annotations:${BUILD_TOOL_VERSION}"
87 | }
88 | }
89 |
90 | if (project.isLibrary) {
91 | configure(project) {
92 | // 这个脚本是用来发布库项目到jcenter
93 | apply plugin: 'com.jfrog.bintray'
94 | apply plugin: 'maven-publish'
95 |
96 | version = project.pomVersion //版本号
97 | group = PROJ_GROUP // 包名
98 | project.archivesBaseName = project.pomArtifactId
99 |
100 | task sourcesJar(type: Jar) {
101 | from android.sourceSets.main.java.srcDirs
102 | classifier = 'sources'
103 | }
104 |
105 | task javadoc(type: Javadoc) {
106 | source = android.sourceSets.main.java.srcDirs
107 | classpath += configurations.compile
108 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
109 | exclude '**/BuildConfig.java'
110 | exclude '**/R.java'
111 | failOnError = false
112 | }
113 |
114 | task javadocJar(type: Jar, dependsOn: javadoc) {
115 | classifier = 'javadoc'
116 | from javadoc.destinationDir
117 | }
118 |
119 | javadoc {
120 | options {
121 | encoding "UTF-8"
122 | charSet 'UTF-8'
123 | author true
124 | version true
125 | links "http://docs.oracle.com/javase/7/docs/api"
126 | title project.pomArtifactId
127 | }
128 | }
129 |
130 | publishing {
131 | publications {
132 | mavenJava(MavenPublication) {
133 | artifactId project.pomArtifactId
134 | artifact "${buildDir}/outputs/aar/${project.name}-release.aar"
135 | artifact javadocJar
136 | artifact sourcesJar
137 |
138 | pom.withXml {
139 | Node root = asNode()
140 | root.appendNode('name', project.pomArtifactId)
141 | root.appendNode('description', project.pomDescription)
142 | root.appendNode('url', PROJ_WEBSITE_URL)
143 |
144 | def issues = root.appendNode('issueManagement')
145 | issues.appendNode('system', 'github')
146 | issues.appendNode('url', PROJ_ISSUE_URL)
147 |
148 | def scm = root.appendNode('scm')
149 | scm.appendNode('url', PROJ_GIT_URL)
150 | scm.appendNode('connection', "scm:git:${PROJ_GIT_URL}")
151 | scm.appendNode('developerConnection', "scm:git:${PROJ_GIT_URL}")
152 |
153 | def license = root.appendNode('licenses').appendNode('license')
154 | license.appendNode('name', "The Apache Software License, Version 2.0")
155 | license.appendNode('url', "http://www.apache.org/licenses/LICENSE-2.0.txt")
156 | license.appendNode('distribution', "repo")
157 |
158 | def developer = root.appendNode('developers').appendNode('developer')
159 | developer.appendNode('id', DEVELOPER_ID)
160 | developer.appendNode('name', DEVELOPER_NAME)
161 | developer.appendNode('email', DEVELOPER_EMAIL)
162 |
163 | def dependenciesNode = root.appendNode('dependencies')
164 | configurations.compile.allDependencies.each {
165 | if (it.group && it.name && it.version) {
166 | def dependencyNode = dependenciesNode.appendNode('dependency')
167 | dependencyNode.appendNode('groupId', it.group)
168 | dependencyNode.appendNode('artifactId', it.name)
169 | dependencyNode.appendNode('version', it.version)
170 | }
171 | }
172 | }
173 | }
174 | }
175 | }
176 |
177 | afterEvaluate {
178 | publishing.publications.mavenJava.artifact(bundleRelease)
179 | }
180 |
181 | bintray {
182 | Properties properties = new Properties()
183 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
184 | user = properties.getProperty("bintray.user")
185 | key = properties.getProperty("bintray.apikey")
186 |
187 | publications = ['mavenJava']
188 | publish = true //是否发布
189 |
190 | pkg {
191 | repo = "maven" //上传的中央仓库名称
192 | name = project.pomArtifactId //发布到中央仓库上的项目名字
193 | desc = project.pomDescription
194 | websiteUrl = PROJ_WEBSITE_URL //项目主页
195 | issueTrackerUrl = PROJ_ISSUE_URL //项目讨论页
196 | vcsUrl = PROJ_GIT_URL //项目GIT仓库
197 | licenses = ["Apache-2.0"]
198 | publicDownloadNumbers = true
199 | version {
200 | name = project.pomVersion
201 | desc = project.pomDescription
202 | gpg {
203 | sign = true //是否GPG签名,可使用Gpg4win创建密钥文件
204 | passphrase = properties.getProperty("bintray.gpg.password")
205 | //GPG签名所用密钥
206 | }
207 | mavenCentralSync {
208 | sync = false //是否同步到Maven Central
209 | user = properties.getProperty("sonatype.user") //sonatype用户名
210 | password = properties.getProperty("sonatype.password")
211 | //sonatype密码
212 | close = '1'
213 | }
214 | }
215 | }
216 | }
217 |
218 | }
219 | }
220 | }
221 | }
222 |
223 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdsjlzx/AndroidPicker/5740268ab0a5da357f0b1d5bd13cbd54202df95c/gradle.properties
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdsjlzx/AndroidPicker/5740268ab0a5da357f0b1d5bd13cbd54202df95c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
7 | #distributionUrl=http://127.0.0.1/php-develop/gradle-2.8-all.zip
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /*.iml
3 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | ext {
4 | isLibrary = true
5 | pomArtifactId = "AndroidPicker"
6 | pomDescription = "Picker For Android, include WheelPicker, ColorPicker, FilePicker and so on"
7 | }
8 |
9 | dependencies {
10 | }
11 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/AppConfig.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework;
2 |
3 | /**
4 | * ************************************************************************
5 | * ** _oo0oo_ **
6 | * ** o8888888o **
7 | * ** 88" . "88 **
8 | * ** (| -_- |) **
9 | * ** 0\ = /0 **
10 | * ** ___/'---'\___ **
11 | * ** .' \\\| |// '. **
12 | * ** / \\\||| : |||// \\ **
13 | * ** / _ ||||| -:- |||||- \\ **
14 | * ** | | \\\\ - /// | | **
15 | * ** | \_| ''\---/'' |_/ | **
16 | * ** \ .-\__ '-' __/-. / **
17 | * ** ___'. .' /--.--\ '. .'___ **
18 | * ** ."" '< '.___\_<|>_/___.' >' "". **
19 | * ** | | : '- \'.;'\ _ /';.'/ - ' : | | **
20 | * ** \ \ '_. \_ __\ /__ _/ .-' / / **
21 | * ** ====='-.____'.___ \_____/___.-'____.-'===== **
22 | * ** '=---=' **
23 | * ************************************************************************
24 | * ** 佛祖保佑 镇类之宝 **
25 | * ************************************************************************
26 | *
27 | * @author 李玉江[QQ :1032694760]
28 | * @version 2014-09-05 11:49
29 | */
30 | public class AppConfig {
31 | /**
32 | * The constant DEBUG_ENABLE.
33 | */
34 | public static final boolean DEBUG_ENABLE = BuildConfig.DEBUG;// 是否调试模式
35 | /**
36 | * The constant DEBUG_TAG.
37 | */
38 | public static final String DEBUG_TAG = "liyujiang";// LogCat的标记
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/adapter/FileAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.BaseAdapter;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import java.io.File;
13 | import java.util.ArrayList;
14 |
15 | import cn.qqtheme.framework.entity.FileItem;
16 | import cn.qqtheme.framework.R;
17 | import cn.qqtheme.framework.util.CompatUtils;
18 | import cn.qqtheme.framework.util.ConvertUtils;
19 | import cn.qqtheme.framework.util.FileUtils;
20 | import cn.qqtheme.framework.util.LogUtils;
21 |
22 | /**
23 | * The type File adapter.
24 | */
25 | public class FileAdapter extends BaseAdapter {
26 | /**
27 | * The constant DIR_ROOT.
28 | */
29 | public static final String DIR_ROOT = "..";
30 | /**
31 | * The constant DIR_PARENT.
32 | */
33 | public static final String DIR_PARENT = ".";
34 | private Context context;
35 | private ArrayList data = new ArrayList();
36 | private String rootPath = null;
37 | private String currentPath = null;
38 | private String[] allowExtensions = null;//允许的扩展名
39 | private boolean onlyListDir = false;//是否仅仅读取目录
40 | private boolean showHomeDir = false;//是否显示返回主目录
41 | private boolean showUpDir = true;//是否显示返回上一级
42 | private boolean showHideDir = true;//是否显示隐藏的目录(以“.”开头)
43 | private int homeIcon = R.drawable.file_picker_home;
44 | private int upIcon = R.drawable.file_picker_updir;
45 | private int folderIcon = R.drawable.file_picker_folder;
46 | private int fileIcon = R.drawable.file_picker_file;
47 |
48 | /**
49 | * Instantiates a new File adapter.
50 | *
51 | * @param context the context
52 | */
53 | public FileAdapter(Context context) {
54 | this.context = context;
55 | }
56 |
57 | /**
58 | * Gets current path.
59 | *
60 | * @return the current path
61 | */
62 | public String getCurrentPath() {
63 | return currentPath;
64 | }
65 |
66 | /**
67 | * Sets allow extensions.
68 | *
69 | * @param allowExtensions the allow extensions
70 | */
71 | public void setAllowExtensions(String[] allowExtensions) {
72 | this.allowExtensions = allowExtensions;
73 | }
74 |
75 | /**
76 | * Sets only list dir.
77 | *
78 | * @param onlyListDir the only list dir
79 | */
80 | public void setOnlyListDir(boolean onlyListDir) {
81 | this.onlyListDir = onlyListDir;
82 | }
83 |
84 | /**
85 | * Sets show home dir.
86 | *
87 | * @param showHomeDir the show home dir
88 | */
89 | public void setShowHomeDir(boolean showHomeDir) {
90 | this.showHomeDir = showHomeDir;
91 | }
92 |
93 | /**
94 | * Sets show up dir.
95 | *
96 | * @param showUpDir the show up dir
97 | */
98 | public void setShowUpDir(boolean showUpDir) {
99 | this.showUpDir = showUpDir;
100 | }
101 |
102 | /**
103 | * Sets show hide dir.
104 | *
105 | * @param showHideDir the show hide dir
106 | */
107 | public void setShowHideDir(boolean showHideDir) {
108 | this.showHideDir = showHideDir;
109 | }
110 |
111 | /**
112 | * Load data array list.
113 | *
114 | * @param path the path
115 | */
116 | public void loadData(String path) {
117 | if (path == null) {
118 | LogUtils.warn("current directory is null");
119 | return;
120 | }
121 | ArrayList datas = new ArrayList();
122 | if (rootPath == null) {
123 | rootPath = path;
124 | }
125 | LogUtils.debug("current directory path: " + path);
126 | currentPath = path;
127 | if (showHomeDir) {
128 | //添加“返回主目录”
129 | FileItem fileRoot = new FileItem();
130 | fileRoot.setDirectory(true);
131 | fileRoot.setIcon(homeIcon);
132 | fileRoot.setName(DIR_ROOT);
133 | fileRoot.setSize(0);
134 | fileRoot.setPath(rootPath);
135 | datas.add(fileRoot);
136 | }
137 | if (showUpDir && !path.equals("/")) {
138 | //添加“返回上一级目录”
139 | FileItem fileParent = new FileItem();
140 | fileParent.setDirectory(true);
141 | fileParent.setIcon(upIcon);
142 | fileParent.setName(DIR_PARENT);
143 | fileParent.setSize(0);
144 | fileParent.setPath(new File(path).getParent());
145 | datas.add(fileParent);
146 | }
147 | File[] files;
148 | if (allowExtensions == null) {
149 | if (onlyListDir) {
150 | files = FileUtils.listDirs(path);
151 | } else {
152 | files = FileUtils.listDirsAndFiles(path);
153 | }
154 | } else {
155 | if (onlyListDir) {
156 | files = FileUtils.listDirs(path, allowExtensions);
157 | } else {
158 | files = FileUtils.listDirsAndFiles(path, allowExtensions);
159 | }
160 | }
161 | if (files != null) {
162 | for (File file : files) {
163 | if (!showHideDir && file.getName().startsWith(".")) {
164 | continue;
165 | }
166 | FileItem fileItem = new FileItem();
167 | boolean isDirectory = file.isDirectory();
168 | fileItem.setDirectory(isDirectory);
169 | if (isDirectory) {
170 | fileItem.setIcon(folderIcon);
171 | fileItem.setSize(0);
172 | } else {
173 | fileItem.setIcon(fileIcon);
174 | fileItem.setSize(file.length());
175 | }
176 | fileItem.setName(file.getName());
177 | fileItem.setPath(file.getAbsolutePath());
178 | datas.add(fileItem);
179 | }
180 | }
181 | data.clear();
182 | data.addAll(datas);
183 | notifyDataSetChanged();
184 | }
185 |
186 | @Override
187 | public int getCount() {
188 | return data.size();
189 | }
190 |
191 | @Override
192 | public FileItem getItem(int position) {
193 | return data.get(position);
194 | }
195 |
196 | @Override
197 | public long getItemId(int position) {
198 | return position;
199 | }
200 |
201 | @Override
202 | public View getView(int position, View convertView, ViewGroup parent) {
203 | ViewHolder holder;
204 | if (convertView == null) {
205 | convertView = LayoutInflater.from(context).inflate(android.R.layout.activity_list_item, null);
206 | CompatUtils.setBackground(convertView, ConvertUtils.toStateListDrawable(Color.WHITE, Color.LTGRAY));
207 | holder = new ViewHolder();
208 | holder.imageView = (ImageView) convertView.findViewById(android.R.id.icon);
209 | holder.textView = (TextView) convertView.findViewById(android.R.id.text1);
210 | convertView.setTag(holder);
211 | } else {
212 | holder = (ViewHolder) convertView.getTag();
213 | }
214 | FileItem item = data.get(position);
215 | holder.imageView.setImageResource(item.getIcon());
216 | holder.textView.setText(item.getName());
217 | return convertView;
218 | }
219 |
220 | private class ViewHolder {
221 | ImageView imageView;
222 | TextView textView;
223 | }
224 |
225 | }
226 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/entity/FileItem.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.entity;
2 |
3 | /**
4 | * 文件项信息
5 | *
6 | * @author 李玉江[QQ :1032694760]
7 | * @version 2014 -05-23 18:02
8 | */
9 | public class FileItem {
10 | private int icon;
11 | private String name;
12 | private String path = "/";
13 | private long size = 0;
14 | private boolean isDirectory = false;
15 |
16 | /**
17 | * Sets icon.
18 | *
19 | * @param icon the icon
20 | */
21 | public void setIcon(int icon) {
22 | this.icon = icon;
23 | }
24 |
25 | /**
26 | * Gets icon.
27 | *
28 | * @return the icon
29 | */
30 | public int getIcon() {
31 | return icon;
32 | }
33 |
34 | /**
35 | * Gets name.
36 | *
37 | * @return the name
38 | */
39 | public String getName() {
40 | return name;
41 | }
42 |
43 | /**
44 | * Sets name.
45 | *
46 | * @param name the name
47 | */
48 | public void setName(String name) {
49 | this.name = name;
50 | }
51 |
52 | /**
53 | * Gets path.
54 | *
55 | * @return the path
56 | */
57 | public String getPath() {
58 | return path;
59 | }
60 |
61 | /**
62 | * Sets path.
63 | *
64 | * @param path the path
65 | */
66 | public void setPath(String path) {
67 | this.path = path;
68 | }
69 |
70 | /**
71 | * Gets size.
72 | *
73 | * @return the size
74 | */
75 | public long getSize() {
76 | return size;
77 | }
78 |
79 | /**
80 | * Sets size.
81 | *
82 | * @param size the size
83 | */
84 | public void setSize(long size) {
85 | this.size = size;
86 | }
87 |
88 | /**
89 | * Is directory boolean.
90 | *
91 | * @return the boolean
92 | */
93 | public boolean isDirectory() {
94 | return isDirectory;
95 | }
96 |
97 | /**
98 | * Sets directory.
99 | *
100 | * @param isDirectory the is directory
101 | */
102 | public void setDirectory(boolean isDirectory) {
103 | this.isDirectory = isDirectory;
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/picker/AddressPicker.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.picker;
2 |
3 | import android.app.Activity;
4 | import android.view.Gravity;
5 | import android.view.View;
6 | import android.widget.LinearLayout;
7 |
8 | import java.util.ArrayList;
9 |
10 | import cn.qqtheme.framework.util.LogUtils;
11 | import cn.qqtheme.framework.widget.WheelView;
12 |
13 | /**
14 | * 地址选择器(包括省级、地级、县级)。
15 | * 地址数据见示例项目的“city.json”,来源于国家统计局官网(http://www.stats.gov.cn/tjsj/tjbz/xzqhdm)
16 | *
17 | * @author 李玉江[QQ :1032694760]
18 | * @version 2015 /12/15
19 | */
20 | public class AddressPicker extends WheelPicker {
21 | private ArrayList provinceList = new ArrayList();
22 | private ArrayList> cityList = new ArrayList>();
23 | private ArrayList>> countyList = new ArrayList>>();
24 | private OnAddressPickListener onAddressPickListener;
25 | private String selectedProvince = "", selectedCity = "", selectedCounty = "";
26 | private int selectedProvinceIndex = 0, selectedCityIndex = 0, selectedCountyIndex = 0;
27 | private boolean hideProvince = false;
28 |
29 | /**
30 | * Instantiates a new Address picker.
31 | *
32 | * @param activity the activity
33 | * @param data the data
34 | */
35 | public AddressPicker(Activity activity, ArrayList data) {
36 | super(activity);
37 | int provinceSize = data.size();
38 | //添加省
39 | for (int x = 0; x < provinceSize; x++) {
40 | Province pro = data.get(x);
41 | provinceList.add(pro.getAreaName());
42 | ArrayList cities = pro.getCities();
43 | ArrayList xCities = new ArrayList();
44 | ArrayList> xCounties = new ArrayList>();
45 | int citySize = cities.size();
46 | //添加地市
47 | for (int y = 0; y < citySize; y++) {
48 | City cit = cities.get(y);
49 | xCities.add(cit.getAreaName());
50 | ArrayList counties = cit.getCounties();
51 | ArrayList yCounties = new ArrayList();
52 | int countySize = counties.size();
53 | //添加区县
54 | if (countySize == 0) {
55 | yCounties.add(cit.getAreaName());
56 | } else {
57 | for (int z = 0; z < countySize; z++) {
58 | yCounties.add(counties.get(z).getAreaName());
59 | }
60 | }
61 | xCounties.add(yCounties);
62 | }
63 | cityList.add(xCities);
64 | countyList.add(xCounties);
65 | }
66 | }
67 |
68 | /**
69 | * Sets selected item.
70 | *
71 | * @param province the province
72 | * @param city the city
73 | * @param county the county
74 | */
75 | public void setSelectedItem(String province, String city, String county) {
76 | for (int i = 0; i < provinceList.size(); i++) {
77 | String pro = provinceList.get(i);
78 | if (pro.contains(province)) {
79 | selectedProvinceIndex = i;
80 | LogUtils.debug("init select province: " + pro);
81 | break;
82 | }
83 | }
84 | ArrayList cities = cityList.get(selectedProvinceIndex);
85 | for (int j = 0; j < cities.size(); j++) {
86 | String cit = cities.get(j);
87 | if (cit.contains(city)) {
88 | selectedCityIndex = j;
89 | LogUtils.debug("init select city: " + cit);
90 | break;
91 | }
92 | }
93 | ArrayList counties = countyList.get(selectedProvinceIndex).get(selectedCityIndex);
94 | for (int k = 0; k < counties.size(); k++) {
95 | String cou = counties.get(k);
96 | if (cou.contains(county)) {
97 | selectedCountyIndex = k;
98 | LogUtils.debug("init select county: " + cou);
99 | break;
100 | }
101 | }
102 | LogUtils.debug(String.format("init select index: %s-%s-%s", selectedProvinceIndex, selectedCityIndex, selectedCountyIndex));
103 | }
104 |
105 | /**
106 | * 隐藏省级行政区,只显示地市级和区县级。
107 | * 设置为true的话,地址数据中只需要某个省份的即可
108 | * 参见示例中的“city2.json”
109 | *
110 | * @param hideProvince the hide province
111 | */
112 | public void setHideProvince(boolean hideProvince) {
113 | this.hideProvince = hideProvince;
114 | }
115 |
116 | /**
117 | * Sets on address pick listener.
118 | *
119 | * @param listener the listener
120 | */
121 | public void setOnAddressPickListener(OnAddressPickListener listener) {
122 | this.onAddressPickListener = listener;
123 | }
124 |
125 | @Override
126 | protected View initContentView() {
127 | if (provinceList.size() == 0) {
128 | throw new IllegalArgumentException("please initial options at first, can't be empty");
129 | }
130 | LinearLayout layout = new LinearLayout(activity);
131 | layout.setOrientation(LinearLayout.HORIZONTAL);
132 | layout.setGravity(Gravity.CENTER);
133 | int screenWidth = screen.widthPixels;
134 | final WheelView provinceView = new WheelView(activity);
135 | provinceView.setLayoutParams(new LinearLayout.LayoutParams(screenWidth / 3, WRAP_CONTENT));
136 | provinceView.setTextSize(textSize);
137 | provinceView.setTextColor(textColorNormal, textColorFocus);
138 | provinceView.setLineVisible(lineVisible);
139 | provinceView.setLineColor(lineColor);
140 | provinceView.setOffset(offset);
141 | layout.addView(provinceView);
142 | if (hideProvince) {
143 | provinceView.setVisibility(View.GONE);
144 | }
145 | final WheelView cityView = new WheelView(activity);
146 | cityView.setLayoutParams(new LinearLayout.LayoutParams(screenWidth / 3, WRAP_CONTENT));
147 | cityView.setTextSize(textSize);
148 | cityView.setTextColor(textColorNormal, textColorFocus);
149 | cityView.setLineVisible(lineVisible);
150 | cityView.setLineColor(lineColor);
151 | cityView.setOffset(offset);
152 | layout.addView(cityView);
153 | final WheelView countyView = new WheelView(activity);
154 | countyView.setLayoutParams(new LinearLayout.LayoutParams(screenWidth / 3, WRAP_CONTENT));
155 | countyView.setTextSize(textSize);
156 | countyView.setTextColor(textColorNormal, textColorFocus);
157 | countyView.setLineVisible(lineVisible);
158 | countyView.setLineColor(lineColor);
159 | countyView.setOffset(offset);
160 | layout.addView(countyView);
161 | provinceView.setItems(provinceList, selectedProvinceIndex);
162 | provinceView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
163 | @Override
164 | public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
165 | selectedProvince = item;
166 | selectedProvinceIndex = selectedIndex;
167 | selectedCountyIndex = 0;
168 | //根据省份获取地市
169 | cityView.setItems(cityList.get(selectedProvinceIndex), isUserScroll ? 0 : selectedCityIndex);
170 | //根据地市获取区县
171 | countyView.setItems(countyList.get(selectedProvinceIndex).get(0), isUserScroll ? 0 : selectedCountyIndex);
172 | }
173 | });
174 | cityView.setItems(cityList.get(selectedProvinceIndex), selectedCityIndex);
175 | cityView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
176 | @Override
177 | public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
178 | selectedCity = item;
179 | selectedCityIndex = selectedIndex;
180 | //根据地市获取区县
181 | countyView.setItems(countyList.get(selectedProvinceIndex).get(selectedCityIndex), isUserScroll ? 0 : selectedCountyIndex);
182 | }
183 | });
184 | countyView.setItems(countyList.get(selectedProvinceIndex).get(selectedCityIndex), selectedCountyIndex);
185 | countyView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
186 | @Override
187 | public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
188 | selectedCounty = item;
189 | selectedCountyIndex = selectedIndex;
190 | }
191 | });
192 | return layout;
193 | }
194 |
195 | @Override
196 | protected void setContentViewAfter(View contentView) {
197 | super.setContentViewAfter(contentView);
198 | super.setOnConfirmListener(new OnConfirmListener() {
199 | @Override
200 | public void onConfirm() {
201 | if (onAddressPickListener != null) {
202 | onAddressPickListener.onAddressPicked(selectedProvince, selectedCity, selectedCounty);
203 | }
204 | }
205 | });
206 | }
207 |
208 | /**
209 | * The type Area.
210 | */
211 | public abstract static class Area {
212 | /**
213 | * The Area id.
214 | */
215 | String areaId;
216 | /**
217 | * The Area name.
218 | */
219 | String areaName;
220 |
221 | /**
222 | * Gets area id.
223 | *
224 | * @return the area id
225 | */
226 | public String getAreaId() {
227 | return areaId;
228 | }
229 |
230 | /**
231 | * Sets area id.
232 | *
233 | * @param areaId the area id
234 | */
235 | public void setAreaId(String areaId) {
236 | this.areaId = areaId;
237 | }
238 |
239 | /**
240 | * Gets area name.
241 | *
242 | * @return the area name
243 | */
244 | public String getAreaName() {
245 | return areaName;
246 | }
247 |
248 | /**
249 | * Sets area name.
250 | *
251 | * @param areaName the area name
252 | */
253 | public void setAreaName(String areaName) {
254 | this.areaName = areaName;
255 | }
256 |
257 | @Override
258 | public String toString() {
259 | return "areaId=" + areaId + ",areaName=" + areaName;
260 | }
261 |
262 | }
263 |
264 | /**
265 | * The type Province.
266 | */
267 | public static class Province extends Area {
268 | /**
269 | * The Cities.
270 | */
271 | ArrayList cities = new ArrayList();
272 |
273 | /**
274 | * Gets cities.
275 | *
276 | * @return the cities
277 | */
278 | public ArrayList getCities() {
279 | return cities;
280 | }
281 |
282 | /**
283 | * Sets cities.
284 | *
285 | * @param cities the cities
286 | */
287 | public void setCities(ArrayList cities) {
288 | this.cities = cities;
289 | }
290 |
291 | }
292 |
293 | /**
294 | * The type City.
295 | */
296 | public static class City extends Area {
297 | private ArrayList counties = new ArrayList();
298 |
299 | /**
300 | * Gets counties.
301 | *
302 | * @return the counties
303 | */
304 | public ArrayList getCounties() {
305 | return counties;
306 | }
307 |
308 | /**
309 | * Sets counties.
310 | *
311 | * @param counties the counties
312 | */
313 | public void setCounties(ArrayList counties) {
314 | this.counties = counties;
315 | }
316 |
317 | }
318 |
319 | /**
320 | * The type County.
321 | */
322 | public static class County extends Area {
323 | }
324 |
325 | /**
326 | * The interface On address pick listener.
327 | */
328 | public interface OnAddressPickListener {
329 |
330 | /**
331 | * On address picked.
332 | *
333 | * @param province the province
334 | * @param city the city
335 | * @param county the county
336 | */
337 | void onAddressPicked(String province, String city, String county);
338 |
339 | }
340 |
341 | }
342 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/picker/ChineseZodiacPicker.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.picker;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * 生肖选择器
7 | *
8 | * @author 李玉江[QQ :1032694760]
9 | * @version 2015 /12/15
10 | */
11 | public class ChineseZodiacPicker extends OptionPicker {
12 |
13 | /**
14 | * Instantiates a new Chinese zodiac picker.
15 | *
16 | * @param activity the activity
17 | */
18 | public ChineseZodiacPicker(Activity activity) {
19 | super(activity, new String[]{
20 | "鼠",
21 | "牛",
22 | "虎",
23 | "兔",
24 | "龙",
25 | "蛇",
26 | "马",
27 | "羊",
28 | "猴",
29 | "鸡",
30 | "狗",
31 | "猪",
32 | });
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/picker/ColorPicker.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.picker;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.res.ColorStateList;
6 | import android.graphics.Color;
7 | import android.text.InputType;
8 | import android.view.Gravity;
9 | import android.view.KeyEvent;
10 | import android.view.View;
11 | import android.view.inputmethod.EditorInfo;
12 | import android.view.inputmethod.InputMethodManager;
13 | import android.widget.EditText;
14 | import android.widget.LinearLayout;
15 | import android.widget.TextView;
16 |
17 | import java.util.Locale;
18 |
19 | import cn.qqtheme.framework.R;
20 | import cn.qqtheme.framework.popup.ConfirmPopup;
21 | import cn.qqtheme.framework.util.CompatUtils;
22 | import cn.qqtheme.framework.util.ConvertUtils;
23 | import cn.qqtheme.framework.widget.ColorPanelView;
24 |
25 | /**
26 | * 颜色选择器。
27 | *
28 | * @author 李玉江[QQ :1032694760]
29 | * @version 2015 /9/29
30 | */
31 | public class ColorPicker extends ConfirmPopup implements TextView.OnEditorActionListener {
32 | private static final int MULTI_ID = 0x1;
33 | private static final int BLACK_ID = 0x2;
34 | private int initColor = Color.WHITE;
35 | private ColorPanelView multiColorView, blackColorView;
36 | private EditText hexValView;
37 | private ColorStateList hexValDefaultColor;
38 | private OnColorPickListener onColorPickListener;
39 |
40 | /**
41 | * Instantiates a new Color picker.
42 | *
43 | * @param activity the activity
44 | */
45 | public ColorPicker(Activity activity) {
46 | super(activity);
47 | }
48 |
49 | @Override
50 | protected LinearLayout initContentView() {
51 | LinearLayout rootLayout = new LinearLayout(activity);
52 | rootLayout.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
53 | rootLayout.setOrientation(LinearLayout.VERTICAL);
54 | blackColorView = new ColorPanelView(activity);
55 | //noinspection ResourceType
56 | blackColorView.setId(BLACK_ID);
57 | blackColorView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, ConvertUtils.toPx(activity, 30)));
58 | blackColorView.setPointerDrawable(CompatUtils.getDrawable(activity, R.drawable.color_picker_cursor_bottom));
59 | blackColorView.setLockPointerInBounds(false);
60 | blackColorView.setOnColorChangedListener(new ColorPanelView.OnColorChangedListener() {
61 | @Override
62 | public void onColorChanged(ColorPanelView view, int color) {
63 | updateCurrentColor(color);
64 | }
65 | });
66 | rootLayout.addView(blackColorView);
67 | multiColorView = new ColorPanelView(activity);
68 | //noinspection ResourceType
69 | multiColorView.setId(MULTI_ID);
70 | multiColorView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1.0f));
71 | multiColorView.setPointerDrawable(CompatUtils.getDrawable(activity, R.drawable.color_picker_cursor_top));
72 | multiColorView.setLockPointerInBounds(true);
73 | multiColorView.setOnColorChangedListener(new ColorPanelView.OnColorChangedListener() {
74 | @Override
75 | public void onColorChanged(ColorPanelView view, int color) {
76 | updateCurrentColor(color);
77 | }
78 | });
79 | rootLayout.addView(multiColorView);
80 | LinearLayout previewLayout = new LinearLayout(activity);
81 | previewLayout.setOrientation(LinearLayout.HORIZONTAL);
82 | previewLayout.setGravity(Gravity.CENTER);
83 | previewLayout.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, ConvertUtils.toPx(activity, 30)));
84 | hexValView = new EditText(activity);
85 | hexValView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
86 | hexValView.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
87 | hexValView.setImeOptions(EditorInfo.IME_ACTION_DONE);
88 | hexValView.setGravity(Gravity.CENTER);
89 | hexValView.setBackgroundColor(initColor);
90 | hexValView.setTextColor(Color.BLACK);
91 | hexValView.setShadowLayer(3, 0, 2, Color.WHITE);//设置阴影,以便背景色为黑色系列时仍然看得见
92 | hexValView.setMinEms(6);
93 | hexValView.setMaxEms(8);
94 | hexValView.setPadding(0, 0, 0, 0);
95 | hexValView.setSingleLine(true);
96 | hexValView.setOnEditorActionListener(this);
97 | hexValDefaultColor = hexValView.getTextColors();
98 | previewLayout.addView(hexValView);
99 | rootLayout.addView(previewLayout);
100 | return rootLayout;
101 | }
102 |
103 | @Override
104 | protected boolean isFixedHeight() {
105 | return true;
106 | }
107 |
108 | @Override
109 | protected void setContentViewAfter(View contentView) {
110 | multiColorView.setColor(initColor);//将触发onColorChanged,故必须先待其他控件初始化完成后才能调用
111 | multiColorView.setBrightnessGradientView(blackColorView);
112 | if (onColorPickListener != null) {
113 | super.setOnConfirmListener(new OnConfirmListener() {
114 | @Override
115 | public void onConfirm() {
116 | onColorPickListener.onColorPicked(Color.parseColor("#" + hexValView.getText()));
117 | }
118 | });
119 | }
120 | }
121 |
122 | private void updateCurrentColor(int color) {
123 | String hexColorString = ConvertUtils.toColorString(color, false).toUpperCase(Locale.getDefault());
124 | hexValView.setText(hexColorString);
125 | hexValView.setTextColor(hexValDefaultColor);
126 | hexValView.setBackgroundColor(color);
127 | }
128 |
129 | /**
130 | * Sets init color.
131 | *
132 | * @param initColor the init color
133 | */
134 | public void setInitColor(int initColor) {
135 | this.initColor = initColor;
136 | }
137 |
138 | /**
139 | * Sets on color pick listener.
140 | *
141 | * @param onColorPickListener the on color pick listener
142 | */
143 | public void setOnColorPickListener(OnColorPickListener onColorPickListener) {
144 | this.onColorPickListener = onColorPickListener;
145 | }
146 |
147 | @Override
148 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
149 | if (actionId == EditorInfo.IME_ACTION_DONE) {
150 | InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
151 | imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
152 | String hexString = hexValView.getText().toString();
153 | int length = hexString.length();
154 | if (length == 6 || length == 8) {
155 | try {
156 | int color = Color.parseColor("#" + hexString);
157 | multiColorView.setColor(color);
158 | hexValView.setTextColor(hexValDefaultColor);
159 | } catch (IllegalArgumentException e) {
160 | hexValView.setTextColor(Color.RED);
161 | }
162 | } else {
163 | hexValView.setTextColor(Color.RED);
164 | }
165 | return true;
166 | }
167 | return false;
168 | }
169 |
170 | /**
171 | * The interface On color pick listener.
172 | */
173 | public interface OnColorPickListener {
174 |
175 | /**
176 | * On color picked.
177 | *
178 | * @param pickedColor the picked color
179 | */
180 | void onColorPicked(int pickedColor);
181 |
182 | }
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/picker/ConstellationPicker.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.picker;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * 星座选择器
7 | *
8 | * @author 李玉江[QQ :1032694760]
9 | * @version 2015 /12/15
10 | */
11 | public class ConstellationPicker extends OptionPicker {
12 |
13 | /**
14 | * Instantiates a new Constellation picker.
15 | *
16 | * @param activity the activity
17 | */
18 | public ConstellationPicker(Activity activity) {
19 | super(activity, new String[]{
20 | "水瓶",
21 | "双鱼",
22 | "白羊",
23 | "金牛",
24 | "双子",
25 | "巨蟹",
26 | "狮子",
27 | "处女",
28 | "天秤",
29 | "天蝎",
30 | "射手",
31 | "摩羯",
32 | });
33 | setLabel("座");
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/library/src/main/java/cn/qqtheme/framework/picker/DatePicker.java:
--------------------------------------------------------------------------------
1 | package cn.qqtheme.framework.picker;
2 |
3 | import android.app.Activity;
4 | import android.text.TextUtils;
5 | import android.view.Gravity;
6 | import android.view.View;
7 | import android.widget.LinearLayout;
8 | import android.widget.TextView;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Collections;
12 | import java.util.Comparator;
13 |
14 | import cn.qqtheme.framework.util.DateUtils;
15 | import cn.qqtheme.framework.widget.WheelView;
16 |
17 | /**
18 | * 日期选择器
19 | *
20 | * @author 李玉江[QQ :1032694760]
21 | * @version 2015 /12/14
22 | */
23 | public class DatePicker extends WheelPicker {
24 | private ArrayList years = new ArrayList();
25 | private ArrayList months = new ArrayList();
26 | private ArrayList days = new ArrayList();
27 | private OnDatePickListener onDatePickListener;
28 | private String yearLabel = "年", monthLabel = "月", dayLabel = "日";
29 | private int selectedYearIndex = 0, selectedMonthIndex = 0, selectedDayIndex = 0;
30 | private Mode mode = Mode.YEAR_MONTH_DAY;
31 |
32 | /**
33 | * The enum Mode.
34 | */
35 | public enum Mode {
36 | /**
37 | * 年月日
38 | */
39 | YEAR_MONTH_DAY,
40 | /**
41 | * 年月
42 | */
43 | YEAR_MONTH,
44 | /**
45 | * 月日
46 | */
47 | MONTH_DAY
48 | }
49 |
50 | /**
51 | * Instantiates a new Date picker.
52 | *
53 | * @param activity the activity
54 | */
55 | public DatePicker(Activity activity) {
56 | this(activity, Mode.YEAR_MONTH_DAY);
57 | }
58 |
59 | /**
60 | * Instantiates a new Date picker.
61 | *
62 | * @param activity the activity
63 | * @param mode the mode
64 | */
65 | public DatePicker(Activity activity, Mode mode) {
66 | super(activity);
67 | this.mode = mode;
68 | for (int i = 2000; i <= 2050; i++) {
69 | years.add(String.valueOf(i));
70 | }
71 | for (int i = 1; i <= 12; i++) {
72 | months.add(DateUtils.fillZero(i));
73 | }
74 | for (int i = 1; i <= 31; i++) {
75 | days.add(DateUtils.fillZero(i));
76 | }
77 | }
78 |
79 | /**
80 | * Sets label.
81 | *
82 | * @param yearLabel the year label
83 | * @param monthLabel the month label
84 | * @param dayLabel the day label
85 | */
86 | public void setLabel(String yearLabel, String monthLabel, String dayLabel) {
87 | this.yearLabel = yearLabel;
88 | this.monthLabel = monthLabel;
89 | this.dayLabel = dayLabel;
90 | }
91 |
92 | /**
93 | * Sets range.
94 | *
95 | * @param startYear the start year
96 | * @param endYear the end year
97 | * @see Mode#YEAR_MONTH_DAY Mode#YEAR_MONTH_DAY
98 | * @see Mode#YEAR_MONTH Mode#YEAR_MONTH
99 | */
100 | public void setRange(int startYear, int endYear) {
101 | years.clear();
102 | for (int i = startYear; i <= endYear; i++) {
103 | years.add(String.valueOf(i));
104 | }
105 | }
106 |
107 | private int findItemIndex(ArrayList items, int item) {
108 | //折半查找有序元素的索引
109 | int index = Collections.binarySearch(items, item, new Comparator