├── .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 | [![API](https://img.shields.io/badge/API-8%2B-green.svg)](https://github.com/gzu-liyujiang/AndroidPicker) 3 | [![Download](https://api.bintray.com/packages/gzu-liyujiang/maven/AndroidPicker/images/download.svg)](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 | ![日期选择器效果图](/screenshots/date.gif) 222 | ![时间选择器效果图](/screenshots/time.gif) 223 | ![单项选择器效果图](/screenshots/option.gif) 224 | ![地址选择器效果图](/screenshots/address.gif) 225 | ![地址选择器效果图](/screenshots/address.png) 226 | ![数字选择器效果图](/screenshots/number.gif) 227 | ![星座选择器效果图](/screenshots/constellation.gif) 228 | ![生肖选择器效果图](/screenshots/chinesezodiac.gif) 229 | ![颜色选择器效果图](/screenshots/color.gif) 230 | ![文件选择器效果图](/screenshots/file.gif) 231 | ![目录选择器效果图](/screenshots/dir.gif) 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 |