├── .classpath ├── .project ├── AndroidManifest.xml ├── README.md ├── bin ├── LauncherDemo.apk └── MainActivity.apk ├── gen └── com │ └── jit │ └── demo │ ├── BuildConfig.java │ └── R.java ├── ic_launcher-web.png ├── libs ├── android-support-v4.jar └── xUitls-1.6.9.jar ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ ├── close.png │ ├── item10_down.png │ ├── item10_normal.png │ ├── item1_down.png │ ├── item1_normal.png │ ├── item2_dowm.png │ ├── item2_down.png │ ├── item2_normal.png │ ├── item3_down.png │ ├── item3_normal.png │ ├── item4_down.png │ ├── item4_normal.png │ ├── item5_down.png │ ├── item5_normal.png │ ├── item6_down.png │ ├── item6_normal.png │ ├── item7_down.png │ ├── item7_normal.png │ ├── item8_down.png │ ├── item8_normal.png │ ├── item9_down.png │ ├── item9_normal.png │ └── main_bg.jpg ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ └── ic_launcher.png ├── layout │ ├── activity_main.xml │ └── item.xml ├── values-v11 │ └── styles.xml ├── values-v14 │ └── styles.xml └── values │ ├── color.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── src └── com └── jit └── demo ├── activity └── MainActivity.java ├── adapter └── ScrollAdapter.java ├── model ├── MoveItem.java └── MoveItems.java ├── util └── DensityUtil.java └── wight └── ScrollLayout.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainActivity 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | 28 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AndroidLauncher 2 | =============== 3 | 4 | A fantastic Launcher for android;一个效果很华丽的仿桌面APP,胜似Launcher。 5 | 如果你有好的实现或者功能扩展,请提交Pull Request。如果你有好的想法,请在我的微信公众账号留言,我来实现你的想法。 6 | 微信公众账号:Android干货分享(ID:android_share) 7 | 技术交流QQ群:318588906,欢迎大家加群,共同探讨下Android和Java技术 8 | -------------------------------------------------------------------------------- /bin/LauncherDemo.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/bin/LauncherDemo.apk -------------------------------------------------------------------------------- /bin/MainActivity.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/bin/MainActivity.apk -------------------------------------------------------------------------------- /gen/com/jit/demo/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /** Automatically generated file. DO NOT MODIFY */ 2 | package com.jit.demo; 3 | 4 | public final class BuildConfig { 5 | public final static boolean DEBUG = true; 6 | } -------------------------------------------------------------------------------- /gen/com/jit/demo/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package com.jit.demo; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class color { 14 | /** 蜜色 15 | */ 16 | public static final int aliceblue=0x7f040033; 17 | /** 亚麻色 18 | */ 19 | public static final int antiquewhite=0x7f040029; 20 | /** 中灰兰色 21 | */ 22 | public static final int aqua=0x7f040089; 23 | /** 粟色 24 | */ 25 | public static final int aquamarine=0x7f04006a; 26 | /** 沙褐色 27 | */ 28 | public static final int azure=0x7f040031; 29 | /** 烟白色 30 | */ 31 | public static final int beige=0x7f04002e; 32 | public static final int bgcolor=0x7f040000; 33 | public static final int big_grey=0x7f0400a4; 34 | /** 浅玫瑰色 35 | */ 36 | public static final int bisque=0x7f040014; 37 | /** 海军色 38 | */ 39 | public static final int black=0x7f040098; 40 | /** 番木色 41 | */ 42 | public static final int blanchedalmond=0x7f040012; 43 | /** 暗绿色 44 | */ 45 | public static final int blue=0x7f040094; 46 | /** 暗红色 47 | */ 48 | public static final int blueviolet=0x7f040062; 49 | /** 暗灰色 50 | */ 51 | public static final int brown=0x7f040057; 52 | /** 浏览历史的颜色 53 | */ 54 | public static final int browsing_history_color=0x7f0400a7; 55 | /** 亮青色 56 | */ 57 | public static final int burlywood=0x7f04003b; 58 | public static final int busy_indicator=0x7f0400ab; 59 | public static final int button_normal=0x7f0400ac; 60 | public static final int button_pressed=0x7f0400ad; 61 | /** 菊兰色 62 | */ 63 | public static final int cadetblue=0x7f040078; 64 | public static final int canvas=0x7f0400a8; 65 | /** 碧绿色 66 | */ 67 | public static final int chartreuse=0x7f04006b; 68 | /** 茶色 69 | */ 70 | public static final int chocolate=0x7f040046; 71 | /** 暗桔黄色 72 | */ 73 | public static final int coral=0x7f04001e; 74 | /** 中绿色 75 | */ 76 | public static final int cornflowerblue=0x7f040077; 77 | /** 柠檬绸色 78 | */ 79 | public static final int cornsilk=0x7f04000e; 80 | /** 淡灰色 81 | */ 82 | public static final int crimson=0x7f04003e; 83 | /** 浅绿色 84 | */ 85 | public static final int cyan=0x7f04008a; 86 | /** 中兰色 87 | */ 88 | public static final int darkblue=0x7f040096; 89 | /** 深天蓝色 90 | */ 91 | public static final int darkcyan=0x7f040090; 92 | /** 中粉紫色 93 | */ 94 | public static final int darkgoldenrod=0x7f04004e; 95 | /** 亮蓝色 96 | */ 97 | public static final int darkgray=0x7f040055; 98 | /** 绿色 99 | */ 100 | public static final int darkgreen=0x7f040093; 101 | /** 暗灰色 102 | */ 103 | public static final int darkgrey=0x7f040056; 104 | /** 银色 105 | */ 106 | public static final int darkkhaki=0x7f04004b; 107 | /** 重褐色 108 | */ 109 | public static final int darkmagenta=0x7f040060; 110 | /** 军兰色 111 | */ 112 | public static final int darkolivegreen=0x7f040079; 113 | /** 亮肉色 114 | */ 115 | public static final int darkorange=0x7f04001d; 116 | /** 赭色 117 | */ 118 | public static final int darkorchid=0x7f040059; 119 | /** 暗洋红 120 | */ 121 | public static final int darkred=0x7f040061; 122 | /** 紫罗兰色 123 | */ 124 | public static final int darksalmon=0x7f040038; 125 | /** 亮绿色 126 | */ 127 | public static final int darkseagreen=0x7f04005e; 128 | /** 中绿宝石 129 | */ 130 | public static final int darkslateblue=0x7f04007c; 131 | /** 橙绿色 132 | */ 133 | public static final int darkslategray=0x7f040082; 134 | /** 暗瓦灰色 135 | */ 136 | public static final int darkslategrey=0x7f040083; 137 | /** 中春绿色 138 | */ 139 | public static final int darkturquoise=0x7f04008e; 140 | /** 苍绿色 141 | */ 142 | public static final int darkviolet=0x7f04005b; 143 | /** 红橙色 144 | */ 145 | public static final int deeppink=0x7f040022; 146 | /** 暗宝石绿 147 | */ 148 | public static final int deepskyblue=0x7f04008f; 149 | /** 石蓝色 150 | */ 151 | public static final int dimgray=0x7f040074; 152 | /** 暗灰色 153 | */ 154 | public static final int dimgrey=0x7f040075; 155 | /** 亮海蓝色 156 | */ 157 | public static final int dodgerblue=0x7f040087; 158 | /** 暗金黄色 159 | */ 160 | public static final int firebrick=0x7f04004f; 161 | /** 雪白色 162 | */ 163 | public static final int floralwhite=0x7f04000c; 164 | public static final int focused=0x7f040003; 165 | /** 海绿色 166 | */ 167 | public static final int forestgreen=0x7f040085; 168 | /** 深粉红色 169 | */ 170 | public static final int fuchsia=0x7f040023; 171 | /** 洋李色 172 | */ 173 | public static final int gainsboro=0x7f04003d; 174 | /** 鲜肉色 175 | */ 176 | public static final int ghostwhite=0x7f04002b; 177 | /** 桃色 178 | */ 179 | public static final int gold=0x7f040018; 180 | /** 苍紫罗兰色 181 | */ 182 | public static final int goldenrod=0x7f040040; 183 | /** 天蓝色 184 | */ 185 | public static final int gray=0x7f040065; 186 | public static final int gray_history=0x7f04009c; 187 | /** 水鸭色 188 | */ 189 | public static final int green=0x7f040092; 190 | /** 苍宝石绿 191 | */ 192 | public static final int greenyellow=0x7f040053; 193 | /** 灰色 194 | */ 195 | public static final int grey=0x7f040066; 196 | /** 天蓝色 197 | */ 198 | public static final int honeydew=0x7f040032; 199 | /** 珊瑚色 200 | */ 201 | public static final int hotpink=0x7f04001f; 202 | /** 秘鲁色 203 | */ 204 | public static final int indianred=0x7f040048; 205 | /** 暗橄榄绿 206 | */ 207 | public static final int indigo=0x7f04007a; 208 | public static final int ivory=0x7f040008; 209 | /** 艾利斯兰 210 | */ 211 | public static final int khaki=0x7f040034; 212 | /** 暗肉色 213 | */ 214 | public static final int lavender=0x7f040039; 215 | /** 海贝色 216 | */ 217 | public static final int lavenderblush=0x7f040010; 218 | /** 黄绿色 219 | */ 220 | public static final int lawngreen=0x7f04006c; 221 | /** 花白色 222 | */ 223 | public static final int lemonchiffon=0x7f04000d; 224 | public static final int light_green=0x7f040007; 225 | /** 黄绿色 226 | */ 227 | public static final int lightblue=0x7f040054; 228 | /** 黄褐色 229 | */ 230 | public static final int lightcoral=0x7f040035; 231 | /** 淡紫色 232 | */ 233 | public static final int lightcyan=0x7f04003a; 234 | /** 老花色 235 | */ 236 | public static final int lightgoldenrodyellow=0x7f040027; 237 | /** 蓟色 238 | */ 239 | public static final int lightgray=0x7f040043; 240 | /** 中紫色 241 | */ 242 | public static final int lightgreen=0x7f04005d; 243 | /** 亮灰色 244 | */ 245 | public static final int lightgrey=0x7f040044; 246 | /** 粉红色 247 | */ 248 | public static final int lightpink=0x7f04001a; 249 | /** 橙色 250 | */ 251 | public static final int lightsalmon=0x7f04001c; 252 | /** 森林绿 253 | */ 254 | public static final int lightseagreen=0x7f040086; 255 | /** 紫罗兰蓝色 256 | */ 257 | public static final int lightskyblue=0x7f040063; 258 | /** 中暗蓝色 259 | */ 260 | public static final int lightslategray=0x7f04006e; 261 | /** 亮蓝灰 262 | */ 263 | public static final int lightslategrey=0x7f04006f; 264 | /** 粉蓝色 265 | */ 266 | public static final int lightsteelblue=0x7f040051; 267 | /** 象牙色 268 | */ 269 | public static final int lightyellow=0x7f040009; 270 | /** 春绿色 271 | */ 272 | public static final int lime=0x7f04008c; 273 | /** 中海蓝 274 | */ 275 | public static final int limegreen=0x7f040081; 276 | /** 亮金黄色 277 | */ 278 | public static final int linen=0x7f040028; 279 | public static final int little_grey=0x7f0400a3; 280 | /** 紫红色 281 | */ 282 | public static final int magenta=0x7f040024; 283 | /** 紫色 284 | */ 285 | public static final int maroon=0x7f040069; 286 | /** 暗灰色 287 | */ 288 | public static final int mediumaquamarine=0x7f040076; 289 | /** 蓝色 290 | */ 291 | public static final int mediumblue=0x7f040095; 292 | /** 褐玫瑰红 293 | */ 294 | public static final int mediumorchid=0x7f04004d; 295 | /** 暗紫罗兰色 296 | */ 297 | public static final int mediumpurple=0x7f04005c; 298 | /** 青绿色 299 | */ 300 | public static final int mediumseagreen=0x7f040080; 301 | /** 草绿色 302 | */ 303 | public static final int mediumslateblue=0x7f04006d; 304 | /** 酸橙色 305 | */ 306 | public static final int mediumspringgreen=0x7f04008d; 307 | /** 靛青色 308 | */ 309 | public static final int mediumturquoise=0x7f04007b; 310 | /** 印第安红 311 | */ 312 | public static final int mediumvioletred=0x7f040049; 313 | /** 闪兰色 314 | */ 315 | public static final int midnightblue=0x7f040088; 316 | /** 幽灵白 317 | */ 318 | public static final int mintcream=0x7f04002c; 319 | /** 白杏色 320 | */ 321 | public static final int mistyrose=0x7f040013; 322 | /** 桔黄色 323 | */ 324 | public static final int moccasin=0x7f040015; 325 | /** 鹿皮色 326 | */ 327 | public static final int navajowhite=0x7f040016; 328 | /** 暗蓝色 329 | */ 330 | public static final int navy=0x7f040097; 331 | public static final int news_3_top_item_color=0x7f04009a; 332 | /** 红色 333 | */ 334 | public static final int oldlace=0x7f040026; 335 | /** 灰色 336 | */ 337 | public static final int olive=0x7f040067; 338 | /** 灰石色 339 | */ 340 | public static final int olivedrab=0x7f040072; 341 | /** 亮粉红色 342 | */ 343 | public static final int orange=0x7f04001b; 344 | /** 西红柿色 345 | */ 346 | public static final int orangered=0x7f040021; 347 | /** 金麒麟色 348 | */ 349 | public static final int orchid=0x7f040041; 350 | public static final int page_indicator=0x7f0400aa; 351 | /** 亮珊瑚色 352 | */ 353 | public static final int palegoldenrod=0x7f040036; 354 | /** 暗紫色 355 | */ 356 | public static final int palegreen=0x7f04005a; 357 | /** 亮钢兰色 358 | */ 359 | public static final int paleturquoise=0x7f040052; 360 | /** 暗深红色 361 | */ 362 | public static final int palevioletred=0x7f04003f; 363 | /** 淡紫红 364 | */ 365 | public static final int papayawhip=0x7f040011; 366 | /** 纳瓦白 367 | */ 368 | public static final int peachpuff=0x7f040017; 369 | /** 巧可力色 370 | */ 371 | public static final int peru=0x7f040047; 372 | /** 金色 373 | */ 374 | public static final int pink=0x7f040019; 375 | /** 实木色 376 | */ 377 | public static final int plum=0x7f04003c; 378 | /** 火砖色 379 | */ 380 | public static final int powderblue=0x7f040050; 381 | /** 产品模块样式2的六种颜色 382 | */ 383 | public static final int product_2_color_1=0x7f04009d; 384 | public static final int product_2_color_2=0x7f04009e; 385 | public static final int product_2_color_3=0x7f04009f; 386 | public static final int product_2_color_4=0x7f0400a0; 387 | public static final int product_2_color_5=0x7f0400a1; 388 | public static final int product_2_color_6=0x7f0400a2; 389 | /** 橄榄色 390 | */ 391 | public static final int purple=0x7f040068; 392 | public static final int purple_title=0x7f04009b; 393 | /** 红紫色 394 | */ 395 | public static final int red=0x7f040025; 396 | /** 暗黄褐色 397 | */ 398 | public static final int rosybrown=0x7f04004c; 399 | /** 钢兰色 400 | */ 401 | public static final int royalblue=0x7f04007e; 402 | /** 暗海兰色 403 | */ 404 | public static final int saddlebrown=0x7f04005f; 405 | /** 古董白 406 | */ 407 | public static final int salmon=0x7f04002a; 408 | /** 浅黄色 409 | */ 410 | public static final int sandybrown=0x7f040030; 411 | /** 米绸色 412 | */ 413 | public static final int seaShell=0x7f04000f; 414 | /** 暗瓦灰色 415 | */ 416 | public static final int seagreen=0x7f040084; 417 | public static final int seek_progress=0x7f0400b4; 418 | public static final int seek_thumb=0x7f0400b3; 419 | public static final int selected=0x7f040002; 420 | /** 褐色 421 | */ 422 | public static final int sienna=0x7f040058; 423 | /** 中紫罗兰色 424 | */ 425 | public static final int silver=0x7f04004a; 426 | /** 亮天蓝色 427 | */ 428 | public static final int skyblue=0x7f040064; 429 | /** 深绿褐色 430 | */ 431 | public static final int slateblue=0x7f040073; 432 | /** 亮蓝灰 433 | */ 434 | public static final int slategray=0x7f040070; 435 | /** 灰石色 436 | */ 437 | public static final int slategrey=0x7f040071; 438 | /** 白色 439 | */ 440 | public static final int slider=0x7f040006; 441 | /** 黄色 442 | */ 443 | public static final int snow=0x7f04000b; 444 | public static final int special_blue=0x7f0400a5; 445 | public static final int special_red=0x7f0400a6; 446 | /** 青色 447 | */ 448 | public static final int springgreen=0x7f04008b; 449 | /** 暗灰蓝色 450 | */ 451 | public static final int steelblue=0x7f04007d; 452 | public static final int survey_options_color=0x7f040099; 453 | /** 亮灰色 454 | */ 455 | public static final int tan=0x7f040045; 456 | /** 暗青色 457 | */ 458 | public static final int teal=0x7f040091; 459 | public static final int text_border_focused=0x7f0400b2; 460 | public static final int text_border_normal=0x7f0400b0; 461 | public static final int text_border_pressed=0x7f0400b1; 462 | public static final int text_normal=0x7f0400ae; 463 | public static final int text_pressed=0x7f0400af; 464 | /** 淡紫色 465 | */ 466 | public static final int thistle=0x7f040042; 467 | /** 热粉红色 468 | */ 469 | public static final int tomato=0x7f040020; 470 | public static final int toolbar=0x7f0400a9; 471 | public static final int translate=0x7f040004; 472 | /** 皇家蓝 473 | */ 474 | public static final int turquoise=0x7f04007f; 475 | public static final int unfocused=0x7f040001; 476 | /** 苍麒麟色 477 | */ 478 | public static final int violet=0x7f040037; 479 | /** 米色 480 | */ 481 | public static final int wheat=0x7f04002f; 482 | public static final int white=0x7f040005; 483 | /** 薄荷色 484 | */ 485 | public static final int whitesmoke=0x7f04002d; 486 | /** 亮黄色 487 | */ 488 | public static final int yellow=0x7f04000a; 489 | } 490 | public static final class dimen { 491 | public static final int activity_horizontal_margin=0x7f050011; 492 | public static final int activity_vertical_margin=0x7f050012; 493 | public static final int all_title=0x7f050008; 494 | public static final int bottom_normal=0x7f050000; 495 | public static final int header_footer_left_right_padding=0x7f05000f; 496 | public static final int header_footer_top_bottom_padding=0x7f050010; 497 | public static final int index_ring_number_size=0x7f050002; 498 | public static final int indicator_corner_radius=0x7f05000d; 499 | public static final int indicator_internal_padding=0x7f05000e; 500 | public static final int indicator_right_padding=0x7f05000c; 501 | public static final int listview_normal=0x7f050001; 502 | public static final int newsnum=0x7f05000b; 503 | public static final int nomal=0x7f050004; 504 | public static final int nomal_max=0x7f050007; 505 | public static final int set_title_size=0x7f050005; 506 | public static final int small_newstitle=0x7f05000a; 507 | public static final int temperature=0x7f050006; 508 | public static final int twocodename=0x7f050003; 509 | public static final int ziti=0x7f050009; 510 | } 511 | public static final class drawable { 512 | public static final int close=0x7f020000; 513 | public static final int ic_launcher=0x7f020001; 514 | public static final int item10_down=0x7f020002; 515 | public static final int item10_normal=0x7f020003; 516 | public static final int item1_down=0x7f020004; 517 | public static final int item1_normal=0x7f020005; 518 | public static final int item2_dowm=0x7f020006; 519 | public static final int item2_down=0x7f020007; 520 | public static final int item2_normal=0x7f020008; 521 | public static final int item3_down=0x7f020009; 522 | public static final int item3_normal=0x7f02000a; 523 | public static final int item4_down=0x7f02000b; 524 | public static final int item4_normal=0x7f02000c; 525 | public static final int item5_down=0x7f02000d; 526 | public static final int item5_normal=0x7f02000e; 527 | public static final int item6_down=0x7f02000f; 528 | public static final int item6_normal=0x7f020010; 529 | public static final int item7_down=0x7f020011; 530 | public static final int item7_normal=0x7f020012; 531 | public static final int item8_down=0x7f020013; 532 | public static final int item8_normal=0x7f020014; 533 | public static final int item9_down=0x7f020015; 534 | public static final int item9_normal=0x7f020016; 535 | public static final int main_bg=0x7f020017; 536 | } 537 | public static final class id { 538 | public static final int container=0x7f080000; 539 | public static final int content_iv=0x7f080001; 540 | public static final int delete_iv=0x7f080002; 541 | } 542 | public static final class layout { 543 | public static final int activity_main=0x7f030000; 544 | public static final int item=0x7f030001; 545 | } 546 | public static final class string { 547 | public static final int app_name=0x7f060000; 548 | public static final int hello_world=0x7f060002; 549 | public static final int menu_settings=0x7f060001; 550 | } 551 | public static final class style { 552 | /** 553 | Base application theme, dependent on API level. This theme is replaced 554 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices. 555 | 556 | 557 | 558 | 559 | 560 | Theme customizations available in newer API levels can go in 561 | res/values-vXX/styles.xml, while customizations related to 562 | backward-compatibility can go here. 563 | 564 | 565 | 566 | 567 | 568 | Base application theme for API 11+. This theme completely replaces 569 | AppBaseTheme from res/values/styles.xml on API 11+ devices. 570 | 571 | API 11 theme customizations can go here. 572 | 573 | Base application theme for API 14+. This theme completely replaces 574 | AppBaseTheme from BOTH res/values/styles.xml and 575 | res/values-v11/styles.xml on API 14+ devices. 576 | 577 | API 14 theme customizations can go here. 578 | */ 579 | public static final int AppBaseTheme=0x7f070000; 580 | /** Application theme. 581 | All customizations that are NOT specific to a particular API-level can go here. 582 | */ 583 | public static final int AppTheme=0x7f070001; 584 | } 585 | } 586 | -------------------------------------------------------------------------------- /ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/ic_launcher-web.png -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/libs/android-support-v4.jar -------------------------------------------------------------------------------- /libs/xUitls-1.6.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/libs/xUitls-1.6.9.jar -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | -------------------------------------------------------------------------------- /res/drawable-hdpi/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/close.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item10_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item10_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item10_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item10_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item1_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item1_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item1_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item1_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item2_dowm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item2_dowm.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item2_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item2_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item2_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item2_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item3_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item3_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item3_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item3_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item4_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item4_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item4_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item4_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item5_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item5_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item5_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item5_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item6_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item6_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item6_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item6_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item7_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item7_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item7_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item7_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item8_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item8_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item8_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item8_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item9_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item9_down.png -------------------------------------------------------------------------------- /res/drawable-hdpi/item9_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/item9_normal.png -------------------------------------------------------------------------------- /res/drawable-hdpi/main_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-hdpi/main_bg.jpg -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-xhdpi/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackCho/AndroidLauncher/f16f317ad1dfac9dcd9521a94d40f7c1b1c63e7a/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 19 | 31 | 32 | -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /res/values/color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #dfcbb8 5 | #cccccccc 6 | #fff33fff 7 | #ffff44ff 8 | #00000000 9 | #ffffff 10 | 11 | #DCE4E3 12 | #98FB98 13 | #fffff0 14 | 15 | #ffffe0 16 | 17 | #ffff00 18 | 19 | #fffafa 20 | 21 | #fffaf0 22 | 23 | #fffacd 24 | 25 | #fff8dc 26 | 27 | #fff5ee 28 | 29 | #fff0f5 30 | 31 | #ffefd5 32 | 33 | #ffebcd 34 | 35 | #ffe4e1 36 | 37 | #ffe4c4 38 | 39 | #ffe4b5 40 | 41 | #ffdead 42 | 43 | #ffdab9 44 | 45 | #ffd700 46 | 47 | #ffc0cb 48 | 49 | #ffb6c1 50 | 51 | #ffa500 52 | 53 | #ffa07a 54 | 55 | #ff8c00 56 | 57 | #ff7f50 58 | 59 | #ff69b4 60 | 61 | #ff6347 62 | 63 | #ff4500 64 | 65 | #ff1493 66 | 67 | #ff00ff 68 | 69 | #ff00ff 70 | 71 | #ff0000 72 | 73 | #fdf5e6 74 | 75 | #fafad2 76 | 77 | #faf0e6 78 | 79 | #faebd7 80 | 81 | #fa8072 82 | 83 | #f8f8ff 84 | 85 | #f5fffa 86 | 87 | #f5f5f5 88 | 89 | #f5f5dc 90 | 91 | #f5deb3 92 | 93 | #f4a460 94 | 95 | #f0ffff 96 | 97 | #f0fff0 98 | 99 | #f0f8ff 100 | 101 | #f0e68c 102 | 103 | #f08080 104 | 105 | #eee8aa 106 | 107 | #ee82ee 108 | 109 | #e9967a 110 | 111 | #e6e6fa 112 | 113 | #e0ffff 114 | 115 | #deb887 116 | 117 | #dda0dd 118 | 119 | #dcdcdc 120 | 121 | #dc143c 122 | 123 | #db7093 124 | 125 | #daa520 126 | 127 | #da70d6 128 | 129 | #d8bfd8 130 | 131 | #d3d3d3 132 | 133 | #d3d3d3 134 | 135 | #d2b48c 136 | 137 | #d2691e 138 | 139 | #cd853f 140 | 141 | #cd5c5c 142 | 143 | #c71585 144 | 145 | #c0c0c0 146 | 147 | #bdb76b 148 | 149 | #bc8f8f 150 | 151 | #ba55d3 152 | 153 | #b8860b 154 | 155 | #b22222 156 | 157 | #b0e0e6 158 | 159 | #b0c4de 160 | 161 | #afeeee 162 | 163 | #adff2f 164 | 165 | #add8e6 166 | 167 | #a9a9a9 168 | 169 | #a9a9a9 170 | 171 | #a52a2a 172 | 173 | #a0522d 174 | 175 | #9932cc 176 | 177 | #98fb98 178 | 179 | #9400d3 180 | 181 | #9370db 182 | 183 | #90ee90 184 | 185 | #8fbc8f 186 | 187 | #8b4513 188 | 189 | #8b008b 190 | 191 | #8b0000 192 | 193 | #8a2be2 194 | 195 | #87cefa 196 | 197 | #87ceeb 198 | 199 | #808080 200 | 201 | #808080 202 | 203 | #808000 204 | 205 | #800080 206 | 207 | #800000 208 | 209 | #7fffd4 210 | 211 | #7fff00 212 | 213 | #7cfc00 214 | 215 | #7b68ee 216 | 217 | #778899 218 | 219 | #778899 220 | 221 | #708090 222 | 223 | #708090 224 | 225 | #6b8e23 226 | 227 | #6a5acd 228 | 229 | #696969 230 | 231 | #696969 232 | 233 | #66cdaa 234 | 235 | #6495ed 236 | 237 | #5f9ea0 238 | 239 | #556b2f 240 | 241 | #4b0082 242 | 243 | #48d1cc 244 | 245 | #483d8b 246 | 247 | #4682b4 248 | 249 | #4169e1 250 | 251 | #40e0d0 252 | 253 | #3cb371 254 | 255 | #32cd32 256 | 257 | #2f4f4f 258 | 259 | #2f4f4f 260 | 261 | #2e8b57 262 | 263 | #228b22 264 | 265 | #20b2aa 266 | 267 | #1e90ff 268 | 269 | #191970 270 | 271 | #00ffff 272 | 273 | #00ffff 274 | 275 | #00ff7f 276 | 277 | #00ff00 278 | 279 | #00fa9a 280 | 281 | #00ced1 282 | 283 | #00bfff 284 | 285 | #008b8b 286 | 287 | #008080 288 | 289 | #008000 290 | 291 | #006400 292 | 293 | #0000ff 294 | 295 | #0000cd 296 | 297 | #00008b 298 | 299 | #000080 300 | 301 | #000000 302 | #646e82 303 | #fbbd27 304 | #9F70C0 305 | #7D7988 306 | 307 | 308 | #3498db 309 | #1abc9c 310 | #e67e22 311 | #9b59b6 312 | #e74c3c 313 | #f1c40f 314 | #D8D8D8 315 | #D8D8D8 316 | 317 | 318 | #2e9ee5 319 | #ef585c 320 | 321 | 322 | #3a2845 323 | 324 | #404040 325 | #C0000000 326 | #C0202020 327 | #C0202020 328 | #00000000 329 | #FF2572AC 330 | #FFFFFF 331 | #FFFFFF 332 | #000000 333 | #2572AC 334 | #000000 335 | #2572AC 336 | #FFFFFF 337 | 338 | -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16sp 5 | 25sp 6 | 30sp 7 | 22sp 8 | 10sp 9 | 20sp 10 | 150sp 11 | 18sp 12 | 35sp 13 | 15sp 14 | 15sp 15 | 12sp 16 | 10dp 17 | 12dp 18 | 4dp 19 | 24dp 20 | 12dp 21 | 16dp 22 | 16dp 23 | 24 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Launcher Demo 5 | Settings 6 | Hello world! 7 | 8 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 15 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /src/com/jit/demo/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.jit.demo.activity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import android.annotation.SuppressLint; 7 | import android.app.Activity; 8 | import android.graphics.BitmapFactory; 9 | import android.graphics.BitmapFactory.Options; 10 | import android.os.Bundle; 11 | import android.util.Log; 12 | 13 | import com.jit.demo.R; 14 | import com.jit.demo.adapter.ScrollAdapter; 15 | import com.jit.demo.model.MoveItem; 16 | import com.jit.demo.wight.ScrollLayout; 17 | import com.jit.demo.wight.ScrollLayout.OnAddOrDeletePage; 18 | import com.jit.demo.wight.ScrollLayout.OnEditModeListener; 19 | import com.jit.demo.wight.ScrollLayout.OnPageChangedListener; 20 | import com.lidroid.xutils.DbUtils; 21 | import com.lidroid.xutils.db.sqlite.Selector; 22 | import com.lidroid.xutils.exception.DbException; 23 | 24 | @SuppressLint("HandlerLeak") 25 | public class MainActivity extends Activity implements OnAddOrDeletePage, 26 | OnPageChangedListener, OnEditModeListener { 27 | 28 | // 滑动控件的容器Container 29 | private ScrollLayout mContainer; 30 | 31 | // Container的Adapter 32 | private ScrollAdapter mItemsAdapter; 33 | // Container中滑动控件列表 34 | private List mList; 35 | 36 | //xUtils中操纵SQLite的助手类 37 | private DbUtils mDbUtils; 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_main); 43 | // 从缓存中初始化滑动控件列表 44 | getDataFromCache(); 45 | // 初始化控件 46 | initView(); 47 | //初始化容器Adapter 48 | loadBackground(); 49 | } 50 | 51 | private void getDataFromCache() { 52 | mDbUtils = DbUtils.create(this); 53 | try { 54 | //使用xUtils,基于orderId从SQLite数据库中获取滑动控件 55 | mList = mDbUtils.findAll(Selector.from(MoveItem.class).orderBy("orderId", false)); 56 | } catch (DbException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | private void initView() { 62 | mContainer = (ScrollLayout) findViewById(R.id.container); 63 | //如果没有缓存数据,则手动添加10条 64 | if (mList == null || mList.size() == 0) { 65 | mList = new ArrayList(); 66 | for (int i = 1; i < 11; i++) { 67 | MoveItem item = new MoveItem(); 68 | //根据drawable name获取对于的ID 69 | item.setImgdown(getDrawableId("item" + i + "_down")); 70 | item.setImgurl(getDrawableId("item" + i + "_normal")); 71 | item.setOrderId(i); 72 | item.setMid(i); 73 | mList.add(item); 74 | } 75 | } 76 | //初始化Container的Adapter 77 | mItemsAdapter = new ScrollAdapter(this, mList); 78 | //设置Container添加删除Item的回调 79 | mContainer.setOnAddPage(this); 80 | //设置Container页面换转的回调,比如自第一页滑动第二页 81 | mContainer.setOnPageChangedListener(this); 82 | //设置Container编辑模式的回调,长按进入修改模式 83 | mContainer.setOnEditModeListener(this); 84 | //设置Adapter 85 | mContainer.setSaAdapter(mItemsAdapter); 86 | //动态设置Container每页的列数为2行 87 | mContainer.setColCount(2); 88 | //动态设置Container每页的行数为4行 89 | mContainer.setRowCount(4); 90 | //调用refreView绘制所有的Item 91 | mContainer.refreView(); 92 | } 93 | 94 | // 设置Container滑动背景图片 95 | private void loadBackground() { 96 | Options options = new Options(); 97 | options.inSampleSize = 2; 98 | mContainer.setBackGroud(BitmapFactory.decodeResource(getResources(), 99 | R.drawable.main_bg, options)); 100 | } 101 | 102 | private int getDrawableId(String name) { 103 | return getResources().getIdentifier(name, "drawable", "com.jit.demo"); 104 | } 105 | 106 | @Override 107 | public void onBackPressed() { 108 | //back键监听,如果在编辑模式,则取消编辑模式 109 | if (mContainer.isEditting()) { 110 | mContainer.showEdit(false); 111 | return; 112 | } else { 113 | try { 114 | //退出APP前,保存当前的Items,记得所有item的位置 115 | List list = mContainer.getAllMoveItems(); 116 | mDbUtils.saveAll(list); 117 | } catch (DbException e) { 118 | e.printStackTrace(); 119 | } 120 | super.onBackPressed(); 121 | android.os.Process.killProcess(android.os.Process.myPid()); 122 | } 123 | } 124 | 125 | @Override 126 | public void onEdit() { 127 | Log.e("test", "onEdit"); 128 | } 129 | 130 | @Override 131 | public void onPage2Other(int former, int current) { 132 | Log.e("test", "former-->" + former +" current-->" + current); 133 | } 134 | 135 | public void onAddOrDeletePage(int page, boolean isAdd) { 136 | Log.e("test", "page-->" + page +" isAdd-->" + isAdd); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/com/jit/demo/adapter/ScrollAdapter.java: -------------------------------------------------------------------------------- 1 | package com.jit.demo.adapter; 2 | 3 | import java.lang.ref.SoftReference; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Set; 8 | import android.annotation.SuppressLint; 9 | import android.content.Context; 10 | import android.graphics.drawable.Drawable; 11 | import android.graphics.drawable.StateListDrawable; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.widget.ImageView; 15 | import com.jit.demo.R; 16 | import com.jit.demo.model.MoveItem; 17 | import com.jit.demo.wight.ScrollLayout.SAdapter; 18 | 19 | @SuppressLint("UseSparseArrays") 20 | public class ScrollAdapter implements SAdapter { 21 | 22 | private Context mContext; 23 | private LayoutInflater mInflater; 24 | 25 | private List mList; 26 | private HashMap> mCache; 27 | 28 | public ScrollAdapter(Context context, List list) { 29 | 30 | this.mContext = context; 31 | this.mInflater = LayoutInflater.from(context); 32 | 33 | this.mList = list; 34 | this.mCache = new HashMap>(); 35 | } 36 | 37 | @Override 38 | public View getView(int position) { 39 | View view = null; 40 | if (position < mList.size()) { 41 | MoveItem moveItem = mList.get(position); 42 | view = mInflater.inflate(R.layout.item, null); 43 | ImageView iv = (ImageView) view.findViewById(R.id.content_iv); 44 | StateListDrawable states = new StateListDrawable(); 45 | int imgUrl = moveItem.getImgurl(); 46 | int imgUrlDown = moveItem.getImgdown(); 47 | 48 | Drawable pressed = null; 49 | Drawable normal = null; 50 | 51 | SoftReference p = mCache.get(imgUrlDown); 52 | if (p != null) { 53 | pressed = p.get(); 54 | } 55 | 56 | SoftReference n = mCache.get(imgUrl); 57 | if (n != null) { 58 | normal = n.get(); 59 | } 60 | 61 | if (pressed == null) { 62 | pressed = mContext.getResources().getDrawable(imgUrlDown); 63 | mCache.put(imgUrlDown, new SoftReference(pressed)); 64 | } 65 | 66 | if (normal == null) { 67 | normal = mContext.getResources().getDrawable(imgUrl); 68 | mCache.put(imgUrl, new SoftReference(normal)); 69 | } 70 | 71 | states.addState(new int[] {android.R.attr.state_pressed},pressed); 72 | states.addState(new int[] {android.R.attr.state_focused},pressed); 73 | states.addState(new int[] { }, normal); 74 | 75 | iv.setImageDrawable(states); 76 | view.setTag(moveItem); 77 | } 78 | return view; 79 | } 80 | 81 | @Override 82 | public int getCount() { 83 | return mList.size(); 84 | } 85 | 86 | @Override 87 | public void exchange(int oldPosition, int newPositon) { 88 | MoveItem item = mList.get(oldPosition); 89 | mList.remove(oldPosition); 90 | mList.add(newPositon, item); 91 | } 92 | 93 | private OnDataChangeListener dataChangeListener = null; 94 | 95 | public interface OnDataChangeListener { 96 | void ondataChange(); 97 | 98 | } 99 | 100 | public OnDataChangeListener getOnDataChangeListener() { 101 | return dataChangeListener; 102 | } 103 | 104 | public void setOnDataChangeListener(OnDataChangeListener dataChangeListener) { 105 | this.dataChangeListener = dataChangeListener; 106 | } 107 | 108 | public void delete(int position) { 109 | if (position < getCount()) { 110 | mList.remove(position); 111 | } 112 | } 113 | 114 | public void add(MoveItem item) { 115 | mList.add(item); 116 | } 117 | 118 | public MoveItem getMoveItem(int position) { 119 | return mList.get(position); 120 | } 121 | 122 | public void recycleCache() { 123 | if (mCache != null) { 124 | Set keys = mCache.keySet(); 125 | for (Iterator it = keys.iterator(); it.hasNext();) { 126 | Integer key = it.next(); 127 | SoftReference reference = mCache.get(key); 128 | if (reference != null) { 129 | reference.clear(); 130 | } 131 | } 132 | mCache.clear(); 133 | mCache = null; 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/com/jit/demo/model/MoveItem.java: -------------------------------------------------------------------------------- 1 | package com.jit.demo.model; import java.io.Serializable; import com.lidroid.xutils.db.annotation.Id; public class MoveItem implements Serializable { private static final long serialVersionUID = 3388701081007512693L; @Id private int _id; //id private int mid; //正常模式下的item的Drawable Id private int img_normal; //按下模式下的item的Drawable Id private int img_pressed; //item的排序字段 private int orderId; public int get_id() { return _id; } public void set_id(int _id) { this._id = _id; } public int getMid() { return mid; } public void setMid(int mid) { this.mid = mid; } public int getImgurl() { return img_normal; } public void setImgurl(int imgurl) { this.img_normal = imgurl; } public int getImgdown() { return img_pressed; } public void setImgdown(int imgdown) { this.img_pressed = imgdown; } public int getOrderId() { return orderId; } public void setOrderId(int orderId) { this.orderId = orderId; } } -------------------------------------------------------------------------------- /src/com/jit/demo/model/MoveItems.java: -------------------------------------------------------------------------------- 1 | package com.jit.demo.model; import java.io.Serializable; import java.util.List; public class MoveItems implements Serializable { private static final long serialVersionUID = -7224258990836336830L; private List allItems; private List existItems; public List getAllItems() { return allItems; } public void setAllItems(List allItems) { this.allItems = allItems; } public List getExistItems() { return existItems; } public void setExistItems(List existItems) { this.existItems = existItems; } public MoveItems(List allItems, List existItems) { super(); this.allItems = allItems; this.existItems = existItems; } public MoveItems() { super(); } } -------------------------------------------------------------------------------- /src/com/jit/demo/util/DensityUtil.java: -------------------------------------------------------------------------------- 1 | package com.jit.demo.util; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | public class DensityUtil { 7 | 8 | public static final float getHeightInPx(Context context) { 9 | final float height = context.getResources().getDisplayMetrics().heightPixels; 10 | return height; 11 | } 12 | 13 | public static final float getWidthInPx(Context context) { 14 | final float width = context.getResources().getDisplayMetrics().widthPixels; 15 | return width; 16 | } 17 | 18 | public static final int getHeightInDp(Context context) { 19 | final float height = context.getResources().getDisplayMetrics().heightPixels; 20 | int heightInDp = px2dip(context, height); 21 | return heightInDp; 22 | } 23 | 24 | public static final int getWidthInDp(Context context) { 25 | final float height = context.getResources().getDisplayMetrics().heightPixels; 26 | int widthInDp = px2dip(context, height); 27 | return widthInDp; 28 | } 29 | 30 | public static int dip2px(Context context, float dpValue) { 31 | final float scale = context.getResources().getDisplayMetrics().density; 32 | return (int) (dpValue * scale + 0.5f); 33 | } 34 | 35 | public static int px2dip(Context context, float pxValue) { 36 | final float scale = context.getResources().getDisplayMetrics().density; 37 | return (int) (pxValue / scale + 0.5f); 38 | } 39 | 40 | public static int px2sp(Context context, float pxValue) { 41 | final float scale = context.getResources().getDisplayMetrics().density; 42 | return (int) (pxValue / scale + 0.5f); 43 | } 44 | 45 | public static int sp2px(Context context, float spValue) { 46 | final float scale = context.getResources().getDisplayMetrics().density; 47 | return (int) (spValue * scale + 0.5f); 48 | } 49 | 50 | public static int getHeight(View view) { 51 | int w = View.MeasureSpec.makeMeasureSpec(0, 52 | View.MeasureSpec.UNSPECIFIED); 53 | int h = View.MeasureSpec.makeMeasureSpec(0, 54 | View.MeasureSpec.UNSPECIFIED); 55 | view.measure(w, h); 56 | return view.getMeasuredHeight(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/jit/demo/wight/ScrollLayout.java: -------------------------------------------------------------------------------- 1 | package com.jit.demo.wight; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.graphics.Bitmap; 10 | import android.graphics.Canvas; 11 | import android.graphics.Paint; 12 | import android.graphics.PixelFormat; 13 | import android.graphics.PointF; 14 | import android.graphics.Rect; 15 | import android.graphics.drawable.Drawable; 16 | import android.util.AttributeSet; 17 | import android.util.Log; 18 | import android.view.Gravity; 19 | import android.view.MotionEvent; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.view.WindowManager; 23 | import android.view.animation.Animation; 24 | import android.view.animation.Animation.AnimationListener; 25 | import android.view.animation.TranslateAnimation; 26 | import android.widget.ImageView; 27 | import android.widget.Scroller; 28 | 29 | import com.jit.demo.R; 30 | import com.jit.demo.adapter.ScrollAdapter; 31 | import com.jit.demo.adapter.ScrollAdapter.OnDataChangeListener; 32 | import com.jit.demo.model.MoveItem; 33 | import com.jit.demo.util.DensityUtil; 34 | import com.lidroid.xutils.DbUtils; 35 | import com.lidroid.xutils.db.sqlite.WhereBuilder; 36 | import com.lidroid.xutils.exception.DbException; 37 | 38 | public class ScrollLayout extends ViewGroup implements OnDataChangeListener { 39 | 40 | //容器的Adapter 41 | private ScrollAdapter mAdapter; 42 | 43 | //左边距 44 | private int leftPadding = 0; 45 | //右边距 46 | private int rightPadding = 0; 47 | //上边距 48 | private int topPadding = 0; 49 | //下边距 50 | private int bottomPadding = 0; 51 | 52 | //每个Item图片宽度的半长,用于松下手指时的动画 53 | private int halfBitmapWidth; 54 | //同上 55 | private int halfBitmapHeight; 56 | 57 | //动态设置行数 58 | private int rowCount = 1; 59 | //动态设置列数 60 | private int colCount = 1; 61 | //每一页的Item总数 62 | private int itemPerPage = 1; 63 | 64 | //行间距 65 | private int rowSpace = 0; 66 | //列间距 67 | private int colSpace = 0; 68 | 69 | //item的宽度 70 | private int childWidth = 0; 71 | //item的高度 72 | private int childHeight = 0; 73 | 74 | //手机屏幕宽度 75 | private int screenWidth = 0; 76 | //手机屏幕高度 77 | private int screenHeight = 0; 78 | 79 | //总Item数 80 | private int totalItem = 0; 81 | //总页数 82 | private int totalPage = 0; 83 | //当前屏数 84 | private int mCurScreen; 85 | //默认屏数为0,即第一屏 86 | private int mDefaultScreen = 0; 87 | 88 | //上次位移滑动到的X坐标位置 89 | private float mLastMotionX; 90 | //上次位移滑动到的Y坐标位置 91 | private float mLastMotionY; 92 | 93 | //拖动点的X坐标(加上当前屏数 * screenWidth) 94 | private int dragPointX; 95 | //拖动点的Y坐标 96 | private int dragPointY; 97 | //X坐标偏移量 98 | private int dragOffsetX; 99 | //Y坐标偏移量 100 | private int dragOffsetY; 101 | 102 | //拖拽点的位置编号,每个Item对应一个位置编号,自增 103 | private int dragPosition = -1; 104 | 105 | //临时交换位置的编号 106 | private int temChangPosition = -1; 107 | 108 | //window管理器,负责随手势显示拖拽View 109 | private WindowManager windowManager; 110 | private WindowManager.LayoutParams windowParams; 111 | 112 | //拖拽Item的子View 113 | private ImageView dragImageView; 114 | //拖拽View对应的位图 115 | private Bitmap dragBitmap; 116 | 117 | //页面滚动的Scroll管理器 118 | private Scroller mScroller; 119 | 120 | //三种滑动状态,默认为静止状态 121 | private int Mode_Free = 0; //静止状态 122 | private int Mode_Drag = 1; //当前页面下,拖动状态 123 | private int Mode_Scroll = 2; //跨页面滚动状态 124 | private int Mode = Mode_Free; 125 | 126 | //手势落下的X坐标 127 | private int startX = 0; 128 | 129 | //编辑状态标识 130 | private boolean isEditting; 131 | 132 | private Context mContext; 133 | 134 | //Container的背景 135 | private Bitmap background; 136 | //背景绘制的Paint 137 | private Paint paint = new Paint(1); 138 | 139 | //系列动画执行完成标识的集合 140 | private HashMap animationMap = new HashMap(); 141 | 142 | //用来判断滑动到哪一个item的位置 143 | private Rect frame; 144 | 145 | //页面滑动的监听 146 | private OnPageChangedListener pageChangedListener; 147 | //删除或增加页面的监听 148 | private OnAddOrDeletePage onAddPage; 149 | //Container编辑模式的监听 150 | private OnEditModeListener onEditModeListener; 151 | 152 | public ScrollLayout(Context context) { 153 | super(context); 154 | init(context); 155 | } 156 | 157 | public ScrollLayout(Context context, AttributeSet attrs) { 158 | super(context, attrs); 159 | init(context); 160 | } 161 | 162 | public ScrollLayout(Context context, AttributeSet attrs, int defStyle) { 163 | super(context, attrs, defStyle); 164 | init(context); 165 | } 166 | 167 | //初始化成员变量,同时设置OnClick监听 168 | private void init(Context context) { 169 | this.mContext = context; 170 | this.mScroller = new Scroller(context); 171 | 172 | this.mCurScreen = mDefaultScreen; 173 | 174 | this.rightPadding = DensityUtil.dip2px(mContext, 70); 175 | this.leftPadding = DensityUtil.dip2px(mContext, 10); 176 | this.topPadding = DensityUtil.dip2px(mContext, 30); 177 | this.bottomPadding = DensityUtil.dip2px(mContext, 30); 178 | 179 | this.colSpace = DensityUtil.dip2px(mContext, 15); 180 | this.rowSpace = DensityUtil.dip2px(mContext, 15); 181 | 182 | if (mAdapter != null) 183 | refreView(); 184 | 185 | this.setOnClickListener(new OnClickListener() { 186 | 187 | @Override 188 | public void onClick(View v) { 189 | showEdit(false); 190 | } 191 | }); 192 | } 193 | 194 | //添加一个item 195 | public void addItemView(MoveItem item) { 196 | mAdapter.add(item); 197 | this.addView(getView(mAdapter.getCount() - 1)); 198 | showEdit(isEditting); 199 | requestLayout(); 200 | } 201 | 202 | @Override 203 | public void addView(View child, int index, LayoutParams params) { 204 | child.setClickable(true); 205 | if (child.getVisibility() != View.VISIBLE) 206 | child.setVisibility(View.VISIBLE); 207 | super.addView(child, index, params); 208 | int pages = (int) Math.ceil(getChildCount() * 1.0 / itemPerPage); 209 | if (pages > totalPage) { 210 | if (this.onAddPage != null) 211 | onAddPage.onAddOrDeletePage(totalPage, true); 212 | totalPage = pages; 213 | } 214 | } 215 | 216 | //绘制Container所有item 217 | public void refreView() { 218 | removeAllViews(); 219 | for (int i = 0; i < mAdapter.getCount(); i++) { 220 | this.addView(getView(i)); 221 | } 222 | totalPage = (int) Math.ceil(getChildCount() * 1.0 / itemPerPage); 223 | requestLayout(); 224 | } 225 | 226 | @Override 227 | public void removeView(View view) { 228 | super.removeView(view); 229 | int pages = (int) Math.ceil(getChildCount() * 1.0 / itemPerPage); 230 | if (pages < totalPage) { 231 | if (this.onAddPage != null) 232 | onAddPage.onAddOrDeletePage(totalPage, false); 233 | totalPage = pages; 234 | } 235 | } 236 | 237 | @Override 238 | public void removeViewAt(int index) { 239 | super.removeViewAt(index); 240 | int pages = (int) Math.ceil(getChildCount() * 1.0 / itemPerPage); 241 | if (pages < totalPage) { 242 | totalPage = pages; 243 | if (this.onAddPage != null) 244 | onAddPage.onAddOrDeletePage(totalPage, false); 245 | } 246 | } 247 | 248 | 249 | @Override 250 | public boolean dispatchTouchEvent(MotionEvent ev) { 251 | final int action = ev.getAction(); 252 | final float x = ev.getX(); 253 | final float y = ev.getY(); 254 | int thresholdX = DensityUtil.dip2px(mContext, 8); 255 | switch (action) { 256 | case MotionEvent.ACTION_DOWN: 257 | startX = (int) x; 258 | if (mScroller.isFinished()) { 259 | if (!mScroller.isFinished()) { 260 | mScroller.abortAnimation(); 261 | } 262 | temChangPosition = dragPosition = pointToPosition((int) x, (int) y); 263 | dragOffsetX = (int) (ev.getRawX() - x); 264 | dragOffsetY = (int) (ev.getRawY() - y); 265 | 266 | mLastMotionX = x; 267 | mLastMotionY = y; 268 | startX = (int) x; 269 | } 270 | break; 271 | case MotionEvent.ACTION_MOVE: 272 | int deltaX = (int) (mLastMotionX - x); 273 | 274 | if (IsCanMove(deltaX) && Math.abs(deltaX) > thresholdX && Mode != Mode_Drag) { 275 | mLastMotionX = x; 276 | scrollBy(deltaX, 0); 277 | Mode = Mode_Scroll; 278 | } 279 | 280 | if (Mode == Mode_Drag) { 281 | onDrag((int) x, (int) y); 282 | } 283 | break; 284 | case MotionEvent.ACTION_UP: 285 | float distance = ev.getRawX() - startX; 286 | if (distance > screenWidth / 6 && mCurScreen > 0 287 | && Mode != Mode_Drag) { 288 | snapToScreen(mCurScreen - 1); 289 | } else if (distance < -screenWidth / 6 290 | && mCurScreen < totalPage - 1 && Mode != Mode_Drag) { 291 | snapToScreen(mCurScreen + 1); 292 | } else if (Mode != Mode_Drag) { 293 | snapToDestination(); 294 | } 295 | if (Mode == Mode_Drag) { 296 | stopDrag(); 297 | } 298 | if (dragImageView != null) { 299 | animationMap.clear(); 300 | showDropAnimation((int) x, (int) y); 301 | } 302 | startX = 0; 303 | break; 304 | case MotionEvent.ACTION_CANCEL: 305 | showEdit(false); 306 | } 307 | super.dispatchTouchEvent(ev); 308 | return true; 309 | } 310 | 311 | //开始拖动 312 | private void startDrag(Bitmap bm, int x, int y, View itemView) { 313 | dragPointX = x - itemView.getLeft() + mCurScreen * screenWidth; 314 | dragPointY = y - itemView.getTop(); 315 | windowParams = new WindowManager.LayoutParams(); 316 | 317 | windowParams.gravity = Gravity.TOP | Gravity.LEFT; 318 | windowParams.x = x - dragPointX + dragOffsetX; 319 | windowParams.y = y - dragPointY + dragOffsetY; 320 | windowParams.height = LayoutParams.WRAP_CONTENT; 321 | windowParams.width = LayoutParams.WRAP_CONTENT; 322 | windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 323 | | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 324 | | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 325 | | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 326 | 327 | windowParams.format = PixelFormat.TRANSLUCENT; 328 | windowParams.windowAnimations = 0; 329 | windowParams.alpha = 0.8f; 330 | 331 | ImageView iv = new ImageView(getContext()); 332 | iv.setImageBitmap(bm); 333 | dragBitmap = bm; 334 | windowManager = (WindowManager) getContext().getSystemService( 335 | Context.WINDOW_SERVICE); 336 | windowManager.addView(iv, windowParams); 337 | dragImageView = iv; 338 | Mode = Mode_Drag; 339 | 340 | halfBitmapWidth = bm.getWidth() / 2; 341 | halfBitmapHeight = bm.getHeight() / 2; 342 | 343 | for (int i = 0; i < getChildCount(); i++) { 344 | getChildAt(i).getBackground().setAlpha((int) (0.8f * 255)); 345 | } 346 | } 347 | 348 | //停止拖动 349 | private void stopDrag() { 350 | recoverChildren(); 351 | if (Mode == Mode_Drag) { 352 | if (getChildAt(dragPosition).getVisibility() != View.VISIBLE) 353 | getChildAt(dragPosition).setVisibility(View.VISIBLE); 354 | Mode = Mode_Free; 355 | Log.e("test", "scroll menu move"); 356 | mContext.sendBroadcast(new Intent("com.stg.menu_move")); 357 | } 358 | } 359 | 360 | //使用Map集合记录,防止动画执行混乱 361 | private class NotifyDataSetListener implements AnimationListener { 362 | private int movedPosition; 363 | 364 | public NotifyDataSetListener(int primaryPosition) { 365 | this.movedPosition = primaryPosition; 366 | } 367 | 368 | @Override 369 | public void onAnimationEnd(Animation animation) { 370 | if (animationMap.containsKey(movedPosition)) { 371 | // remove from map when end 372 | animationMap.remove(movedPosition); 373 | } 374 | } 375 | 376 | @Override 377 | public void onAnimationRepeat(Animation animation) { 378 | } 379 | 380 | @Override 381 | public void onAnimationStart(Animation animation) { 382 | // put into map when start 383 | animationMap.put(movedPosition, true); 384 | } 385 | } 386 | 387 | //返回滑动的位移动画,比较复杂,有兴趣的可以看看 388 | private Animation animationPositionToPosition(int oldP, int newP, 389 | boolean isCrossScreen, boolean isForward) { 390 | PointF oldPF = positionToPoint2(oldP); 391 | PointF newPF = positionToPoint2(newP); 392 | 393 | TranslateAnimation animation = null; 394 | 395 | // when moving forward across pages,the first item of the new page moves 396 | // backward 397 | if (oldP != 0 && (oldP + 1) % itemPerPage == 0 && isForward) { 398 | animation = new TranslateAnimation(screenWidth - oldPF.x, 0, 399 | DensityUtil.dip2px(mContext, 25) - screenHeight, 0); 400 | animation.setDuration(800); 401 | } 402 | // when moving backward across pages,the last item of the new page moves 403 | // forward 404 | else if (oldP != 0 && oldP % itemPerPage == 0 && isCrossScreen && !isForward) { 405 | animation = new TranslateAnimation(newPF.x - screenWidth, 0, 406 | screenHeight - DensityUtil.dip2px(mContext, 25), 0); 407 | animation.setDuration(800); 408 | } 409 | // regular animation between two neighbor items 410 | else { 411 | animation = new TranslateAnimation(newPF.x - oldPF.x, 0, newPF.y 412 | - oldPF.y, 0); 413 | animation.setDuration(500); 414 | } 415 | animation.setFillAfter(true); 416 | animation.setAnimationListener(new NotifyDataSetListener(oldP)); 417 | 418 | return animation; 419 | } 420 | 421 | 422 | //滑动合法性的判断,防止滑动到空白区域 423 | private boolean IsCanMove(int deltaX) { 424 | if (getScrollX() <= 0 && deltaX < 0) { 425 | return false; 426 | } 427 | if (getScrollX() >= (totalPage - 1) * screenWidth && deltaX > 0) { 428 | return false; 429 | } 430 | return true; 431 | } 432 | 433 | //判断滑动的一系列动画是否有冲突 434 | private boolean isMovingFastConflict(int moveNum) { 435 | int itemsMoveNum = Math.abs(moveNum); 436 | int temp = dragPosition; 437 | for (int i = 0; i < itemsMoveNum; i++) { 438 | int holdPosition = moveNum > 0 ? temp + 1 : temp - 1; 439 | if (animationMap.containsKey(holdPosition)) { 440 | return true; 441 | } 442 | temp = holdPosition; 443 | } 444 | return false; 445 | } 446 | 447 | //执行位置动画 448 | private void movePostionAnimation(int oldP, int newP) { 449 | int moveNum = newP - oldP; 450 | boolean isCrossScreen = false; 451 | boolean isForward = false; 452 | if (moveNum != 0 && !isMovingFastConflict(moveNum)) { 453 | int absMoveNum = Math.abs(moveNum); 454 | for (int i = Math.min(oldP, newP) + 1; i <= Math.max(oldP, newP); i++) { 455 | if (i % 8 == 0) { 456 | isCrossScreen = true; 457 | } 458 | } 459 | if (isCrossScreen) { 460 | isForward = moveNum < 0 ? false : true; 461 | } 462 | for (int i = 0; i < absMoveNum; i++) { 463 | int holdPosition = (moveNum > 0) ? oldP + 1 : oldP - 1; 464 | View view = getChildAt(holdPosition); 465 | if (view != null) { 466 | view.startAnimation(animationPositionToPosition(oldP, 467 | holdPosition, isCrossScreen, isForward)); 468 | } 469 | oldP = holdPosition; 470 | } 471 | } 472 | } 473 | 474 | //滑动过程中,使所有的item暗掉 475 | private void fadeChildren() { 476 | final int count = getChildCount() - 1; 477 | for (int i = count; i >= 0; i--) { 478 | View child = getChildAt(i); 479 | child.getBackground().setAlpha(180); 480 | } 481 | } 482 | 483 | //滑动停止后,恢复item的透明度 484 | private void recoverChildren() { 485 | final int count = getChildCount() - 1; 486 | for (int i = count; i >= 0; i--) { 487 | final View child = getChildAt(i); 488 | // child.setAlpha(1.0f); 489 | child.getBackground().setAlpha(255); 490 | Drawable drawable = child.getBackground(); 491 | if (drawable != null) { 492 | child.getBackground().setAlpha(255); 493 | } 494 | } 495 | } 496 | 497 | public int getChildIndex(View view) { 498 | if (view != null && view.getParent() instanceof ScrollLayout) { 499 | final int childCount = ((ScrollLayout) view.getParent()).getChildCount(); 500 | for (int i = 0; i < childCount; i++) { 501 | if (view == ((ScrollLayout) view.getParent()).getChildAt(i)) { 502 | return i; 503 | } 504 | } 505 | } 506 | return -1; 507 | } 508 | 509 | //获取特定position下的item View 510 | private View getView(final int position) { 511 | View view = null; 512 | if (mAdapter != null) { 513 | view = mAdapter.getView(position); 514 | view.setOnLongClickListener(new OnLongClickListener() { 515 | @Override 516 | public boolean onLongClick(View v) { 517 | Log.e("test", "onLongClick"); 518 | // if (Mode != Mode_Scroll) { 519 | return onItemLongClick(v); 520 | // } 521 | // return false; 522 | } 523 | }); 524 | 525 | } 526 | return view; 527 | } 528 | 529 | @Override 530 | public void computeScroll() { 531 | if (mScroller.computeScrollOffset()) { 532 | scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 533 | postInvalidate(); 534 | } 535 | } 536 | 537 | //Container背景滑动的实现,下面是计算公式 538 | // int w = x * ((width - n) / (totalPage - 1)) / getWidth(); 539 | @Override 540 | protected void dispatchDraw(Canvas canvas) { 541 | if (this.background != null) { 542 | int width = this.background.getWidth(); 543 | int height = this.background.getHeight(); 544 | int x = getScrollX(); 545 | int n = height * getWidth() / getHeight(); 546 | int w; 547 | if (totalPage == 1) { 548 | w = x * (width - n) / 1 / getWidth(); 549 | } else { 550 | w = x * ((width - n) / (totalPage - 1)) / getWidth(); 551 | } 552 | canvas.drawBitmap(this.background, new Rect(w, 0, n + w, height), new Rect( 553 | x, 0, x + getWidth(), getHeight()), this.paint); 554 | } 555 | super.dispatchDraw(canvas); 556 | } 557 | 558 | //获取当前Container状态下,所有的item 559 | public List getAllMoveItems() { 560 | List items = new ArrayList(); 561 | int count = getChildCount(); 562 | MoveItem item = null; 563 | for (int i = 0; i < count; i++) { 564 | item = (MoveItem) getChildAt(i).getTag(); 565 | items.add(item); 566 | } 567 | return items; 568 | } 569 | 570 | public Bitmap getBg() { 571 | return background; 572 | } 573 | 574 | public int getBottomPadding() { 575 | return bottomPadding; 576 | } 577 | 578 | public int getColCount() { 579 | return colCount; 580 | } 581 | 582 | public int getColSpace() { 583 | return colSpace; 584 | } 585 | 586 | public int getCurrentPage() { 587 | return mCurScreen; 588 | } 589 | 590 | public int getLeftPadding() { 591 | return leftPadding; 592 | } 593 | 594 | public OnAddOrDeletePage getOnCaculatePage() { 595 | return onAddPage; 596 | } 597 | 598 | public OnEditModeListener getOnEditModeListener() { 599 | return onEditModeListener; 600 | } 601 | 602 | public OnPageChangedListener getOnPageChangedListener() { 603 | return pageChangedListener; 604 | } 605 | 606 | public int getRightPadding() { 607 | return rightPadding; 608 | } 609 | 610 | public int getRowCount() { 611 | return rowCount; 612 | } 613 | 614 | public int getRowSpace() { 615 | return rowSpace; 616 | } 617 | 618 | public ScrollAdapter getSaAdapter() { 619 | return mAdapter; 620 | } 621 | 622 | public int getTopPadding() { 623 | return topPadding; 624 | } 625 | 626 | public int getTotalItem() { 627 | return totalItem; 628 | } 629 | 630 | public int getTotalPage() { 631 | return totalPage; 632 | } 633 | 634 | 635 | 636 | @Override 637 | public void ondataChange() { 638 | refreView(); 639 | } 640 | 641 | //根据手势绘制不断变化位置的dragView 642 | private void onDrag(int x, int y) { 643 | if (dragImageView != null) { 644 | windowParams.alpha = 0.8f; 645 | windowParams.x = x - dragPointX + dragOffsetX; 646 | windowParams.y = y - dragPointY + dragOffsetY; 647 | windowManager.updateViewLayout(dragImageView, windowParams); 648 | } 649 | int tempPosition = pointToPosition(x, y); 650 | if (tempPosition != -1) { 651 | dragPosition = tempPosition; 652 | } 653 | View view = getChildAt(temChangPosition); 654 | if (view == null) { 655 | stopDrag(); 656 | return; 657 | } 658 | view.setVisibility(View.INVISIBLE); 659 | if (temChangPosition != dragPosition) { 660 | View dragView = getChildAt(temChangPosition); 661 | movePostionAnimation(temChangPosition, dragPosition); 662 | removeViewAt(temChangPosition); 663 | addView(dragView, dragPosition); 664 | getChildAt(dragPosition).setVisibility(View.INVISIBLE); 665 | this.getSaAdapter().exchange(temChangPosition, dragPosition); 666 | temChangPosition = dragPosition; 667 | } 668 | 669 | if (x > getRight() - DensityUtil.dip2px(mContext, 25) 670 | && mCurScreen < totalPage - 1 && mScroller.isFinished() 671 | && x - startX > 10) { 672 | snapToScreen(mCurScreen + 1, false); 673 | } else if (x - getLeft() < DensityUtil.dip2px(mContext, 35) 674 | && mCurScreen > 0 && mScroller.isFinished() && x - startX < -10) { 675 | snapToScreen(mCurScreen - 1, false); 676 | } 677 | 678 | } 679 | 680 | public boolean onItemLongClick(View v) { 681 | if (mScroller.isFinished()) { 682 | v.destroyDrawingCache(); 683 | v.setDrawingCacheEnabled(true); 684 | fadeChildren(); 685 | if (onEditModeListener != null) 686 | onEditModeListener.onEdit(); 687 | Bitmap bm = Bitmap.createBitmap(v.getDrawingCache()); 688 | showEdit(true); 689 | v.setVisibility(View.GONE); 690 | startDrag(bm, (int) (mLastMotionX), (int) (mLastMotionY), v); 691 | return true; 692 | } 693 | return false; 694 | 695 | } 696 | 697 | @Override 698 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 699 | final int childCount = getChildCount(); 700 | for (int i = 0; i < childCount; i++) { 701 | final View childView = getChildAt(i); 702 | if (childView.getVisibility() != View.GONE) { 703 | childWidth = childView.getMeasuredWidth(); 704 | childHeight = childView.getMeasuredHeight(); 705 | int page = i / itemPerPage; 706 | 707 | int row = i / colCount % rowCount; 708 | int col = i % colCount; 709 | int left = leftPadding + page * screenWidth + col 710 | * (colSpace + childWidth); 711 | int top = topPadding + row * (rowSpace + childHeight); 712 | 713 | childView.layout(left, top, left + childWidth, 714 | top + childView.getMeasuredHeight()); 715 | } 716 | } 717 | } 718 | 719 | @Override 720 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 721 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 722 | 723 | final int width = MeasureSpec.getSize(widthMeasureSpec); 724 | MeasureSpec.getMode(widthMeasureSpec); 725 | 726 | final int height = MeasureSpec.getSize(heightMeasureSpec); 727 | MeasureSpec.getMode(heightMeasureSpec); 728 | 729 | screenWidth = width; 730 | screenHeight = height; 731 | int usedWidth = width - leftPadding - rightPadding - (colCount - 1) 732 | * colSpace; 733 | int usedheight = ((height - topPadding - bottomPadding - (rowCount - 1) 734 | * rowSpace)); 735 | int childWidth = usedWidth / colCount; 736 | int childHeight = usedheight / rowCount; 737 | final int count = getChildCount(); 738 | for (int i = 0; i < count; i++) { 739 | View child = getChildAt(i); 740 | int childWidthSpec = getChildMeasureSpec( 741 | MeasureSpec 742 | .makeMeasureSpec(childWidth, MeasureSpec.EXACTLY), 743 | 20, childWidth); 744 | int childHeightSpec = getChildMeasureSpec( 745 | MeasureSpec.makeMeasureSpec(childHeight, 746 | MeasureSpec.EXACTLY), 20, childHeight); 747 | child.measure(childWidthSpec, childHeightSpec); 748 | } 749 | scrollTo(mCurScreen * width, 0); 750 | } 751 | 752 | //根据坐标,判断当前item所属的位置,即编号 753 | public int pointToPosition(int x, int y) { 754 | int locX = x + mCurScreen * getWidth(); 755 | 756 | if (frame == null) 757 | frame = new Rect(); 758 | final int count = getChildCount(); 759 | for (int i = count - 1; i >= 0; i--) { 760 | final View child = getChildAt(i); 761 | child.getHitRect(frame); 762 | if (frame.contains(locX, y)) { 763 | return i; 764 | } 765 | } 766 | return -1; 767 | } 768 | 769 | //item编号对应的左上角坐标 770 | public PointF positionToPoint1(int position) { 771 | PointF point = new PointF(); 772 | 773 | int page = position / itemPerPage; 774 | int row = position / colCount % rowCount; 775 | int col = position % colCount; 776 | int left = leftPadding + page * screenWidth + col 777 | * (colSpace + childWidth); 778 | int top = topPadding + row * (rowSpace + childHeight); 779 | 780 | point.x = left; 781 | point.y = top; 782 | return point; 783 | 784 | } 785 | 786 | public PointF positionToPoint2(int position) { 787 | PointF point = new PointF(); 788 | 789 | int row = position / colCount % rowCount; 790 | int col = position % colCount; 791 | int left = leftPadding + col * (colSpace + childWidth); 792 | int top = topPadding + row * (rowSpace + childHeight); 793 | 794 | point.x = left; 795 | point.y = top; 796 | return point; 797 | 798 | } 799 | 800 | public void setBackGroud(Bitmap paramBitmap) { 801 | this.background = paramBitmap; 802 | this.paint.setFilterBitmap(true); 803 | } 804 | 805 | public void setBottomPadding(int bottomPadding) { 806 | this.bottomPadding = bottomPadding; 807 | } 808 | 809 | public void setColCount(int colCount) { 810 | this.colCount = colCount; 811 | this.itemPerPage = this.colCount * this.rowCount; 812 | } 813 | 814 | public boolean isEditting() { 815 | return isEditting; 816 | } 817 | 818 | public void setColSpace(int colSpace) { 819 | this.colSpace = colSpace; 820 | } 821 | 822 | public void setLeftPadding(int leftPadding) { 823 | this.leftPadding = leftPadding; 824 | } 825 | 826 | public void setOnAddPage(OnAddOrDeletePage onAddPage) { 827 | this.onAddPage = onAddPage; 828 | } 829 | 830 | public void setOnEditModeListener(OnEditModeListener onEditModeListener) { 831 | this.onEditModeListener = onEditModeListener; 832 | } 833 | 834 | public void setOnPageChangedListener( 835 | OnPageChangedListener pageChangedListener) { 836 | this.pageChangedListener = pageChangedListener; 837 | } 838 | 839 | public void setRightPadding(int rightPadding) { 840 | this.rightPadding = rightPadding; 841 | } 842 | 843 | public void setRowCount(int rowCount) { 844 | this.rowCount = rowCount; 845 | this.itemPerPage = this.colCount * this.rowCount; 846 | } 847 | 848 | public void setRowSpace(int rowSpace) { 849 | this.rowSpace = rowSpace; 850 | } 851 | 852 | public void setSaAdapter(ScrollAdapter saAdapter) { 853 | this.mAdapter = saAdapter; 854 | this.mAdapter.setOnDataChangeListener(this); 855 | } 856 | 857 | public void setTopPadding(int topPadding) { 858 | this.topPadding = topPadding; 859 | } 860 | 861 | public void setTotalItem(int totalItem) { 862 | this.totalItem = totalItem; 863 | } 864 | 865 | //执行松手动画 866 | private void showDropAnimation(int x, int y) { 867 | ViewGroup moveView = (ViewGroup) getChildAt(dragPosition); 868 | TranslateAnimation animation = new TranslateAnimation(x 869 | - halfBitmapWidth - moveView.getLeft(), 0, y - halfBitmapHeight 870 | - moveView.getTop(), 0); 871 | animation.setFillAfter(false); 872 | animation.setDuration(300); 873 | moveView.setAnimation(animation); 874 | windowManager.removeView(dragImageView); 875 | dragImageView = null; 876 | 877 | if (dragBitmap != null) { 878 | dragBitmap = null; 879 | } 880 | 881 | for (int i = 0; i < getChildCount(); i++) { 882 | getChildAt(i).clearAnimation(); 883 | } 884 | } 885 | 886 | public void showEdit(boolean isEdit) { 887 | isEditting = isEdit; 888 | int count = getChildCount(); 889 | for (int i = 0; i < count; i++) { 890 | View child = getChildAt(i); 891 | ImageView iv = (ImageView) child.findViewById(R.id.delete_iv); 892 | iv.setTag(child.getTag()); 893 | iv.setVisibility(isEdit == true ? View.VISIBLE : View.GONE); 894 | if (isEdit) { 895 | iv.setOnClickListener(new DelItemClick(i)); 896 | } 897 | } 898 | 899 | if (isEdit == false) { 900 | int pages = (int) Math.ceil(getChildCount() * 1.0 / itemPerPage); 901 | if (pages < totalPage) { 902 | totalPage = pages; 903 | if (this.onAddPage != null) 904 | onAddPage.onAddOrDeletePage(totalPage + 1, false); 905 | } 906 | } 907 | } 908 | 909 | //滚屏 910 | public void snapToDestination() { 911 | final int screenWidth = getWidth(); 912 | final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth; 913 | if (destScreen >= 0 && destScreen < totalPage) { 914 | snapToScreen(destScreen); 915 | } 916 | } 917 | 918 | public void snapToScreen(int whichScreen) { 919 | snapToScreen(whichScreen, true); 920 | } 921 | 922 | public void snapToScreen(int whichScreen, boolean isFast) { 923 | // get the valid layout page 924 | whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); 925 | if (getScrollX() != (whichScreen * getWidth())) { 926 | 927 | final int delta = whichScreen * getWidth() - getScrollX(); 928 | 929 | if (pageChangedListener != null) 930 | pageChangedListener.onPage2Other(mCurScreen, whichScreen); 931 | 932 | if (!isFast) 933 | mScroller.startScroll(getScrollX(), 0, delta, 0, 800); 934 | else 935 | mScroller.startScroll(getScrollX(), 0, delta, 0, 500); 936 | mCurScreen = whichScreen; 937 | requestLayout(); 938 | invalidate(); // Redraw the layout 939 | } 940 | } 941 | 942 | /** 943 | * 删除按钮的功能处理 944 | * 945 | */ 946 | private final class DelItemClick implements OnClickListener { 947 | int deletePostion; 948 | 949 | public DelItemClick(int deletePostion) { 950 | this.deletePostion = deletePostion; 951 | } 952 | 953 | @Override 954 | public void onClick(View v) { 955 | if (v.getParent() != null) { 956 | if (mCurScreen < totalPage - 1) { 957 | 958 | } 959 | movePostionAnimation(deletePostion, getChildCount() - 1); 960 | removeView((ViewGroup) (v.getParent())); 961 | mAdapter.delete(deletePostion); 962 | MoveItem item = (MoveItem) v.getTag(); 963 | DbUtils utils = DbUtils.create(mContext); 964 | try { 965 | utils.delete(MoveItem.class,WhereBuilder.b("mid", "=", item.getMid())); 966 | } catch (DbException e) { 967 | e.printStackTrace(); 968 | } 969 | showEdit(false); 970 | showEdit(true); 971 | 972 | //如果删除后少了一屏,则移动到前一屏,并进行页面刷新 973 | if (getChildCount() % itemPerPage == 0) { 974 | snapToScreen(totalPage - 1); 975 | } 976 | } 977 | } 978 | } 979 | 980 | public interface SAdapter { 981 | void exchange(int oldPosition, int newPositon); 982 | int getCount(); 983 | View getView(int position); 984 | } 985 | 986 | public interface OnAddOrDeletePage { 987 | void onAddOrDeletePage(int page, boolean isAdd); 988 | } 989 | 990 | public interface OnEditModeListener { 991 | void onEdit(); 992 | } 993 | 994 | public interface OnPageChangedListener { 995 | void onPage2Other(int n1, int n2); 996 | } 997 | 998 | } 999 | --------------------------------------------------------------------------------