diff --git a/._README.md b/._README.md new file mode 100644 index 00000000..497cf3b3 Binary files /dev/null and b/._README.md differ diff --git a/.gitignore b/.gitignore index 8d8d99f2..bfdbd6c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,53 +1,53 @@ -# Android generated -bin/ -gen/ - -# Ant -build.xml -local.properties - -# Maven -target/ -pom.xml.* -release.properties - -# Eclipse -.classpath -.project -.externalToolBuilders/ -.apt_generated/ - -# IntelliJ -*.iml -*.ipr -*.iws -.idea/ -out/ -output/ -.gitignore.orig -.project.bak -.settings/org.eclipse.core.resources.prefs -.settings/org.eclipse.core.runtime.prefs -.settings/org.eclipse.jdt.apt.core.prefs -.settings/org.eclipse.jdt.core.prefs -.settings/org.eclipse.jdt.launching.prefs -.settings/ -.properties -**/*.iml -**/*/.idea -**/.idea -.gradle -build/ -**/.gradle -**/*/build -**/build -# key info: -ultimateandroid.jks -keystore.properties -gradleinfo.properties - - -# Ignore Gradle GUI config -gradle-app.setting -manifest-merger-release-report.txt -*.apk +# Android generated +bin/ +gen/ + +# Ant +build.xml +local.properties + +# Maven +target/ +pom.xml.* +release.properties + +# Eclipse +.classpath +.project +.externalToolBuilders/ +.apt_generated/ + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ +out/ +output/ +.gitignore.orig +.project.bak +.settings/org.eclipse.core.resources.prefs +.settings/org.eclipse.core.runtime.prefs +.settings/org.eclipse.jdt.apt.core.prefs +.settings/org.eclipse.jdt.core.prefs +.settings/org.eclipse.jdt.launching.prefs +.settings/ +.properties +**/*.iml +**/*/.idea +**/.idea +.gradle +build/ +**/.gradle +**/*/build +**/build +# key info: +ultimateandroid.jks +keystore.properties +gradleinfo.properties + + +# Ignore Gradle GUI config +gradle-app.setting +manifest-merger-release-report.txt +*.apk diff --git a/.travis.yml b/.travis.yml index 6a480206..63378264 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,43 +1,43 @@ -language: android - -# Turning off caching to avoid caching Issues -# cache: false -# Using the new Container-Based Infrastructure -sudo: false - -env: - global: - # Initiating clean Gradle output - - TERM=dumb - # Amount of memory granted to Gradle JVM - - GRADLE_OPTS="-Xmx512m -XX:MaxPermSize=512m" - # General Android settings used in builds - - ANDROID_TARGET=android-23 - -before_install: - # Making sure gradlew has executable permissions - - cd UltimateRecyclerView - - chmod a+x gradlew - -android: - components: - # We are using the latest revision of Android SDK Tools - - - android-23 - # The BuildTools version we are using for our project - - build-tools-23.0.1 - - - platform-tools - - tools - # Additional components - - extra-google-google_play_services - - extra-google-m2repository - - extra-android-m2repository - - licenses: - - 'android-sdk-license-.+' - -script: - - #./gradlew build - ./gradlew assembleDebug +language: android + +# Turning off caching to avoid caching Issues +# cache: false +# Using the new Container-Based Infrastructure +sudo: false + +env: + global: + # Initiating clean Gradle output + - TERM=dumb + # Amount of memory granted to Gradle JVM + - GRADLE_OPTS="-Xmx512m -XX:MaxPermSize=512m" + # General Android settings used in builds + - ANDROID_TARGET=android-23 + +before_install: + # Making sure gradlew has executable permissions + - cd UltimateRecyclerView + - chmod a+x gradlew + +android: + components: + # We are using the latest revision of Android SDK Tools + + - android-23 + # The BuildTools version we are using for our project + - build-tools-23.0.1 + + - platform-tools + - tools + # Additional components + - extra-google-google_play_services + - extra-google-m2repository + - extra-android-m2repository + + licenses: + - 'android-sdk-license-.+' + +script: + + #./gradlew build + ./gradlew assembleDebug diff --git a/LICENSE b/LICENSE index e06d2081..7b216eb0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,202 +1,202 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md index 88f958bf..163e4558 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,151 @@ -# UltimateRecyclerView - -[![Download](https://api.bintray.com/packages/jjhesk/maven/MenuURV/images/download.svg) ](https://bintray.com/jjhesk/maven/MenuURV/_latestVersion)[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)[![Stories in Ready](https://badge.waffle.io/cymcsg/UltimateRecyclerView.svg?label=ready&title=Ready)](http://waffle.io/cymcsg/UltimateRecyclerView) - - -[![Throughput Graph](https://graphs.waffle.io/cymcsg/UltimateRecyclerView/throughput.svg)](https://waffle.io/cymcsg/UltimateRecyclerView/metrics) - -#### Master branch:[![Build Status](https://travis-ci.org/cymcsg/UltimateRecyclerView.svg?branch=master)](https://travis-ci.org/cymcsg/UltimateRecyclerView) - - -##### Project website:[https://github.com/cymcsg/UltimateRecyclerView](https://github.com/cymcsg/UltimateRecyclerView) - - -### Quick Setup(Basic Usage) - -###### 1.Integration jcenter - -Please follow the latest publishing aar on jcenter. - -follow by the gradle code -```gradle -dependencies{ - compile 'com.hkm.ui:ultimaterecyclerview:0.5.8' -} -``` - -###### 2.Usage: - -``` xml - -``` - - -Remote server: dont forget to declare the repos location -``` -repositories { - jcenter() - maven { url "http://dl.bintray.com/jjhesk/maven" } - } -``` - +# UltimateRecyclerView + +[![Download](https://api.bintray.com/packages/jjhesk/maven/MenuURV/images/download.svg) ](https://bintray.com/jjhesk/maven/MenuURV/_latestVersion)[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)[![Stories in Ready](https://badge.waffle.io/cymcsg/UltimateRecyclerView.svg?label=ready&title=Ready)](http://waffle.io/cymcsg/UltimateRecyclerView) + + +[![Throughput Graph](https://graphs.waffle.io/cymcsg/UltimateRecyclerView/throughput.svg)](https://waffle.io/cymcsg/UltimateRecyclerView/metrics) + +#### Master branch:[![Build Status](https://travis-ci.org/cymcsg/UltimateRecyclerView.svg?branch=master)](https://travis-ci.org/cymcsg/UltimateRecyclerView) + + +##### Project website:[https://github.com/cymcsg/UltimateRecyclerView](https://github.com/cymcsg/UltimateRecyclerView) + + +### Quick Setup(Basic Usage) + +###### 1.Integration jcenter + +Please follow the latest publishing aar on jcenter. + +follow by the gradle code +```gradle +dependencies{ + compile 'com.hkm.ui:ultimaterecyclerview:0.9.10' +} +``` + +###### 2.Usage: + +``` xml + +``` + + +Remote server: dont forget to declare the repos location +``` +repositories { + jcenter() + maven { url "http://dl.bintray.com/jjhesk/maven" } + } +``` + ### Version Log -* ***v0.5.8*** In this version we are now based on support library 23.4.0. We have fixed the load more and disable load more function from early triggers. There is no need to change anything from their implementations. Please read up on the example code if you have any questions from the implementations. - -* ***v0.5.6*** In this version we now have 23.3.0 support library and the min version is supported all the ways to v13. New added feature that allow us to adding have node connector on each item on `linearlayoutmanager`. By extending `TimeLineView` you will now have unlimited builds from the things that connected to each dot. -* ***v0.5.0*** this library will be based on v23.2.1 from now on. if you need have the v23.1.1 please go back to the previous release. detail of this upgrade please see [#342](https://github.com/cymcsg/UltimateRecyclerView/issues/342) -* ***v0.4.9*** This is the last version that will be based on V23.1.1. and this library will not be supported on this version. For further supports please refer to the latest release. -* ***v0.3.11*** There are still version that is based on 22.+ - -### Description - -UltimateRecyclerView is a RecyclerView(advanced and flexible version of ListView) with pulling to refresh, loading more, swiping to dismiss, draging and drop, animations ,sticky header,show or hide toolbar and FAB when scrolling and many other features.You can use it ```just like RecyclerView```. - -Notice that UltimateRecyclerView is a project under development. - -[Your donations is highly appreciated. Thank you!](#donations) - -### Features: - -* Swipe to refresh(using android.support.v4.widget.SwipeRefreshLayout) -* Many kinds of animations -* Swipe to dismiss -* Parallax or normal head view -* Drag and drop items -* Loading more when reach the last item(infinite scrolling) -* Custom views in loading more -* Showing or hiding toolbar and floating button when scrolling -* Scrollbars -* Colorful styles of ``swipe to refresh`` -* Sticky header like instagram -* Support different layout in adapter -* Loading adapter with animation - -### Upcoming features: -* Refer to discussion for headers [#299](https://github.com/cymcsg/UltimateRecyclerView/issues/299) -* Refer to discussion for the loading more [#276](https://github.com/cymcsg/UltimateRecyclerView/issues/276) -* Swipe issue and discussion [#296](https://github.com/cymcsg/UltimateRecyclerView/issues/296) -* Wishlist for [UltiamteRecyclerview 0.4.2](UpcomingChanges.md) -* and more. - -> Notice that it might not be the latest version - -### Demo App / Sample Code: -* Due to rapid updates and developments we have decided to host the demo APK on github -* Check out this link for [latest demonstration for the code](https://github.com/cymcsg/UltimateRecyclerView/releases) -* Video demo for [grid layout demo](https://www.youtube.com/watch?v=iTnIf-N8m1Y) -* or you can check it out already compiled at [Google Play](https://play.google.com/store/apps/details?id=com.marshalchen.ultimaterecyclerview.demo) -* You can clone the project and compile it yourself (it includes a sample), or you can check it out already compiled at Google Play -* You can read more usage in [wiki](https://github.com/cymcsg/UltimateRecyclerView/wiki) and welcome to make your own tutorials in here. - -#### Welcome to fork and PR (pull request) -If you have some good ideas, please tell us. My email is cymcsg # gmail.com.And it is a good idea to put your idea on the issue. If you want to use a rapid development framework for developing apps, you can try [UltimateAndroid Framework](https://github.com/cymcsg/UltimateAndroid). - -### Screenshot - -![grid_layout](http://i.giphy.com/UVKEWEGu64z60.gif) -![grid_layout](http://i.giphy.com/UKxCkkUHVH8Fq.gif) -![admob](http://i.giphy.com/bExwitMhjtUqI.gif) -![expandable](http://i.giphy.com/pLWHKsEdVlsKA.gif) -![node](http://i.giphy.com/Xjf7Y8pZ84OxW.gif) -![multitype](http://i.giphy.com/bvU4HcWvMhejm.gif) -![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview11.gif) -![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview12.gif) -![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview7.gif) -![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/f4794974d8de71ab1d0f0efddda556df7e792df2/ultimaterecyclerview/ultimate_recyclerview3.gif) -![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview9.gif) - - -### Thanks -* Use animators from [recyclerview-animators](https://github.com/wasabeef/recyclerview-animators) -* Deal with different types of LayoutManager from[SuperRecyclerView](https://github.com/Malinskiy/SuperRecyclerView) -* Divider of recyclerview[RecyclerView-FlexibleDivider](https://github.com/yqritc/RecyclerView-FlexibleDivider) -* Parallax header of the recyclerview[android-parallax-recyclerview](https://github.com/kanytu/android-parallax-recyclerview) -* Floating action button [FloatingActionButton](https://github.com/futuresimple/android-floating-action-button) -* Colorful pull to refresh [Ultra Pull To Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh) -* Sticky section headers in RecyclerView [StickHeader](https://github.com/eowise/recyclerview-stickyheaders) -* Swipe[AndroidSwipeLayout](https://github.com/daimajia/AndroidSwipeLayout) -* Thanks [jjhesk](https://github.com/jjhesk) for doing so many work on the project - -If there are someone who I do not mention here,please accept my sincerely appologies and tell me. - -

Donations:

-Donate $9.99: [![$9.99](https://bytebucket.org/marshalchen/images/raw/9c442645492ddc10474416debf511a57a0367397/others/donate.jpg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5GYRYZVNAK2G2) - -Alipay:![donate](https://bytebucket.org/marshalchen/images/raw/9c442645492ddc10474416debf511a57a0367397/others/alipay.png) - -###Bitcoin Donation Accepted -![wallet](http://s32.postimg.org/sdd1oio1t/qrwallet.jpg) - -## License - -``` -Copyright 2015 MarsellChan - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` +* ***v0.9.10*** Update library to support 25.3.1 and removed support from support `Adview`. Minor bug fixed from `setOnLoadListener` +* ***v0.5.8*** In this version we are now based on support library 23.4.0. We have fixed the load more and disable load more function from early triggers. There is no need to change anything from their implementations. Please read up on the example code if you have any questions from the implementations. + +* ***v0.5.6*** In this version we now have 23.3.0 support library and the min version is supported all the ways to v13. New added feature that allow us to adding have node connector on each item on `linearlayoutmanager`. By extending `TimeLineView` you will now have unlimited builds from the things that connected to each dot. +* ***v0.5.0*** this library will be based on v23.2.1 from now on. if you need have the v23.1.1 please go back to the previous release. detail of this upgrade please see [#342](https://github.com/cymcsg/UltimateRecyclerView/issues/342) +* ***v0.4.9*** This is the last version that will be based on V23.1.1. and this library will not be supported on this version. For further supports please refer to the latest release. +* ***v0.3.11*** There are still version that is based on 22.+ + +### Description + +UltimateRecyclerView is a RecyclerView(advanced and flexible version of ListView) with pulling to refresh, loading more, swiping to dismiss, draging and drop, animations ,sticky header,show or hide toolbar and FAB when scrolling and many other features.You can use it ```just like RecyclerView```. + +Notice that UltimateRecyclerView is a project under development. + +[Your donations is highly appreciated. Thank you!](#donations) + +### Features: + +* Swipe to refresh(using android.support.v4.widget.SwipeRefreshLayout) +* Many kinds of animations +* Swipe to dismiss +* Parallax or normal head view +* Drag and drop items +* Loading more when reach the last item(infinite scrolling) +* Custom views in loading more +* Showing or hiding toolbar and floating button when scrolling +* Scrollbars +* Colorful styles of ``swipe to refresh`` +* Sticky header like instagram +* Support different layout in adapter +* Loading adapter with animation + +### Upcoming features: +* Refer to discussion for headers [#299](https://github.com/cymcsg/UltimateRecyclerView/issues/299) +* Refer to discussion for the loading more [#276](https://github.com/cymcsg/UltimateRecyclerView/issues/276) +* Swipe issue and discussion [#296](https://github.com/cymcsg/UltimateRecyclerView/issues/296) +* Wishlist for [UltiamteRecyclerview 0.4.2](UpcomingChanges.md) +* and more. + +> Notice that it might not be the latest version + +### Demo App / Sample Code: +* Due to rapid updates and developments we have decided to host the demo APK on github +* Check out this link for [latest demonstration for the code](https://github.com/cymcsg/UltimateRecyclerView/releases) +* Video demo for [grid layout demo](https://www.youtube.com/watch?v=iTnIf-N8m1Y) +* or you can check it out already compiled at [Google Play](https://play.google.com/store/apps/details?id=com.marshalchen.ultimaterecyclerview.demo) +* You can clone the project and compile it yourself (it includes a sample), or you can check it out already compiled at Google Play +* You can read more usage in [wiki](https://github.com/cymcsg/UltimateRecyclerView/wiki) and welcome to make your own tutorials in here. + +#### Welcome to fork and PR (pull request) +If you have some good ideas, please tell us. My email is cymcsg # gmail.com.And it is a good idea to put your idea on the issue. If you want to use a rapid development framework for developing apps, you can try [UltimateAndroid Framework](https://github.com/cymcsg/UltimateAndroid). + +### Screenshot + +![grid_layout](http://i.giphy.com/UVKEWEGu64z60.gif) +![grid_layout](http://i.giphy.com/UKxCkkUHVH8Fq.gif) +![admob](http://i.giphy.com/bExwitMhjtUqI.gif) +![expandable](http://i.giphy.com/pLWHKsEdVlsKA.gif) +![node](http://i.giphy.com/Xjf7Y8pZ84OxW.gif) +![multitype](http://i.giphy.com/bvU4HcWvMhejm.gif) +![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview11.gif) +![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview12.gif) +![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview7.gif) +![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/f4794974d8de71ab1d0f0efddda556df7e792df2/ultimaterecyclerview/ultimate_recyclerview3.gif) +![ultimate_recyclerview](https://bytebucket.org/marshalchen/images/raw/44beb162121c719ea4094bd7ea1c9f0cd7de4c04/ultimaterecyclerview/ultimate_recyclerview9.gif) + + +### Thanks +* Use animators from [recyclerview-animators](https://github.com/wasabeef/recyclerview-animators) +* Deal with different types of LayoutManager from[SuperRecyclerView](https://github.com/Malinskiy/SuperRecyclerView) +* Divider of recyclerview[RecyclerView-FlexibleDivider](https://github.com/yqritc/RecyclerView-FlexibleDivider) +* Parallax header of the recyclerview[android-parallax-recyclerview](https://github.com/kanytu/android-parallax-recyclerview) +* Floating action button [FloatingActionButton](https://github.com/futuresimple/android-floating-action-button) +* Colorful pull to refresh [Ultra Pull To Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh) +* Sticky section headers in RecyclerView [StickHeader](https://github.com/eowise/recyclerview-stickyheaders) +* Swipe[AndroidSwipeLayout](https://github.com/daimajia/AndroidSwipeLayout) +* Thanks [jjhesk](https://github.com/jjhesk) for doing so many work on the project + +If there are someone who I do not mention here,please accept my sincerely appologies and tell me. + +

Donations:

+Donate $9.99: [![$9.99](https://bytebucket.org/marshalchen/images/raw/9c442645492ddc10474416debf511a57a0367397/others/donate.jpg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5GYRYZVNAK2G2) + +Alipay:![donate](https://bytebucket.org/marshalchen/images/raw/9c442645492ddc10474416debf511a57a0367397/others/alipay.png) + +###Bitcoin Donation Accepted +![wallet](http://s32.postimg.org/sdd1oio1t/qrwallet.jpg) + +## License + +``` +Copyright 2015 MarsellChan + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/UltimateRecyclerView/app/build.gradle b/UltimateRecyclerView/app/build.gradle index aaa8fd37..964f5438 100644 --- a/UltimateRecyclerView/app/build.gradle +++ b/UltimateRecyclerView/app/build.gradle @@ -6,11 +6,11 @@ android { defaultConfig { applicationId "com.marshalchen.ultimaterecyclerview.demo" - minSdkVersion 15 + minSdkVersion 17 targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int - versionCode app_demo_versionCode - versionName app_demo_versionName + versionCode 199 + versionName "1.1" } buildTypes { release { @@ -30,19 +30,12 @@ repositories { } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile supportDependencies.appCompat - compile supportDependencies.annotation - compile supportDependencies.cv - - debugCompile supportDependencies.leakcanary - releaseCompile supportDependencies.leakcanarynoop - testCompile supportDependencies.leakcanarynoop - - // compile 'com.marshalchen.ultimaterecyclerview:library:0.4.0' - compile 'com.google.android.gms:play-services:7.3.0' - debugCompile 'me.drakeet.library:crashwoodpecker:0.9.7' - releaseCompile 'me.drakeet.library:crashwoodpecker-do-nothing:0.9.7' - + compile "com.android.support:appcompat-v7:${SUPPORT_LIBRARY}" + compile "com.android.support:cardview-v7:${SUPPORT_LIBRARY}" + //compile 'com.google.android.gms:play-services:7.3.0' + debugCompile "com.squareup.leakcanary:leakcanary-android:${LEAKCANARY}" + releaseCompile "com.squareup.leakcanary:leakcanary-android-no-op:${LEAKCANARY}" + testCompile "com.squareup.leakcanary:leakcanary-android-no-op:${LEAKCANARY}" compile 'com.hkm.loyalslider:library:1.6.2' compile project(':ultimaterecyclerview') //used in the gridlayout diff --git a/UltimateRecyclerView/app/src/main/AndroidManifest.xml b/UltimateRecyclerView/app/src/main/AndroidManifest.xml index 55e9216f..4129f873 100644 --- a/UltimateRecyclerView/app/src/main/AndroidManifest.xml +++ b/UltimateRecyclerView/app/src/main/AndroidManifest.xml @@ -26,7 +26,7 @@ - + @@ -60,9 +60,15 @@ + + @@ -75,18 +81,21 @@ + - - + <!–This meta-data tag is required to use Google Play Services.–> + android:value="@integer/google_play_services_version" />--> diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentArgs.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentArgs.java new file mode 100644 index 00000000..9ea28b45 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentArgs.java @@ -0,0 +1,139 @@ +package com.marshalchen.ultimaterecyclerview.demo; + + +import android.app.Fragment; + +import java.lang.reflect.Field; + +/** + * Created by hesk on 2016/9/16. + */ + +public class FragmentArgs { + + private Fragment fragment; + private Class fragmentClass; + + public FragmentArgs(Class clazz) { + fragmentClass = clazz; + try { + fragment = (Fragment) fragmentClass.newInstance(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public Class getFragmentClass() { + return fragmentClass; + } + + public FragmentArgs setInt(String field, int value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setInt(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setLong(String field, long value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setLong(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setDouble(String field, double value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setDouble(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setFloat(String field, float value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setFloat(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setByte(String field, byte value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setByte(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setBoolean(String field, boolean value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setBoolean(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setString(String field, String value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.set(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgs setObject(String field, Object value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.set(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public Fragment create() { + return fragment; + } +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentArgsV4.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentArgsV4.java new file mode 100644 index 00000000..640f1b8b --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentArgsV4.java @@ -0,0 +1,138 @@ +package com.marshalchen.ultimaterecyclerview.demo; + +import android.support.v4.app.Fragment; + +import java.lang.reflect.Field; + +/** + * Created by hesk on 2016/9/16. + */ + +public class FragmentArgsV4 { + + private Fragment fragment; + private Class fragmentClass; + + public FragmentArgsV4(Class clazz) { + fragmentClass = clazz; + try { + fragment = (Fragment) fragmentClass.newInstance(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public Class getFragmentClass() { + return fragmentClass; + } + + public FragmentArgsV4 setInt(String field, int value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setInt(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setLong(String field, long value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setLong(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setDouble(String field, double value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setDouble(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setFloat(String field, float value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setFloat(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setByte(String field, byte value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setByte(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setBoolean(String field, boolean value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.setBoolean(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setString(String field, String value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.set(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public FragmentArgsV4 setObject(String field, Object value) { + try { + Field f = fragmentClass.getDeclaredField(field); + f.setAccessible(true); + f.set(fragment, value); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return this; + } + + public Fragment create() { + return fragment; + } +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentTest/FragmentGridHeader.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentTest/FragmentGridHeader.java new file mode 100644 index 00000000..175bbe6e --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentTest/FragmentGridHeader.java @@ -0,0 +1,32 @@ +package com.marshalchen.ultimaterecyclerview.demo.FragmentTest; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; + +import com.marshalchen.ultimaterecyclerview.demo.R; + +/** + * Created by hesk on 2016/9/16. + */ + +public class FragmentGridHeader extends AppCompatActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.framelo); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, new FragmentURV()) + .addToBackStack(null) + .commit(); + + + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + finish(); + } +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentTest/FragmentURV.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentTest/FragmentURV.java new file mode 100644 index 00000000..ab6363da --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/FragmentTest/FragmentURV.java @@ -0,0 +1,108 @@ +package com.marshalchen.ultimaterecyclerview.demo.FragmentTest; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.GridLayoutManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; +import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; +import com.marshalchen.ultimaterecyclerview.demo.R; +import com.marshalchen.ultimaterecyclerview.demo.griddemo.TypedAdapter; +import com.marshalchen.ultimaterecyclerview.demo.modules.JRitem; +import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; +import com.ml93.captainmiaoUtil.ui.floatingactionbutton.JellyBeanFloatingActionButton; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by hesk on 2016/9/15. + */ + +public class FragmentURV extends Fragment { + private UltimateRecyclerView listuv; + private TypedAdapter mGridAdapter; + private GridLayoutManager mGridLayoutManager; + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + listuv = (UltimateRecyclerView) view.findViewById(R.id.example_lv_list); + // mGridAdapter = new TypedAdapter(SampleDataboxset.genJRList(2)); + mGridAdapter = new TypedAdapter(); + mGridLayoutManager = new GridLayoutManager(getActivity(), 2); + mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + if (mGridAdapter.getItemViewType(position) == UltimateViewAdapter.VIEW_TYPES.NORMAL) { + return 1; + } else { + return mGridLayoutManager.getSpanCount(); + } + } + }); + listuv.setLoadMoreView(R.layout.custom_bottom_progressbar); + listuv.setOnLoadMoreListener(new UltimateRecyclerView.OnLoadMoreListener() { + @Override + public void loadMore(int itemsCount, int maxLastVisiblePosition) { + // Log.d(TAG, itemsCount + " :: " + itemsCount); + listuv.postDelayed(new Runnable() { + @Override + public void run() { + mGridAdapter.insert(SampleDataboxset.genJRList(5)); + } + }, 2000); + } + }); + listuv.setHasFixedSize(true); + listuv.setSaveEnabled(true); + listuv.setClipToPadding(true); + listuv.setNormalHeader(setupHeaderView()); + listuv.setLayoutManager(mGridLayoutManager); + listuv.postDelayed(new Runnable() { + @Override + public void run() { + listuv.mSwipeRefreshLayout.setEnabled(true); + listuv.setRefreshing(false); + mGridAdapter.insert(getJRList()); + } + }, 3300); + listuv.setAdapter(mGridAdapter); + listuv.setRefreshing(true); + listuv.setItemAnimator(new DefaultItemAnimator()); + otherbuttons((JellyBeanFloatingActionButton) view.findViewById(R.id.custom_urv_add_floating_button)); + } + + private void otherbuttons(JellyBeanFloatingActionButton button) { + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(getContext(), FragmentGridHeader.class); + getActivity().startActivity(intent); + } + }); + } + + private List getJRList() { + List team = new ArrayList<>(); + //you can make your own test for starting-zero-data + team = SampleDataboxset.genJRList(4); + return team; + } + + private View setupHeaderView() { + return LayoutInflater.from(getContext()).inflate(R.layout.header_love, null, false); + } + + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.swipe_list_view_activity, container, false); + } + +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/LauncherActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/LauncherActivity.java new file mode 100644 index 00000000..a9e514e6 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/LauncherActivity.java @@ -0,0 +1,320 @@ +package com.marshalchen.ultimaterecyclerview.demo; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.view.ActionMode; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.animation.OvershootInterpolator; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Spinner; + +import com.marshalchen.ultimaterecyclerview.ObservableScrollState; +import com.marshalchen.ultimaterecyclerview.ObservableScrollViewCallbacks; +import com.marshalchen.ultimaterecyclerview.URLogs; +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; +import com.marshalchen.ultimaterecyclerview.demo.modules.FastBinding; +import com.marshalchen.ultimaterecyclerview.itemTouchHelper.SimpleItemTouchHelperCallback; +import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration; + +import java.util.ArrayList; +import java.util.List; + +import jp.wasabeef.recyclerview.animators.*; + +/** + * Created by Marshal Chen on 3/8/2016. + */ +public class LauncherActivity extends AppCompatActivity implements ActionMode.Callback { + UltimateRecyclerView ultimateRecyclerView; + SimpleAdapter simpleRecyclerViewAdapter = null; + LinearLayoutManager linearLayoutManager; + int moreNum = 2; + private ActionMode actionMode; + + Toolbar toolbar; + boolean isDrag = true; + + private ItemTouchHelper mItemTouchHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_launcher); + + toolbar = (Toolbar) findViewById(R.id.tool_bar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayShowTitleEnabled(false); + + + ultimateRecyclerView = (UltimateRecyclerView) findViewById(R.id.ultimate_recycler_view); + ultimateRecyclerView.setHasFixedSize(false); + final List stringList = new ArrayList<>(); + + stringList.add("111"); + stringList.add("aaa"); + stringList.add("222"); + stringList.add("33"); + stringList.add("44"); + stringList.add("55"); + stringList.add("66"); + stringList.add("11771"); + simpleRecyclerViewAdapter = new SimpleAdapter(stringList); + + linearLayoutManager = new LinearLayoutManager(this); + ultimateRecyclerView.setLayoutManager(linearLayoutManager); + + StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(simpleRecyclerViewAdapter); + ultimateRecyclerView.addItemDecoration(headersDecor); +//// ultimateRecyclerView.setEmptyView(getResources().getIdentifier("empty_view","layout",getPackageName())); +// ultimateRecyclerView.showEmptyView(); + // ultimateRecyclerView.enableLoadmore(); + //simpleRecyclerViewAdapter.setCustomLoadMoreView(LayoutInflater.from(this) + // .inflate(R.layout.custom_bottom_progressbar, null)); + + ultimateRecyclerView.setLoadMoreView(R.layout.custom_bottom_progressbar); + ultimateRecyclerView.setParallaxHeader(getLayoutInflater().inflate(R.layout.parallax_recyclerview_header, ultimateRecyclerView.mRecyclerView, false)); +// // ultimateRecyclerView.setNormalHeader(getLayoutInflater().inflate(R.layout.parallax_recyclerview_header, ultimateRecyclerView.mRecyclerView, false)); + ultimateRecyclerView.setOnParallaxScroll(new UltimateRecyclerView.OnParallaxScroll() { + @Override + public void onParallaxScroll(float percentage, float offset, View parallax) { + Drawable c = toolbar.getBackground(); + c.setAlpha(Math.round(127 + percentage * 128)); + toolbar.setBackgroundDrawable(c); + } + }); + ultimateRecyclerView.setRecylerViewBackgroundColor(Color.parseColor("#ffffff")); + ultimateRecyclerView.setDefaultOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + simpleRecyclerViewAdapter.insert(moreNum++ + " Refresh things", 0); + ultimateRecyclerView.setRefreshing(false); + // ultimateRecyclerView.scrollBy(0, -50); + linearLayoutManager.scrollToPosition(0); +// ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); +// simpleRecyclerViewAdapter.notifyDataSetChanged(); + } + }, 1000); + } + }); + + ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(simpleRecyclerViewAdapter); + mItemTouchHelper = new ItemTouchHelper(callback); + mItemTouchHelper.attachToRecyclerView(ultimateRecyclerView.mRecyclerView); + simpleRecyclerViewAdapter.setOnDragStartListener(new SimpleAdapter.OnStartDragListener() { + @Override + public void onStartDrag(RecyclerView.ViewHolder viewHolder) { + mItemTouchHelper.startDrag(viewHolder); + } + }); + ultimateRecyclerView.reenableLoadmore(); + ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); + + ultimateRecyclerView.setOnLoadMoreListener(new UltimateRecyclerView.OnLoadMoreListener() { + @Override + public void loadMore(int itemsCount, final int maxLastVisiblePosition) { + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + public void run() { + simpleRecyclerViewAdapter.insert("More " + moreNum++, simpleRecyclerViewAdapter.getAdapterItemCount()); + simpleRecyclerViewAdapter.insert("More " + moreNum++, simpleRecyclerViewAdapter.getAdapterItemCount()); + simpleRecyclerViewAdapter.insert("More " + moreNum++, simpleRecyclerViewAdapter.getAdapterItemCount()); + // linearLayoutManager.scrollToPositionWithOffset(maxLastVisiblePosition,-1); + // linearLayoutManager.scrollToPosition(maxLastVisiblePosition); + + } + }, 1000); + } + }); + +// ultimateRecyclerView.setDefaultSwipeToRefreshColorScheme(getResources().getColor(android.R.color.holo_blue_bright), +// getResources().getColor(android.R.color.holo_green_light), +// getResources().getColor(android.R.color.holo_orange_light), +// getResources().getColor(android.R.color.holo_red_light)); + +// ultimateRecyclerView.setScrollViewCallbacks(new ObservableScrollViewCallbacks() { +// @Override +// public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { +// +// } +// +// @Override +// public void onDownMotionEvent() { +// +// } +// +// @Override +// public void onUpOrCancelMotionEvent(ObservableScrollState observableScrollState) { +//// if (observableScrollState == ObservableScrollState.DOWN) { +//// ultimateRecyclerView.showToolbar(toolbar, ultimateRecyclerView, getScreenHeight()); +//// ultimateRecyclerView.showFloatingActionMenu(); +//// } else if (observableScrollState == ObservableScrollState.UP) { +//// ultimateRecyclerView.hideToolbar(toolbar, ultimateRecyclerView, getScreenHeight()); +//// ultimateRecyclerView.hideFloatingActionMenu(); +//// } else if (observableScrollState == ObservableScrollState.STOP) { +//// } +// URLogs.d("onUpOrCancelMotionEvent"); +// if (observableScrollState == ObservableScrollState.UP) { +// ultimateRecyclerView.hideToolbar(toolbar, ultimateRecyclerView, getScreenHeight()); +// ultimateRecyclerView.hideFloatingActionMenu(); +// } else if (observableScrollState == ObservableScrollState.DOWN) { +// ultimateRecyclerView.showToolbar(toolbar, ultimateRecyclerView, getScreenHeight()); +// ultimateRecyclerView.showFloatingActionMenu(); +// } +// } +// }); + + ultimateRecyclerView.showFloatingButtonView(); +// + Spinner spinner = (Spinner) findViewById(R.id.spinner); + ArrayAdapter spinnerAdapter = + new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); + for (Type type : Type.values()) { + spinnerAdapter.add(type.name()); + } + spinner.setAdapter(spinnerAdapter); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + ultimateRecyclerView.setItemAnimator(Type.values()[position].getAnimator()); + ultimateRecyclerView.getItemAnimator().setAddDuration(500); + ultimateRecyclerView.getItemAnimator().setRemoveDuration(500); + } + + @Override public void onNothingSelected(AdapterView parent) { + + } + }); + + + + findViewById(R.id.add).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + simpleRecyclerViewAdapter.insert("newly added item", 1); + } + }); + + findViewById(R.id.del).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + simpleRecyclerViewAdapter.remove(1); + } + }); + +// + } + + private void toggleSelection(int position) { + simpleRecyclerViewAdapter.toggleSelection(position); + actionMode.setTitle("Selected " + "1"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + + } + + public int getScreenHeight() { + return findViewById(android.R.id.content).getHeight(); + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + URLogs.d("actionmode---" + (mode == null)); + mode.getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + // return false; + } + + /** + * Called to refresh an action mode's action menu whenever it is invalidated. + * + * @param mode ActionMode being prepared + * @param menu Menu used to populate action buttons + * @return true if the menu or action mode was updated, false otherwise. + */ + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + // swipeToDismissTouchListener.setEnabled(false); + this.actionMode = mode; + return false; + } + + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + + + @Override + public void onDestroyActionMode(ActionMode mode) { + this.actionMode = null; + } + + + // + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + FastBinding.startactivity(this, item.getItemId()); + return super.onOptionsItemSelected(item); + } + + enum Type { + FadeIn(new FadeInAnimator(new OvershootInterpolator(1f))), + FadeInDown(new FadeInDownAnimator(new OvershootInterpolator(1f))), + FadeInUp(new FadeInUpAnimator(new OvershootInterpolator(1f))), + FadeInLeft(new FadeInLeftAnimator(new OvershootInterpolator(1f))), + FadeInRight(new FadeInRightAnimator(new OvershootInterpolator(1f))), + Landing(new LandingAnimator(new OvershootInterpolator(1f))), + ScaleIn(new ScaleInAnimator(new OvershootInterpolator(1f))), + ScaleInTop(new ScaleInTopAnimator(new OvershootInterpolator(1f))), + ScaleInBottom(new ScaleInBottomAnimator(new OvershootInterpolator(1f))), + ScaleInLeft(new ScaleInLeftAnimator(new OvershootInterpolator(1f))), + ScaleInRight(new ScaleInRightAnimator(new OvershootInterpolator(1f))), + FlipInTopX(new FlipInTopXAnimator(new OvershootInterpolator(1f))), + FlipInBottomX(new FlipInBottomXAnimator(new OvershootInterpolator(1f))), + FlipInLeftY(new FlipInLeftYAnimator(new OvershootInterpolator(1f))), + FlipInRightY(new FlipInRightYAnimator(new OvershootInterpolator(1f))), + SlideInLeft(new SlideInLeftAnimator(new OvershootInterpolator(1f))), + SlideInRight(new SlideInRightAnimator(new OvershootInterpolator(1f))), + SlideInDown(new SlideInDownAnimator(new OvershootInterpolator(1f))), + SlideInUp(new SlideInUpAnimator(new OvershootInterpolator(1f))), + OvershootInRight(new OvershootInRightAnimator(1.0f)), + OvershootInLeft(new OvershootInLeftAnimator(1.0f)); + + private BaseItemAnimator mAnimator; + + Type(BaseItemAnimator animator) { + mAnimator = animator; + } + + public BaseItemAnimator getAnimator() { + return mAnimator; + } + } +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/MainList.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/MainList.java index 1aa62d5a..6a74af0d 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/MainList.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/MainList.java @@ -9,6 +9,7 @@ import android.widget.ArrayAdapter; import android.widget.ListView; +import com.marshalchen.ultimaterecyclerview.demo.FragmentTest.FragmentGridHeader; import com.marshalchen.ultimaterecyclerview.demo.admobdemo.TestAdMobClassicActivity; import com.marshalchen.ultimaterecyclerview.demo.admobdemo.TestAdvancedAdmobActivity; import com.marshalchen.ultimaterecyclerview.demo.dragdemo.DragActivity; @@ -22,6 +23,8 @@ import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.LineNodeActivity; import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.PullToRefreshActivity; import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.SliderHeader; +import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.Stagger2ColumnLoadTest; +import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.StaggerHeaderCol2Test; import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.StaggerLoadMoreActivity; import com.marshalchen.ultimaterecyclerview.demo.loadmoredemo.SwipeListViewExampleActivity; import com.marshalchen.ultimaterecyclerview.demo.multiitemdemo.MultiViewTypesActivity; @@ -55,7 +58,7 @@ protected void onCreate(Bundle savedInstanceState) { } public void initList() { - + data.put("LauncherActivity", LauncherActivity.class); data.put("Debug Grid Test", GridLayoutRVTest.class); data.put("Issue #374, #363 enabled and disable load more off screen", GridTestOnlyOnePage.class); data.put("Debug load more", DebugLoadMoreActivity.class); @@ -67,11 +70,13 @@ public void initList() { data.put("Debug Admob classic", TestAdMobClassicActivity.class); data.put("Debug Admob advanced", TestAdvancedAdmobActivity.class); data.put("Debug Slider Header", SliderHeader.class); - data.put("Debug Stagger Load More", StaggerLoadMoreActivity.class); + data.put("Stagger, Single Add", StaggerLoadMoreActivity.class); + data.put("Stagger, 2 column, Load More", Stagger2ColumnLoadTest.class); + data.put("Stagger, 2 column, Header, Load More", StaggerHeaderCol2Test.class); data.put("Debug Swipe List", SwipeListViewExampleActivity.class); data.put("Debug expandable", TestExpandableRV.class); - data.put("Debug dragging", DragActivity.class); data.put("Debug multi view types", MultiViewTypesActivity.class); + data.put("Fragment Grid Header", FragmentGridHeader.class); } @Override diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/SimpleAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/SimpleAdapter.java new file mode 100644 index 00000000..b9da2833 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/SimpleAdapter.java @@ -0,0 +1,222 @@ +package com.marshalchen.ultimaterecyclerview.demo; + +/** + * Created by Marshal Chen on 3/8/2016. + */ + +import android.graphics.Color; +import android.support.v4.view.MotionEventCompat; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.marshalchen.ultimaterecyclerview.URLogs; +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; +import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; +import com.marshalchen.ultimaterecyclerview.demo.rvComponents.itemCommonBinder; +import com.marshalchen.ultimaterecyclerview.itemTouchHelper.ItemTouchHelperViewHolder; + +import java.security.SecureRandom; +import java.util.List; + + +public class SimpleAdapter extends UltimateViewAdapter { + private List stringList; + + public SimpleAdapter(List stringList) { + this.stringList = stringList; + } + + + @Override + public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { + if (position < getItemCount() && (customHeaderView != null ? position <= stringList.size() : position < stringList.size()) && (customHeaderView != null ? position > 0 : true)) { + + ((ViewHolder) holder).textViewSample.setText(stringList.get(customHeaderView != null ? position - 1 : position)); + // ((ViewHolder) holder).itemView.setActivated(selectedItems.get(position, false)); + if (mDragStartListener != null) { +// ((ViewHolder) holder).imageViewSample.setOnTouchListener(new View.OnTouchListener() { +// @Override +// public boolean onTouch(View v, MotionEvent event) { +// if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { +// mDragStartListener.onStartDrag(holder); +// } +// return false; +// } +// }); + + ((ViewHolder) holder).item_view.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return false; + } + }); + } + } + + } + + @Override + public int getAdapterItemCount() { + return stringList.size(); + } + + + + @Override + public UltimateRecyclerviewViewHolder onCreateViewHolder(ViewGroup parent) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.recycler_view_adapter, parent, false); + ViewHolder vh = new ViewHolder(v); + return vh; + } + + + public void insert(String string, int position) { + insertInternal(stringList, string, position); + } + + public void remove(int position) { + removeInternal(stringList, position); + } + + public void clear() { + clearInternal(stringList); + } + + + public void swapPositions(int from, int to) { + swapPositions(stringList, from, to); + } + + + @Override + public long generateHeaderId(int position) { + // URLogs.d("position--" + position + " " + getItem(position)); + if (getItem(position).length() > 0) + return getItem(position).charAt(0); + else return -1; + } + + @Override + public RecyclerView.ViewHolder onCreateHeaderViewHolder(ViewGroup viewGroup) { + View view = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.stick_header_item, viewGroup, false); + return new RecyclerView.ViewHolder(view) { + }; + } + + @Override + public void onBindHeaderViewHolder(RecyclerView.ViewHolder viewHolder, int position) { + + TextView textView = (TextView) viewHolder.itemView.findViewById(R.id.stick_text); + textView.setText(String.valueOf(getItem(position).charAt(0))); +// viewHolder.itemView.setBackgroundColor(Color.parseColor("#AA70DB93")); + viewHolder.itemView.setBackgroundColor(Color.parseColor("#AAffffff")); + ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.stick_img); + + SecureRandom imgGen = new SecureRandom(); + switch (imgGen.nextInt(3)) { + case 0: + imageView.setImageResource(R.drawable.jr1); + break; + case 1: + imageView.setImageResource(R.drawable.jr2); + break; + case 2: + imageView.setImageResource(R.drawable.jr3); + break; + } + + } + + @Override + public void onItemMove(int fromPosition, int toPosition) { + if (fromPosition > 0 && toPosition > 0) { + swapPositions(fromPosition, toPosition); +// notifyItemMoved(fromPosition, toPosition); + super.onItemMove(fromPosition, toPosition); + } + + } + + @Override + public void onItemDismiss(int position) { + if (position > 0) { + remove(position); + // notifyItemRemoved(position); +// notifyDataSetChanged(); + super.onItemDismiss(position); + } + + } +// +// private int getRandomColor() { +// SecureRandom rgen = new SecureRandom(); +// return Color.HSVToColor(150, new float[]{ +// rgen.nextInt(359), 1, 1 +// }); +// } + + public void setOnDragStartListener(OnStartDragListener dragStartListener) { + mDragStartListener = dragStartListener; + + } + + class ViewHolder extends UltimateRecyclerviewViewHolder { + + TextView textViewSample; + ImageView imageViewSample; + ProgressBar progressBarSample; + View item_view; + + public ViewHolder(View itemView) { + super(itemView); +// itemView.setOnTouchListener(new SwipeDismissTouchListener(itemView, null, new SwipeDismissTouchListener.DismissCallbacks() { +// @Override +// public boolean canDismiss(Object token) { +// Logs.d("can dismiss"); +// return true; +// } +// +// @Override +// public void onDismiss(View view, Object token) { +// // Logs.d("dismiss"); +// remove(getPosition()); +// +// } +// })); + textViewSample = (TextView) itemView.findViewById( + R.id.textview); + imageViewSample = (ImageView) itemView.findViewById(R.id.imageview); + progressBarSample = (ProgressBar) itemView.findViewById(R.id.progressbar); + progressBarSample.setVisibility(View.GONE); + item_view = itemView.findViewById(R.id.itemview); + } + + @Override + public void onItemSelected() { + itemView.setBackgroundColor(Color.LTGRAY); + } + + @Override + public void onItemClear() { + itemView.setBackgroundColor(0); + } + } + + public String getItem(int position) { + if (customHeaderView != null) + position--; + // URLogs.d("position----"+position); + if (position >= 0 && position < stringList.size()) + return stringList.get(position); + else return ""; + } + +} \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdMobClassicActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdMobClassicActivity.java index 2a4ee4ba..fe7ec1c6 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdMobClassicActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdMobClassicActivity.java @@ -13,9 +13,9 @@ import android.view.View; import android.view.ViewGroup; -import com.google.android.gms.ads.AdRequest; +/*import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdSize; -import com.google.android.gms.ads.AdView; +import com.google.android.gms.ads.AdView;*/ import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; import com.marshalchen.ultimaterecyclerview.demo.R; import com.marshalchen.ultimaterecyclerview.demo.modules.FastBinding; @@ -39,7 +39,7 @@ public class TestAdMobClassicActivity extends AppCompatActivity { private boolean admob_test_mode = false; - private AdView createadmob() { + /* private AdView createadmob() { AdView mAdView = new AdView(this); mAdView.setAdSize(AdSize.MEDIUM_RECTANGLE); mAdView.setAdUnitId("ca-app-pub-3940256099942544/6300978111"); @@ -52,7 +52,7 @@ private AdView createadmob() { // Start loading the ad. mAdView.loadAd(adRequestBuilder.build()); return mAdView; - } + }*/ private void enableSwipe() { @@ -144,12 +144,12 @@ protected void onCreate(Bundle savedInstanceState) { /** * working example 2 with multiple called Adviews */ - simpleRecyclerViewAdapter = new ZeroStickyAdvertistmentAdapter(createadmob(), SampleDataboxset.newListFromGen()); + /* simpleRecyclerViewAdapter = new ZeroStickyAdvertistmentAdapter(createadmob(), SampleDataboxset.newListFromGen()); linearLayoutManager = new LinearLayoutManager(this); ultimateRecyclerView.setLayoutManager(linearLayoutManager); ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); ultimateRecyclerView.setItemViewCacheSize(3); - ultimateRecyclerView.setRecylerViewBackgroundColor(Color.parseColor("#f5f5ff")); + ultimateRecyclerView.setRecylerViewBackgroundColor(Color.parseColor("#f5f5ff"));*/ enableEmptyView(); enableRefresh(); enableLoadMore(); diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdvancedAdmobActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdvancedAdmobActivity.java index 980e90f9..1689088d 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdvancedAdmobActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/TestAdvancedAdmobActivity.java @@ -3,34 +3,28 @@ import android.graphics.Color; import android.os.Bundle; import android.os.Handler; -import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.DisplayMetrics; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Spinner; import android.widget.TextView; -import com.google.android.gms.ads.AdListener; +/*import com.google.android.gms.ads.AdListener; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdSize; -import com.google.android.gms.ads.AdView; +import com.google.android.gms.ads.AdView;*/ import com.marshalchen.ultimaterecyclerview.quickAdapter.AdmobAdapter; -import com.marshalchen.ultimaterecyclerview.URLogs; import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; -import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; import com.marshalchen.ultimaterecyclerview.demo.R; import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; import com.marshalchen.ultimaterecyclerview.quickAdapter.BiAdAdapterSwitcher; -import com.marshalchen.ultimaterecyclerview.ui.AdGoogleDisplaySupport; +import com.ml93.captainmiaoUtil.ui.AdGoogleDisplaySupport; import java.util.ArrayList; import java.util.List; @@ -108,7 +102,10 @@ private static int getIdRV() { return R.layout.countable_rv_adp; } - private RelativeLayout createadmob() { + /** + * + * + private RelativeLayout createadmob() { AdSize adSize = AdSize.SMART_BANNER; @@ -144,9 +141,9 @@ private RelativeLayout createadmob() { final int ad_height = AdGoogleDisplaySupport.defaultHeight(displaymetrics); AdGoogleDisplaySupport.panelAdjust(mAdView, (int) (ad_height * ratio)); // get display info - /* G.display_w = displayMetrics.widthPixels; - G.display_h = displayMetrics.heightPixels; - G.scale = Math.max(G.display_w/1280.0f, G.display_h/800.0f);*/ + // G.display_w = displayMetrics.widthPixels; + // G.display_h = displayMetrics.heightPixels; + // G.scale = Math.max(G.display_w/1280.0f, G.display_h/800.0f); mAdView.setAdListener(new AdListener() { @Override public void onAdLoaded() { @@ -162,16 +159,19 @@ public void onAdLoaded() { } + */ + + /** * example 1 implementation of the switch view - */ + private BiAdAdapterSwitcher imple_switch_view(final UltimateRecyclerView rv) { final adap adp1 = new adap(createadmob(), new ArrayList()); final regular adp2 = new regular(new ArrayList()); final BiAdAdapterSwitcher switchable = new BiAdAdapterSwitcher(rv, adp2, adp1); return switchable; } - + */ private Handler osh = new Handler(); @Override @@ -190,7 +190,7 @@ protected void onCreate(Bundle savedInstanceState) { /** * example 2 implementation enhancement of list view - */ + bi_sw = imple_switch_view(ultimateRecyclerView) .onEnableRefresh(100) .EnableAutoDisableLoadMoreByMaxPages() @@ -211,7 +211,7 @@ public void run() { return true; } }); - + */ TextView b = (TextView) findViewById(R.id.del); b.setText("with Ad"); TextView a = (TextView) findViewById(R.id.add); @@ -223,7 +223,7 @@ public void onClick(View v) { * example 2 implementation enhancement of list view * without advertisement configurations */ - bi_sw.init(false); + // bi_sw.init(false); } }); @@ -234,7 +234,7 @@ public void onClick(View v) { * example 2 implementation enhancement of list view * with advertisement configuration */ - bi_sw.init(true); + // bi_sw.init(true); } }); setup_spinner(); diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/ZeroStickyAdvertistmentAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/ZeroStickyAdvertistmentAdapter.java index 65ce1cca..bd727c4c 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/ZeroStickyAdvertistmentAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/admobdemo/ZeroStickyAdvertistmentAdapter.java @@ -2,8 +2,9 @@ import android.support.v7.widget.RecyclerView; import android.view.View; +import android.view.ViewGroup; -import com.google.android.gms.ads.AdView; +//import com.google.android.gms.ads.AdView; import com.marshalchen.ultimaterecyclerview.quickAdapter.AdmobAdapter; import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; import com.marshalchen.ultimaterecyclerview.demo.R; @@ -13,14 +14,14 @@ /** * Created by hesk on 20/5/15. */ -public class ZeroStickyAdvertistmentAdapter extends AdmobAdapter { +public class ZeroStickyAdvertistmentAdapter extends AdmobAdapter { - public ZeroStickyAdvertistmentAdapter(AdView v, List f) { + public ZeroStickyAdvertistmentAdapter(ViewGroup v, List f) { super(v, false, 12, f); } - public ZeroStickyAdvertistmentAdapter(AdView v, int e, List f, AdviewListener listener) { + public ZeroStickyAdvertistmentAdapter(ViewGroup v, int e, List f, AdviewListener listener) { super(v, false, e, f, listener); } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/expandemo/ExpCustomAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/expandemo/ExpCustomAdapter.java index aac5e2c8..804cb1b5 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/expandemo/ExpCustomAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/expandemo/ExpCustomAdapter.java @@ -69,13 +69,5 @@ protected List getChildrenByPath(String path, int depth, int position } - @Override - public RecyclerView.ViewHolder newFooterHolder(View view) { - return new UltimateRecyclerviewViewHolder(view); - } - @Override - public RecyclerView.ViewHolder newHeaderHolder(View view) { - return new UltimateRecyclerviewViewHolder(view); - } } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridJRAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridJRAdapter.java deleted file mode 100644 index bd55c0a9..00000000 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridJRAdapter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.marshalchen.ultimaterecyclerview.demo.griddemo; - -import android.view.View; -import android.view.ViewGroup; - -import com.marshalchen.ultimaterecyclerview.UltimateGridLayoutAdapter; -import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; -import com.marshalchen.ultimaterecyclerview.demo.R; -import com.marshalchen.ultimaterecyclerview.demo.modules.JRitem; -import com.marshalchen.ultimaterecyclerview.demo.rvComponents.itemGridCellBinder; - -import java.util.List; - -/** - * Created by hesk on 3/2/16. - */ -public class GridJRAdapter extends UltimateGridLayoutAdapter { - - public GridJRAdapter(List hand) { - super(hand); - } - - /** - * the layout id for the normal data - * - * @return the ID - */ - @Override - protected int getNormalLayoutResId() { - return itemGridCellBinder.layout; - } - - /** - * this is the Normal View Holder initiation - * - * @param view view - * @return holder - */ - @Override - protected itemGridCellBinder newViewHolder(View view) { - return new itemGridCellBinder(view, true); - } - - - @Override - public long generateHeaderId(int position) { - return 0; - } - - /** - * binding normal view holder - * - * @param holder holder class - * @param data data - * @param position position - */ - @Override - protected void withBindHolder(itemGridCellBinder holder, JRitem data, int position) { - - } - - @Override - protected void bindNormal(itemGridCellBinder b, JRitem jRitem, int position) { - b.textViewSample.setText(jRitem.train_name); - b.imageViewSample.setImageResource(jRitem.photo_id); - } - - - @Override - public UltimateRecyclerviewViewHolder onCreateHeaderViewHolder(ViewGroup parent) { - return new UltimateRecyclerviewViewHolder(parent); - } - - @Override - public itemGridCellBinder newFooterHolder(View view) { - return new itemGridCellBinder(view, false); - } - - @Override - public itemGridCellBinder newHeaderHolder(View view) { - return new itemGridCellBinder(view, false); - } -} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridLayoutRVTest.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridLayoutRVTest.java index 7b2ae7b6..ee04ff69 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridLayoutRVTest.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridLayoutRVTest.java @@ -5,6 +5,7 @@ import android.support.annotation.LayoutRes; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.Toolbar; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.DisplayMetrics; @@ -14,10 +15,11 @@ import android.view.View; import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; +import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; import com.marshalchen.ultimaterecyclerview.demo.R; import com.marshalchen.ultimaterecyclerview.demo.modules.JRitem; import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; -import com.marshalchen.ultimaterecyclerview.grid.BasicGridLayoutManager; + import java.util.ArrayList; import java.util.List; @@ -27,8 +29,8 @@ */ public class GridLayoutRVTest extends AppCompatActivity { protected UltimateRecyclerView listuv; - protected GridJRAdapter mGridAdapter = null; - private BasicGridLayoutManager mGridLayoutManager; + protected TypedAdapter mGridAdapter; + private GridLayoutManager mGridLayoutManager; private int moreNum = 2, columns = 2; private ActionMode actionMode; private Toolbar mToolbar; @@ -49,15 +51,23 @@ protected void onCreate(Bundle savedInstanceState) { setSupportActionBar(mToolbar); getSupportActionBar().setDisplayShowTitleEnabled(true); listuv = (UltimateRecyclerView) findViewById(R.id.ultimate_recycler_view); - mGridAdapter = new GridJRAdapter(getJRList()); - mGridAdapter.setSpanColumns(columns); - mGridLayoutManager = new BasicGridLayoutManager(this, columns, mGridAdapter); + mGridAdapter = new TypedAdapter(); + mGridLayoutManager = new GridLayoutManager(this, 2); + mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + if (mGridAdapter.getItemViewType(position) == UltimateViewAdapter.VIEW_TYPES.NORMAL) { + return 1; + } else { + return mGridLayoutManager.getSpanCount(); + } + } + }); listuv.setLayoutManager(mGridLayoutManager); listuv.setHasFixedSize(true); listuv.setSaveEnabled(true); listuv.setClipToPadding(false); - // mGridAdapter.setCustomLoadMoreView(LayoutInflater.from(this).inflate(R.layout.custom_bottom_progressbar, null)); listuv.setNormalHeader(setupHeaderView()); final Handler f = new Handler(); @@ -74,14 +84,17 @@ public void run() { }, 2000); } }); - - // listuv.enableLoadmore(); - // listuv.disableLoadmore(); listuv.setLoadMoreView(R.layout.custom_bottom_progressbar); - listuv.setAdapter(mGridAdapter); + listuv.postDelayed(new Runnable() { + @Override + public void run() { + listuv.setRefreshing(false); + mGridAdapter.insert(getJRList()); + } + }, 3300); listuv.setItemAnimator(new DefaultItemAnimator()); - + listuv.setAdapter(mGridAdapter); harness_control(); } @@ -92,7 +105,7 @@ protected void afterAdd() { private List getJRList() { List team = new ArrayList<>(); //you can make your own test for starting-zero-data - // team = SampleDataboxset.genJRList(2); + team = SampleDataboxset.genJRList(3); return team; } @@ -108,8 +121,6 @@ private void dimension_columns() { private View setupHeaderView() { View custom_header = LayoutInflater.from(this).inflate(R.layout.header_love, null, false); - - return custom_header; } @@ -120,14 +131,12 @@ public void onClick(View v) { mGridAdapter.insert(SampleDataboxset.genJRList(4)); } }); - findViewById(R.id.del).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mGridAdapter.removeLast(); } }); - findViewById(R.id.delall).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -140,15 +149,12 @@ public void onClick(View v) { mGridAdapter.insertFirst(SampleDataboxset.genJRSingle()); } }); - findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listuv.reenableLoadmore(); } }); - - } } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridStringAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridStringAdapter.java deleted file mode 100644 index d30d84fc..00000000 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/GridStringAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.marshalchen.ultimaterecyclerview.demo.griddemo; - -import android.support.v7.widget.GridLayoutManager; -import android.view.View; -import android.view.ViewGroup; - -import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; -import com.marshalchen.ultimaterecyclerview.UltimateGridLayoutAdapter; -import com.marshalchen.ultimaterecyclerview.demo.R; -import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; -import com.marshalchen.ultimaterecyclerview.demo.rvComponents.itemGridCellBinder; - -import java.util.List; - -/** - * Created by hesk on 24/8/15. - */ -public class GridStringAdapter extends UltimateGridLayoutAdapter { - - public GridStringAdapter(List hand) { - super(hand); - } - - /** - * the layout id for the normal data - * - * @return the ID - */ - @Override - protected int getNormalLayoutResId() { - return R.layout.grid_item; - } - - /** - * this is the Normal View Holder initiation - * - * @param view view - * @return holder - */ - @Override - protected itemGridCellBinder newViewHolder(View view) { - return new itemGridCellBinder(view, true); - } - - - @Override - public itemGridCellBinder newFooterHolder(View view) { - return new itemGridCellBinder(view, false); - } - - @Override - public itemGridCellBinder newHeaderHolder(View view) { - return new itemGridCellBinder(view, false); - } - - - @Override - public long generateHeaderId(int position) { - return 0; - } - - /** - * binding normal view holder - * - * @param holder holder class - * @param data data - * @param position position - */ - @Override - protected void withBindHolder(itemGridCellBinder holder, String data, int position) { - - } - - @Override - public UltimateRecyclerviewViewHolder onCreateHeaderViewHolder(ViewGroup parent) { - return new UltimateRecyclerviewViewHolder(parent); - } - - @Override - protected void bindNormal(itemGridCellBinder b, String s, int position) { - b.textViewSample.setText(s); - b.imageViewSample.setImageResource(SampleDataboxset.getGirlImageRandom()); - } - - - //https://gist.github.com/yqritc/ccca77dc42f2364777e1 - public static class GridSpan extends GridLayoutManager.SpanSizeLookup { - final private int columns; - final private int intervalRow; - final private GridStringAdapter mGridAdapter; - - public GridSpan(int col, int intervalRow, GridStringAdapter mGridAdapter) { - this.columns = col; - this.intervalRow = intervalRow; - this.mGridAdapter = mGridAdapter; - } - - /** - * Returns the number of span occupied by the item at position. - * - * @param position The adapter position of the item - * @return The number of spans occupied by the item at the provided position - */ - @Override - public int getSpanSize(int position) { - if (position == mGridAdapter.getAdapterItemCount()) { - return columns; - } else { - int mIntervalHeader = columns * intervalRow; - int h = position % mIntervalHeader == 0 ? columns : 1; - return h; - } - } - } - -} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/TypedAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/TypedAdapter.java new file mode 100644 index 00000000..198e4748 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/griddemo/TypedAdapter.java @@ -0,0 +1,55 @@ +package com.marshalchen.ultimaterecyclerview.demo.griddemo; + +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.view.View; + +import com.marshalchen.ultimaterecyclerview.demo.modules.JRitem; +import com.marshalchen.ultimaterecyclerview.demo.rvComponents.itemGridCellBinder; +import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +/** + * Created by hesk on 2016/9/16. + */ + +public class TypedAdapter extends easyRegularAdapter { + public TypedAdapter() { + super(); + } + + public TypedAdapter(List list) { + super(list); + } + + public TypedAdapter(JRitem... list) { + super(list); + } + + @Override + protected int getNormalLayoutResId() { + return itemGridCellBinder.layout; + } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) + @Override + public long generateHeaderId(int position) { + return View.generateViewId(); + } + + @Override + protected itemGridCellBinder newViewHolder(View view) { + return new itemGridCellBinder(view, true); + } + + @Override + protected void withBindHolder(itemGridCellBinder holder, JRitem data, int position) { + holder.textViewSample.setText(data.train_name); + holder.imageViewSample.setImageResource(data.photo_id); + } + + +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/BasicFunctions.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/BasicFunctions.java index 68d3158d..c4d2cf06 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/BasicFunctions.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/BasicFunctions.java @@ -3,17 +3,18 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.ActionMode; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; +import android.widget.TextView; import com.marshalchen.ultimaterecyclerview.DragDropTouchListener; import com.marshalchen.ultimaterecyclerview.ItemTouchListenerAdapter; @@ -24,8 +25,11 @@ import com.marshalchen.ultimaterecyclerview.demo.R; import com.marshalchen.ultimaterecyclerview.layoutmanagers.ClassicSpanGridLayoutManager; import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; -import com.marshalchen.ultimaterecyclerview.ui.AnimationType; +import com.ml93.captainmiaoUtil.ui.AnimationType; import com.marshalchen.ultimaterecyclerview.layoutmanagers.ScrollSmoothLineaerLayoutManager; +import com.ml93.captainmiaoUtil.ui.emptyview.emptyViewOnShownListener; + +import org.w3c.dom.Text; /** * Created by hesk on 19/2/16. @@ -35,7 +39,7 @@ public abstract class BasicFunctions extends AppCompatActivity { protected UltimateRecyclerView ultimateRecyclerView; protected void enableParallaxHeader() { - ultimateRecyclerView.setParallaxHeader(getLayoutInflater().inflate(R.layout.parallax_recyclerview_header, ultimateRecyclerView.mRecyclerView, false)); + ultimateRecyclerView.setParallaxHeader(R.layout.parallax_recyclerview_header); ultimateRecyclerView.setOnParallaxScroll(new UltimateRecyclerView.OnParallaxScroll() { @Override public void onParallaxScroll(float percentage, float offset, View parallax) { @@ -50,15 +54,12 @@ protected void enableLoadMore() { // StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(simpleRecyclerViewAdapter); // ultimateRecyclerView.addItemDecoration(headersDecor); ultimateRecyclerView.setLoadMoreView(R.layout.custom_bottom_progressbar); - ultimateRecyclerView.setOnLoadMoreListener(new UltimateRecyclerView.OnLoadMoreListener() { @Override public void loadMore(int itemsCount, final int maxLastVisiblePosition) { status_progress = true; - Handler handler = new Handler(); - handler.postDelayed(new Runnable() { + ultimateRecyclerView.postDelayed(new Runnable() { public void run() { - onLoadmore(); status_progress = false; } @@ -73,17 +74,17 @@ public void run() { protected abstract void onFireRefresh(); protected void enableRefresh() { - ultimateRecyclerView.setDefaultOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - onFireRefresh(); - } - }, 1000); - } - }); +// ultimateRecyclerView.setDefaultOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { +// @Override +// public void onRefresh() { +// new Handler().postDelayed(new Runnable() { +// @Override +// public void run() { +// onFireRefresh(); +// } +// }, 1000); +// } +// }); // ultimateRecyclerView.setDefaultSwipeToRefreshColorScheme(getResources().getColor(android.R.color.holo_blue_bright), // getResources().getColor(android.R.color.holo_green_light), // getResources().getColor(android.R.color.holo_orange_light), @@ -124,10 +125,10 @@ public void onUpOrCancelMotionEvent(ObservableScrollState observableScrollState) URLogs.d("onUpOrCancelMotionEvent"); if (observableScrollState == ObservableScrollState.UP) { ultimateRecyclerView.hideToolbar(toolbar, ultimateRecyclerView, getScreenHeight()); - ultimateRecyclerView.hideFloatingActionMenu(); + // ultimateRecyclerView.hideFloatingActionMenu(); } else if (observableScrollState == ObservableScrollState.DOWN) { ultimateRecyclerView.showToolbar(toolbar, ultimateRecyclerView, getScreenHeight()); - ultimateRecyclerView.showFloatingActionMenu(); + // ultimateRecyclerView.showFloatingActionMenu(); } } }); @@ -136,10 +137,21 @@ public void onUpOrCancelMotionEvent(ObservableScrollState observableScrollState) } protected void enableEmptyViewPolicy() { - // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); - // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER); - // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_SHOW_LOADMORE_ONLY); ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_CLEAR_ALL); + ultimateRecyclerView.setOnBindEmptyView(new emptyViewOnShownListener() { + @Override + public void onEmptyViewShow(View mView) { + Log.d("empty view", "here is what they are doing now"); + TextView tv = (TextView) mView.findViewById(R.id.exp_section_title); + if (tv != null) { + StringBuilder sb = new StringBuilder(); + sb.append("Your pressed at \""); + sb.append(1); + sb.append("\" and that is not found."); + tv.setText(sb.toString()); + } + } + }); } protected void enableSwipe() { @@ -219,7 +231,11 @@ public void onNothingSelected(AdapterView parent) { } - private void bButtons() { + private void applySupportToolbar(Toolbar bar) { + toolbar = bar; + setSupportActionBar(bar); + getSupportActionBar().setDisplayShowTitleEnabled(false); + findViewById(R.id.add).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -233,13 +249,20 @@ public void onClick(View v) { removeButtonTrigger(); } }); - findViewById(R.id.toggle).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { toggleButtonTrigger(); } }); + + final TextView txt = (TextView) findViewById(R.id.other); + ultimateRecyclerView.setUpdateScrollLocation(new UltimateRecyclerView.updateScroll() { + @Override + public void update(int local) { + txt.setText(local + "."); + } + }); } protected void toggleButtonTrigger() { @@ -262,12 +285,9 @@ protected void toggleButtonTrigger() { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_loadmore); - toolbar = (Toolbar) findViewById(R.id.tool_bar); - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayShowTitleEnabled(false); ultimateRecyclerView = (UltimateRecyclerView) findViewById(R.id.ultimate_recycler_view); + applySupportToolbar((Toolbar) findViewById(R.id.tool_bar)); doURV(ultimateRecyclerView); - bButtons(); ArrayAdapter spinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); setupSpinnerSelection((Spinner) findViewById(R.id.spinner), spinnerAdapter); } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugLoadMoreActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugLoadMoreActivity.java index 141b1812..dd7535f1 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugLoadMoreActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugLoadMoreActivity.java @@ -2,12 +2,12 @@ import android.graphics.Color; -import com.marshalchen.ultimaterecyclerview.ui.swipe.SwipeableRecyclerViewTouchListener; +import com.ml93.captainmiaoUtil.ui.swipe.SwipeableRecyclerViewTouchListener; import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; import com.marshalchen.ultimaterecyclerview.demo.R; import com.marshalchen.ultimaterecyclerview.demo.rvComponents.sectionZeroAdapter; import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; -import com.marshalchen.ultimaterecyclerview.ui.swipe.defaultRegularSwipe; +import com.ml93.captainmiaoUtil.ui.swipe.defaultRegularSwipe; import java.util.ArrayList; @@ -28,9 +28,6 @@ protected void enableEmptyViewPolicy() { @Override protected void onLoadmore() { - - // SampleDataboxset.insertMore(simpleRecyclerViewAdapter, 2); - SampleDataboxset.insertMoreWhole(simpleRecyclerViewAdapter, 2); // linearLayoutManager.scrollToPositionWithOffset(maxLastVisiblePosition, -1); @@ -39,11 +36,11 @@ protected void onLoadmore() { /** * this is the example for making the function test for loading more and disable loading more */ - /* if (isEnableAutoLoadMore) { + /* if (isEnableAutoLoadMore) { ultimateRecyclerView.enableLoadmore(); - } else { + } else { ultimateRecyclerView.disableLoadmore(); - }*/ + }*/ } @Override diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugNoHeaderLoadMoreActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugNoHeaderLoadMoreActivity.java index 4184aa8c..a18800b5 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugNoHeaderLoadMoreActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/DebugNoHeaderLoadMoreActivity.java @@ -21,8 +21,6 @@ protected void enableEmptyViewPolicy() { ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER); // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); - - } @Override diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/FinalEmptyViewDisplayActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/FinalEmptyViewDisplayActivity.java index 1bae13ba..3f00bcee 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/FinalEmptyViewDisplayActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/FinalEmptyViewDisplayActivity.java @@ -9,14 +9,14 @@ import com.marshalchen.ultimaterecyclerview.demo.R; import com.marshalchen.ultimaterecyclerview.demo.rvComponents.sectionZeroAdapter; import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; -import com.marshalchen.ultimaterecyclerview.ui.emptyview.emptyViewOnShownListener; +import com.ml93.captainmiaoUtil.ui.emptyview.emptyViewOnShownListener; import java.util.ArrayList; /** * Created by hesk on 25/2/16. */ -public class FinalEmptyViewDisplayActivity extends BasicFunctions implements emptyViewOnShownListener { +public class FinalEmptyViewDisplayActivity extends BasicFunctions { private sectionZeroAdapter simpleRecyclerViewAdapter = null; private Handler time_count = new Handler(); private int time = 0; @@ -45,7 +45,21 @@ public void run() { protected void enableEmptyViewPolicy() { // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER); - ultimateRecyclerView.setEmptyView(R.layout.empty_view_v2, UltimateRecyclerView.EMPTY_CLEAR_ALL, this); + ultimateRecyclerView.setEmptyView(R.layout.empty_view_v2, UltimateRecyclerView.EMPTY_CLEAR_ALL); + ultimateRecyclerView.setOnBindEmptyView(new emptyViewOnShownListener() { + @Override + public void onEmptyViewShow(View mView) { + TextView tv = (TextView) mView.findViewById(R.id.exp_section_title); + if (tv != null) { + StringBuilder sb = new StringBuilder(); + sb.append("Your pressed at \""); + sb.append(time); + sb.append("\" and that is not found."); + tv.setText(sb.toString()); + } + time++; + } + }); } @@ -84,16 +98,4 @@ protected void toggleButtonTrigger() { } - @Override - public void onEmptyViewShow(View mView) { - TextView tv = (TextView) mView.findViewById(R.id.exp_section_title); - if (tv != null) { - StringBuilder sb = new StringBuilder(); - sb.append("Your pressed at \""); - sb.append(time); - sb.append("\" and that is not found."); - tv.setText(sb.toString()); - } - time++; - } } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/PullToRefreshActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/PullToRefreshActivity.java index 61a4e806..5fa591cc 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/PullToRefreshActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/PullToRefreshActivity.java @@ -3,32 +3,42 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.GridLayoutManager; import android.view.ActionMode; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import com.marshalchen.ultimaterecyclerview.CustomUltimateRecyclerview; import com.marshalchen.ultimaterecyclerview.URLogs; import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; +import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; import com.marshalchen.ultimaterecyclerview.demo.R; +import com.marshalchen.ultimaterecyclerview.demo.griddemo.TypedAdapter; +import com.marshalchen.ultimaterecyclerview.demo.modules.JRitem; +import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; import com.marshalchen.ultimaterecyclerview.demo.rvComponents.sectionZeroAdapter; import com.marshalchen.ultimaterecyclerview.demo.modules.FastBinding; -import in.srain.cube.views.ptr.PtrDefaultHandler; -import in.srain.cube.views.ptr.PtrFrameLayout; -import in.srain.cube.views.ptr.PtrHandler; -import in.srain.cube.views.ptr.PtrUIHandler; -import in.srain.cube.views.ptr.header.MaterialHeader; -import in.srain.cube.views.ptr.header.StoreHouseHeader; -import in.srain.cube.views.ptr.indicator.PtrIndicator; +import java.util.ArrayList; +import java.util.List; + +import com.insraincubeptr.PtrDefaultHandler; +import com.insraincubeptr.PtrFrameLayout; +import com.insraincubeptr.PtrHandler; +import com.insraincubeptr.PtrUIHandler; +import com.insraincubeptr.header.MaterialHeader; +import com.insraincubeptr.header.StoreHouseHeader; +import com.insraincubeptr.indicator.PtrIndicator; public class PullToRefreshActivity extends BasicFunctions implements ActionMode.Callback { - private CustomUltimateRecyclerview ultimateRecyclerView; + private UltimateRecyclerView ultimateRecyclerView; private sectionZeroAdapter simpleRecyclerViewAdapter = null; - private View floatingButton = null; + private TypedAdapter mGridAdapter; + private GridLayoutManager mGridLayoutManager; @Override protected void onLoadmore() { @@ -37,9 +47,9 @@ protected void onLoadmore() { @Override protected void onFireRefresh() { - simpleRecyclerViewAdapter.insertLast("Refresh things"); - // ultimateRecyclerView.scrollBy(0, -50); - linearLayoutManager.scrollToPosition(0); + // simpleRecyclerViewAdapter.insertLast("Refresh things"); + // ultimateRecyclerView.scrollBy(0, -50); + // linearLayoutManager.scrollToPosition(0); ultimateRecyclerView.mPtrFrameLayout.refreshComplete(); changeHeaderHandler.sendEmptyMessageDelayed(0, 500); } @@ -54,25 +64,109 @@ protected void removeButtonTrigger() { } + private void setup() { + mGridAdapter = new TypedAdapter(); + mGridLayoutManager = new GridLayoutManager(this, 3); + mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + if (mGridAdapter.getItemViewType(position) == UltimateViewAdapter.VIEW_TYPES.NORMAL) { + return 1; + } else { + return mGridLayoutManager.getSpanCount(); + } + } + }); + ultimateRecyclerView.setLoadMoreView(R.layout.custom_bottom_progressbar); + ultimateRecyclerView.setOnLoadMoreListener(new UltimateRecyclerView.OnLoadMoreListener() { + @Override + public void loadMore(int itemsCount, int maxLastVisiblePosition) { + // Log.d(TAG, itemsCount + " :: " + itemsCount); + ultimateRecyclerView.postDelayed(new Runnable() { + @Override + public void run() { + mGridAdapter.insert(SampleDataboxset.genJRList(5)); + } + }, 2000); + } + }); + ultimateRecyclerView.setHasFixedSize(true); + ultimateRecyclerView.setSaveEnabled(true); + ultimateRecyclerView.setClipToPadding(true); + ultimateRecyclerView.setNormalHeader(setupHeaderView()); + ultimateRecyclerView.setLayoutManager(mGridLayoutManager); + ultimateRecyclerView.setAdapter(mGridAdapter); + ultimateRecyclerView.setRefreshing(true); + ultimateRecyclerView.setItemAnimator(new DefaultItemAnimator()); + + } + + private List getJRList() { + List team = new ArrayList<>(); + //you can make your own test for starting-zero-data + team = SampleDataboxset.genJRList(4); + return team; + } + + private View setupHeaderView() { + return LayoutInflater.from(this).inflate(R.layout.header_love, null, false); + } + @Override protected void onCreate(Bundle savedInstanceState) { - ultimateRecyclerView = (CustomUltimateRecyclerview) findViewById(R.id.custom_ultimate_recycler_view); super.onCreate(savedInstanceState); - ultimateRecyclerView.setCustomSwipeToRefresh(); - // refreshingMaterial(); + setContentView(R.layout.custom_refresh_activity); + ultimateRecyclerView = (UltimateRecyclerView) findViewById(R.id.custom_ultimate_recycler_view); + //refreshingMaterial(); + setup(); refreshingString(); - } void refreshingString() { storeHouseHeader = new StoreHouseHeader(this); - // header.setPadding(0, 15, 0, 0); - - storeHouseHeader.initWithString("XCode Big Air"); - // header.initWithStringArray(R.array.akta); - ultimateRecyclerView.mPtrFrameLayout.removePtrUIHandler(materialHeader); + storeHouseHeader.setPadding(0, 150, 0, 150); + // storeHouseHeader.setPadding(0, LocalDisplay.dp2px(20), 0, LocalDisplay.dp2px(20)); + storeHouseHeader.initWithString("BIG SEXY MAMA"); + //storeHouseHeader.initWithStringArray(R.array.akta); + // ultimateRecyclerView.mPtrFrameLayout.removePtrUIHandler(materialHeader); ultimateRecyclerView.mPtrFrameLayout.setHeaderView(storeHouseHeader); ultimateRecyclerView.mPtrFrameLayout.addPtrUIHandler(storeHouseHeader); + // ultimateRecyclerView.mPtrFrameLayout.autoRefresh(false); + ultimateRecyclerView.setPtrHandler(new PtrHandler() { + @Override + public boolean checkCanDoRefresh(PtrFrameLayout ptrFrameLayout, View view, View view2) { + return PtrDefaultHandler.checkContentCanBePulledDown(ptrFrameLayout, view, view2); + // return true; + } + + @Override + public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) { + ptrFrameLayout.postDelayed(new Runnable() { + @Override + public void run() { + mGridAdapter.insert(getJRList()); + //ultimateRecyclerView.mPtrFrameLayout.refreshComplete(); + // onFireRefresh(); + } + }, 2000); + } + }); + ultimateRecyclerView.mPtrFrameLayout.postDelayed(new Runnable() { + @Override + public void run() { + ultimateRecyclerView.mPtrFrameLayout.autoRefresh(); + } + }, 100); + } +/* + + void refreshingRental() { + rentalsSunHeaderView = new RentalsSunHeaderView(this); + rentalsSunHeaderView.setUp(ultimateRecyclerView.mPtrFrameLayout); + ultimateRecyclerView.mPtrFrameLayout.removePtrUIHandler(materialHeader); + ultimateRecyclerView.mPtrFrameLayout.removePtrUIHandler(storeHouseHeader); + ultimateRecyclerView.mPtrFrameLayout.setHeaderView(rentalsSunHeaderView); + ultimateRecyclerView.mPtrFrameLayout.addPtrUIHandler(rentalsSunHeaderView); ultimateRecyclerView.mPtrFrameLayout.autoRefresh(false); ultimateRecyclerView.mPtrFrameLayout.setPtrHandler(new PtrHandler() { @Override @@ -86,49 +180,20 @@ public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) { ptrFrameLayout.postDelayed(new Runnable() { @Override public void run() { - onFireRefresh(); + linearLayoutManager.scrollToPosition(0); + ultimateRecyclerView.mPtrFrameLayout.refreshComplete(); + changeHeaderHandler.sendEmptyMessageDelayed(3, 500); } - }, 1800); + }, + + 1800); } }); } +*/ - -// void refreshingRental() { -// rentalsSunHeaderView = new RentalsSunHeaderView(this); -// rentalsSunHeaderView.setUp(ultimateRecyclerView.mPtrFrameLayout); -// -// ultimateRecyclerView.mPtrFrameLayout.removePtrUIHandler(materialHeader); -// ultimateRecyclerView.mPtrFrameLayout.removePtrUIHandler(storeHouseHeader); -// ultimateRecyclerView.mPtrFrameLayout.setHeaderView(rentalsSunHeaderView); -// ultimateRecyclerView.mPtrFrameLayout.addPtrUIHandler(rentalsSunHeaderView); -// ultimateRecyclerView.mPtrFrameLayout.autoRefresh(false); -// ultimateRecyclerView.mPtrFrameLayout.setPtrHandler(new PtrHandler() { -// @Override -// public boolean checkCanDoRefresh(PtrFrameLayout ptrFrameLayout, View view, View view2) { -// boolean canbePullDown = PtrDefaultHandler.checkContentCanBePulledDown(ptrFrameLayout, view, view2); -// return canbePullDown; -// } -// -// @Override -// public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) { -// ptrFrameLayout.postDelayed(new Runnable() { -// @Override -// public void run() { -// simpleRecyclerViewAdapter.insert("Refresh things", 0); -// // ultimateRecyclerView.scrollBy(0, -50); -// linearLayoutManager.scrollToPosition(0); -// ultimateRecyclerView.mPtrFrameLayout.refreshComplete(); -// changeHeaderHandler.sendEmptyMessageDelayed(3, 500); -// } -// }, 1800); -// } -// }); -// -// } - - void refreshingMaterial() { + private void refreshingMaterial() { materialHeader = new MaterialHeader(this); int[] colors = getResources().getIntArray(R.array.google_colors); materialHeader.setColorSchemeColors(colors); @@ -151,9 +216,9 @@ public void onRefreshBegin(final PtrFrameLayout frame) { frame.postDelayed(new Runnable() { @Override public void run() { - simpleRecyclerViewAdapter.insertLast("Refresh things"); + // simpleRecyclerViewAdapter.insertLast("Refresh things"); // ultimateRecyclerView.scrollBy(0, -50); - linearLayoutManager.scrollToPosition(0); + // linearLayoutManager.scrollToPosition(0); ultimateRecyclerView.mPtrFrameLayout.refreshComplete(); // changeHeaderHandler.sendEmptyMessageDelayed(2, 500); } @@ -162,7 +227,7 @@ public void run() { }); } - Handler changeHeaderHandler = new Handler() { + final Handler changeHeaderHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -187,8 +252,8 @@ public void handleMessage(Message msg) { } }; private int mLoadTime = 0; - StoreHouseHeader storeHouseHeader; - MaterialHeader materialHeader; + private StoreHouseHeader storeHouseHeader; + private MaterialHeader materialHeader; // RentalsSunHeaderView rentalsSunHeaderView; private void refreshingStringArray() { @@ -205,8 +270,6 @@ private void refreshingStringArray() { // change header after loaded ultimateRecyclerView.mPtrFrameLayout.addPtrUIHandler(new PtrUIHandler() { - - @Override public void onUIReset(PtrFrameLayout frame) { mLoadTime++; @@ -252,12 +315,13 @@ public void onRefreshBegin(final PtrFrameLayout frame) { @Override public void run() { // frame.refreshComplete(); - simpleRecyclerViewAdapter.insertLast("Refresh things"); - // ultimateRecyclerView.scrollBy(0, -50); - linearLayoutManager.scrollToPosition(0); + // simpleRecyclerViewAdapter.insertLast("Refresh things"); + // ultimateRecyclerView.scrollBy(0, -50); + // linearLayoutManager.scrollToPosition(0); ultimateRecyclerView.mPtrFrameLayout.refreshComplete(); - if (mLoadTime % 2 == 0) + if (mLoadTime % 2 == 0) { changeHeaderHandler.sendEmptyMessageDelayed(1, 500); + } } }, 2000); } @@ -272,8 +336,6 @@ private void toggleSelection(int position) { @Override protected void onDestroy() { super.onDestroy(); - - } public int getScreenHeight() { @@ -334,48 +396,5 @@ public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } -/* - - enum Type { - FadeIn("FadeIn", new FadeInAnimator()), - FadeInDown("FadeInDown", new FadeInDownAnimator()), - FadeInUp("FadeInUp", new FadeInUpAnimator()), - FadeInLeft("FadeInLeft", new FadeInLeftAnimator()), - FadeInRight("FadeInRight", new FadeInRightAnimator()), - Landing("Landing", new LandingAnimator()), - ScaleIn("ScaleIn", new ScaleInAnimator()), - ScaleInTop("ScaleInTop", new ScaleInTopAnimator()), - ScaleInBottom("ScaleInBottom", new ScaleInBottomAnimator()), - ScaleInLeft("ScaleInLeft", new ScaleInLeftAnimator()), - ScaleInRight("ScaleInRight", new ScaleInRightAnimator()), - FlipInTopX("FlipInTopX", new FlipInTopXAnimator()), - FlipInBottomX("FlipInBottomX", new FlipInBottomXAnimator()), - FlipInLeftY("FlipInLeftY", new FlipInLeftYAnimator()), - FlipInRightY("FlipInRightY", new FlipInRightYAnimator()), - SlideInLeft("SlideInLeft", new SlideInLeftAnimator()), - SlideInRight("SlideInRight", new SlideInRightAnimator()), - SlideInDown("SlideInDown", new SlideInDownAnimator()), - SlideInUp("SlideInUp", new SlideInUpAnimator()), - OvershootInRight("OvershootInRight", new OvershootInRightAnimator()), - OvershootInLeft("OvershootInLeft", new OvershootInLeftAnimator()); - - private String mTitle; - private BaseItemAnimator mAnimator; - - Type(String title, BaseItemAnimator animator) { - mTitle = title; - mAnimator = animator; - } - - public BaseItemAnimator getAnimator() { - return mAnimator; - } - - public String getTitle() { - return mTitle; - } - } -*/ - } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/Stagger2ColumnLoadTest.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/Stagger2ColumnLoadTest.java new file mode 100644 index 00000000..a09e6ce6 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/Stagger2ColumnLoadTest.java @@ -0,0 +1,84 @@ +package com.marshalchen.ultimaterecyclerview.demo.loadmoredemo; + +import android.graphics.Color; +import android.support.v7.widget.StaggeredGridLayoutManager; + +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; +import com.marshalchen.ultimaterecyclerview.demo.R; +import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; +import com.marshalchen.ultimaterecyclerview.demo.rvComponents.staggerAdapter; + +import java.util.ArrayList; + +/** + * Created by hesk on 2016/9/17. + */ + +public class Stagger2ColumnLoadTest extends BasicFunctions { + staggerAdapter simpleRecyclerViewAdapter = null; + + @Override + protected void onLoadmore() { + SampleDataboxset.insertMoreWhole(simpleRecyclerViewAdapter, 3); + } + + @Override + protected void enableEmptyViewPolicy() { + // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); + // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER); + ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); + } + + @Override + protected void onFireRefresh() { + // simpleRecyclerViewAdapter.insertLast(moreNum++ + " Refresh things"); + ultimateRecyclerView.setRefreshing(false); + // ultimateRecyclerView.scrollBy(0, -50); + linearLayoutManager.scrollToPosition(0); + //ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); + //simpleRecyclerViewAdapter.notifyDataSetChanged(); + simpleRecyclerViewAdapter.removeAll(); + ultimateRecyclerView.disableLoadmore(); + ultimateRecyclerView.showEmptyView(); + } + + @Override + protected void doURV(UltimateRecyclerView urv) { + ultimateRecyclerView.setHasFixedSize(false); + simpleRecyclerViewAdapter = new staggerAdapter(new ArrayList()); + //configLinearLayoutManager(ultimateRecyclerView); + + StaggeredGridLayoutManager gaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); + ultimateRecyclerView.setLayoutManager(gaggeredGridLayoutManager); + // enableParallaxHeader(); + enableEmptyViewPolicy(); + enableLoadMore(); + ultimateRecyclerView.setRecylerViewBackgroundColor(Color.parseColor("#ff4fcccf")); + enableRefresh(); + // enableScrollControl(); + // enableSwipe(); + // enableItemClick(); + ultimateRecyclerView.setItemViewCacheSize(simpleRecyclerViewAdapter.getAdditionalItems()); + ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); + ultimateRecyclerView.postDelayed(new Runnable() { + @Override + public void run() { + simpleRecyclerViewAdapter.insert(SampleDataboxset.newListFromGen(4)); + } + }, 3000); + ultimateRecyclerView.setRefreshing(true); + } + + @Override + protected void addButtonTrigger() { + simpleRecyclerViewAdapter.insertLast("++ New Item"); + ultimateRecyclerView.reenableLoadmore(); + } + + @Override + protected void removeButtonTrigger() { + simpleRecyclerViewAdapter.removeLast(); + } + + +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/StaggerHeaderCol2Test.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/StaggerHeaderCol2Test.java new file mode 100644 index 00000000..709aaeb8 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/loadmoredemo/StaggerHeaderCol2Test.java @@ -0,0 +1,87 @@ +package com.marshalchen.ultimaterecyclerview.demo.loadmoredemo; + +import android.graphics.Color; +import android.support.v7.widget.StaggeredGridLayoutManager; + +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; +import com.marshalchen.ultimaterecyclerview.demo.R; +import com.marshalchen.ultimaterecyclerview.demo.modules.SampleDataboxset; +import com.marshalchen.ultimaterecyclerview.demo.rvComponents.staggerAdapter; +import com.ml93.captainmiaoUtil.ItemDecoration.ParallaxHeaderDecoration; + +import java.util.ArrayList; + +/** + * Created by hesk on 2016/9/17. + */ + +public class StaggerHeaderCol2Test extends BasicFunctions { + staggerAdapter simpleRecyclerViewAdapter = null; + + @Override + protected void onLoadmore() { + SampleDataboxset.insertMoreWhole(simpleRecyclerViewAdapter, 3); + } + + @Override + protected void enableEmptyViewPolicy() { + // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); + // ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER); + ultimateRecyclerView.setEmptyView(R.layout.empty_view, UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE); + } + + @Override + protected void onFireRefresh() { + // simpleRecyclerViewAdapter.insertLast(moreNum++ + " Refresh things"); + ultimateRecyclerView.setRefreshing(false); + // ultimateRecyclerView.scrollBy(0, -50); + linearLayoutManager.scrollToPosition(0); + //ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); + //simpleRecyclerViewAdapter.notifyDataSetChanged(); + simpleRecyclerViewAdapter.removeAll(); + ultimateRecyclerView.disableLoadmore(); + ultimateRecyclerView.showEmptyView(); + } + + @Override + protected void doURV(UltimateRecyclerView urv) { + ultimateRecyclerView.setHasFixedSize(false); + simpleRecyclerViewAdapter = new staggerAdapter(new ArrayList()); + //configLinearLayoutManager(ultimateRecyclerView); + + StaggeredGridLayoutManager gaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); + ultimateRecyclerView.setLayoutManager(gaggeredGridLayoutManager); + // enableParallaxHeader(); + enableEmptyViewPolicy(); + enableLoadMore(); + ultimateRecyclerView.setRecylerViewBackgroundColor(Color.parseColor("#ff4fcccf")); + enableRefresh(); + // enableScrollControl(); + // enableSwipe(); + // enableItemClick(); + ultimateRecyclerView.setParallaxHeader(R.layout.parallax_recyclerview_header); + //ultimateRecyclerView.addItemDecoration(new ParallaxHeaderDecoration(this, R.drawable.jr6)); + ultimateRecyclerView.setItemViewCacheSize(simpleRecyclerViewAdapter.getAdditionalItems()); + ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); + ultimateRecyclerView.postDelayed(new Runnable() { + @Override + public void run() { + simpleRecyclerViewAdapter.insert(SampleDataboxset.newListFromGen(4)); + } + }, 3000); + ultimateRecyclerView.setRefreshing(true); + } + + @Override + protected void addButtonTrigger() { + simpleRecyclerViewAdapter.insertLast("++ New Item"); + ultimateRecyclerView.reenableLoadmore(); + } + + @Override + protected void removeButtonTrigger() { + simpleRecyclerViewAdapter.removeLast(); + } + + +} diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/modules/MainWatcher.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/modules/MainWatcher.java index 94602ccb..b36b2338 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/modules/MainWatcher.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/modules/MainWatcher.java @@ -3,7 +3,6 @@ import android.app.Application; import android.content.pm.ApplicationInfo; -import me.drakeet.library.CrashWoodpecker; /** * Created by hesk on 2/10/15. diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesActivity.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesActivity.java index 6dd4a495..c8c618a4 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesActivity.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesActivity.java @@ -9,12 +9,11 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.Toolbar; -import android.view.LayoutInflater; import android.view.View; import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; import com.marshalchen.ultimaterecyclerview.demo.R; -import com.marshalchen.ultimaterecyclerview.ui.divideritemdecoration.HorizontalDividerItemDecoration; +import com.ml93.captainmiaoUtil.ItemDecoration.HorizontalDividerItemDecoration; import java.util.ArrayList; import java.util.List; @@ -54,13 +53,11 @@ protected void onCreate(Bundle savedInstanceState) { simpleRecyclerViewAdapter = new MultiViewTypesRecyclerViewAdapter(stringList); - simpleRecyclerViewAdapter.setCustomLoadMoreView( - LayoutInflater.from(this).inflate(R.layout.custom_bottom_progressbar, null)); - // stringList.add("66"); // stringList.add("11771"); linearLayoutManager = new LinearLayoutManager(this); ultimateRecyclerView.setLayoutManager(linearLayoutManager); + ultimateRecyclerView.setLoadMoreView(R.layout.custom_bottom_progressbar); // ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); ultimateRecyclerView.setAdapter(simpleRecyclerViewAdapter); ultimateRecyclerView.setDefaultOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesRecyclerViewAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesRecyclerViewAdapter.java index e299026f..12a61066 100755 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesRecyclerViewAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/multiitemdemo/MultiViewTypesRecyclerViewAdapter.java @@ -59,22 +59,6 @@ public void remove(int position) { } - /** - * requirement: FOOTER, HEADER. it does not bind and need to do that in the header binding - * - * @param view with no binding view of nothing - * @return v - */ - @Override - public RecyclerView.ViewHolder newFooterHolder(View view) { - return new UltimateRecyclerviewViewHolder<>(view); - } - - @Override - public RecyclerView.ViewHolder newHeaderHolder(View view) { - return new UltimateRecyclerviewViewHolder<>(view); - } - @Override public UltimateRecyclerviewViewHolder onCreateViewHolder(ViewGroup parent) { View v = LayoutInflater.from(parent.getContext()) diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SimpleAnimationAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SimpleAnimationAdapter.java index 011d6a5b..5c050e9f 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SimpleAnimationAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SimpleAnimationAdapter.java @@ -60,22 +60,6 @@ public int getAdapterItemCount() { return stringList.size(); } - /** - * requirement: FOOTER, HEADER. it does not bind and need to do that in the header binding - * - * @param view with no binding view of nothing - * @return v - */ - @Override - public RecyclerView.ViewHolder newFooterHolder(View view) { - return new ViewHolder(view, false); - } - - @Override - public RecyclerView.ViewHolder newHeaderHolder(View view) { - return new ViewHolder(view, false); - } - @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) { View v = LayoutInflater.from(parent.getContext()) diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SwipeAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SwipeAdapter.java index d57eb8cb..4cf62626 100755 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SwipeAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/SwipeAdapter.java @@ -73,16 +73,6 @@ public void onClick(View v) { return viewHolder; } - @Override - public SVHolder newFooterHolder(View view) { - return new SVHolder(view, false); - } - - @Override - public SVHolder newHeaderHolder(View view) { - return new SVHolder(view, false); - } - @Override public long generateHeaderId(int position) { return 0; diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/TimeLineAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/TimeLineAdapter.java index c72d3beb..f1c966fd 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/TimeLineAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/TimeLineAdapter.java @@ -4,7 +4,7 @@ import com.marshalchen.ultimaterecyclerview.demo.modules.TimeLineModel; import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; -import com.marshalchen.ultimaterecyclerview.ui.timelineview.TimelineView; +import com.ml93.captainmiaoUtil.ui.timelineview.TimelineView; import java.util.List; diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/itemNode.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/itemNode.java index dcd079b0..a40d2446 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/itemNode.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/itemNode.java @@ -5,7 +5,7 @@ import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; import com.marshalchen.ultimaterecyclerview.demo.R; -import com.marshalchen.ultimaterecyclerview.ui.timelineview.TimelineView; +import com.ml93.captainmiaoUtil.ui.timelineview.TimelineView; /** * Created by zJJ on 4/27/2016. diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionCommonAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionCommonAdapter.java index 0f91a389..663b6339 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionCommonAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionCommonAdapter.java @@ -160,13 +160,4 @@ public void onBindHeaderViewHolder(RecyclerView.ViewHolder viewHolder, int posit } - @Override - public itemCommonBinder newFooterHolder(View view) { - return new itemCommonBinder(view, false); - } - - @Override - public itemCommonBinder newHeaderHolder(View view) { - return new itemCommonBinder(view, false); - } } \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionZeroAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionZeroAdapter.java index 485d2272..adffccbd 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionZeroAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/sectionZeroAdapter.java @@ -35,15 +35,6 @@ protected itemCommonBinder newViewHolder(View view) { - @Override - public itemCommonBinder newFooterHolder(View view) { - return new itemCommonBinder(view, false); - } - - @Override - public itemCommonBinder newHeaderHolder(View view) { - return new itemCommonBinder(view, false); - } /* @Override @@ -115,7 +106,6 @@ protected void withBindHolder(itemCommonBinder holder, String data, int position @Override public void onItemMove(int fromPosition, int toPosition) { swapPositions(fromPosition, toPosition); -// notifyItemMoved(fromPosition, toPosition); super.onItemMove(fromPosition, toPosition); } diff --git a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/staggerAdapter.java b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/staggerAdapter.java index b4e1a331..874cdde6 100644 --- a/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/staggerAdapter.java +++ b/UltimateRecyclerView/app/src/main/java/com/marshalchen/ultimaterecyclerview/demo/rvComponents/staggerAdapter.java @@ -31,15 +31,7 @@ protected itemStaggerCommonBinder newViewHolder(View view) { return new itemStaggerCommonBinder(view, VIEW_TYPES.NORMAL); } - @Override - public itemStaggerCommonBinder newFooterHolder(View view) { - return new itemStaggerCommonBinder(view, VIEW_TYPES.FOOTER); - } - @Override - public itemStaggerCommonBinder newHeaderHolder(View view) { - return new itemStaggerCommonBinder(view, VIEW_TYPES.HEADER); - } @Override protected void withBindHolder(itemStaggerCommonBinder holder, String data, int position) { diff --git a/UltimateRecyclerView/app/src/main/res/layout/activity_drag.xml b/UltimateRecyclerView/app/src/main/res/layout/activity_drag.xml index 6c788d0d..db74bb59 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/activity_drag.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/activity_drag.xml @@ -47,8 +47,8 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/res/layout/activity_loadmore.xml b/UltimateRecyclerView/app/src/main/res/layout/activity_loadmore.xml index 5ab79acd..374a5b79 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/activity_loadmore.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/activity_loadmore.xml @@ -22,8 +22,8 @@ + tools:context=".loadmoredemo.PullToRefreshActivity"> @@ -44,23 +45,25 @@ - + app:recyclerviewPadding="2dp" + app:recyclerviewRefreshType="ptr" /> + + + fab:urv_fab_colorNormal="#aaffff" /> \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/res/layout/empty_view.xml b/UltimateRecyclerView/app/src/main/res/layout/empty_view.xml index 9d4a2824..f4381609 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/empty_view.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/empty_view.xml @@ -4,6 +4,7 @@ android:layout_height="match_parent"> + android:layout_width="250dp" + android:layout_height="wrap_content"> diff --git a/UltimateRecyclerView/app/src/main/res/layout/exp_parent.xml b/UltimateRecyclerView/app/src/main/res/layout/exp_parent.xml index 57f03760..6f47bf16 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/exp_parent.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/exp_parent.xml @@ -2,7 +2,7 @@ - - - - + diff --git a/UltimateRecyclerView/app/src/main/res/layout/floatingbutton_grid_layout.xml b/UltimateRecyclerView/app/src/main/res/layout/floatingbutton_grid_layout.xml index c1282e1a..17334346 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/floatingbutton_grid_layout.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/floatingbutton_grid_layout.xml @@ -75,15 +75,15 @@ - + diff --git a/UltimateRecyclerView/app/src/main/res/layout/header_love.xml b/UltimateRecyclerView/app/src/main/res/layout/header_love.xml index f12ba47a..8f026b60 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/header_love.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/header_love.xml @@ -7,6 +7,6 @@ + android:scaleType="centerCrop" + android:src="@drawable/jr1" /> \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/res/layout/item_node.xml b/UltimateRecyclerView/app/src/main/res/layout/item_node.xml index 4345d590..8ec94b28 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/item_node.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/item_node.xml @@ -5,7 +5,7 @@ android:layout_height="wrap_content" android:orientation="horizontal"> - + android:layout_width="match_parent" + android:layout_height="match_parent"> @@ -45,7 +45,7 @@ @@ -59,7 +59,7 @@ diff --git a/UltimateRecyclerView/app/src/main/res/layout/parallax_recyclerview_header.xml b/UltimateRecyclerView/app/src/main/res/layout/parallax_recyclerview_header.xml index 0fcc182e..abfed8c5 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/parallax_recyclerview_header.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/parallax_recyclerview_header.xml @@ -1,15 +1,16 @@ + android:layout_height="180dp"> + app:srcCompat="@drawable/jr6" /> \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/res/layout/recycler_view_adapter.xml b/UltimateRecyclerView/app/src/main/res/layout/recycler_view_adapter.xml new file mode 100644 index 00000000..04573a09 --- /dev/null +++ b/UltimateRecyclerView/app/src/main/res/layout/recycler_view_adapter.xml @@ -0,0 +1,30 @@ + + + + + + + + + \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/res/layout/rv_item_linear.xml b/UltimateRecyclerView/app/src/main/res/layout/rv_item_linear.xml index 78130fca..19242c72 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/rv_item_linear.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/rv_item_linear.xml @@ -15,7 +15,7 @@ - + android:background="#FFFFFF"> + + android:layout_width="match_parent" + android:layout_height="match_parent" + app:recyclerviewDefaultSwipeColor="@array/google_colors" + app:recyclerviewEmptyView="@layout/empty_view" + app:recyclerviewRefreshType="swiperefresh" + app:recyclerviewScrollbars="vertical" /> + + + - \ No newline at end of file + \ No newline at end of file diff --git a/UltimateRecyclerView/app/src/main/res/layout/toolbar_loadmore.xml b/UltimateRecyclerView/app/src/main/res/layout/toolbar_loadmore.xml index 2e924ab6..94b067cd 100644 --- a/UltimateRecyclerView/app/src/main/res/layout/toolbar_loadmore.xml +++ b/UltimateRecyclerView/app/src/main/res/layout/toolbar_loadmore.xml @@ -2,11 +2,13 @@ + + + \ No newline at end of file diff --git a/UltimateRecyclerView/build.gradle b/UltimateRecyclerView/build.gradle index 33e3b3bb..b8e10784 100644 --- a/UltimateRecyclerView/build.gradle +++ b/UltimateRecyclerView/build.gradle @@ -5,10 +5,8 @@ buildscript { jcenter() } dependencies { - // - @ https://oss.sonatype.org/ - classpath 'com.android.tools.build:gradle:2.1.0' - // - tutorials @https://github.com/novoda/bintray-release - classpath 'com.novoda:bintray-release:0.3.4' + classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.novoda:bintray-release:0.4.0' } } @@ -27,35 +25,8 @@ ext { //Library configurations PUBLISH_GROUP_ID = 'com.marshalchen.ultimaterecyclerview' PUBLISH_ARTIFACT_ID = 'library' - - ARTIFACT_ID = 'urvlib' - VERSION_CODE = 23 //your version - //Application - app_demo_versionCode = 23 - app_demo_versionName = '1.4.0' - //Support and Build tools version - ftKit = '0.4.1' - - //Support Libraries dependencies - supportDependencies = [ - percent : "com.android.support:percent:${SUPPORT_LIBRARY}", - annotation : "com.android.support:support-annotations:${SUPPORT_LIBRARY}", - support : "com.android.support:support-v13:${SUPPORT_LIBRARY}", - appCompat : "com.android.support:appcompat-v7:${SUPPORT_LIBRARY}", - rv : "com.android.support:recyclerview-v7:${SUPPORT_LIBRARY}", - cv : "com.android.support:cardview-v7:${SUPPORT_LIBRARY}", - kitCore : "com.52inc:52Kit-core:${ftKit}", - - - - leakcanary : "com.squareup.leakcanary:leakcanary-android:${LEAKCANARY}", - leakcanarynoop: "com.squareup.leakcanary:leakcanary-android-no-op:${LEAKCANARY}", - - - ] - IS_UPLOADING = project.getGradle().startParameter.taskNames.any { it.contains('bintrayUpload') } } diff --git a/UltimateRecyclerView/gradle.properties b/UltimateRecyclerView/gradle.properties index 55e65dd7..263e82c6 100644 --- a/UltimateRecyclerView/gradle.properties +++ b/UltimateRecyclerView/gradle.properties @@ -1,9 +1,25 @@ -SUPPORT_LIBRARY=23.4.0 -ANDROID_BUILD_MIN_SDK_VERSION=13 -ANDROID_BUILD_TARGET_SDK_VERSION=23 -ANDROID_BUILD_SDK_VERSION=23 -ANDROID_BUILD_TOOLS_VERSION=23.0.3 - +SUPPORT_LIBRARY=25.3.1 +ANDROID_BUILD_MIN_SDK_VERSION=17 +ANDROID_BUILD_TARGET_SDK_VERSION=25 +ANDROID_BUILD_SDK_VERSION=25 +ANDROID_BUILD_TOOLS_VERSION=25.0.2 #version check on @link https://github.com/square/leakcanary -LEAKCANARY=1.4-beta2 +LEAKCANARY=1.5 +POM_NAME=ultimaterecyclerview +POM_ARTIFACT_ID=library +POM_PACKAGING=aar + +GROUP=com.marshalchen.ultimaterecyclerview +POM_DESCRIPTION=A RecyclerView(advanced and flexible version of ListView) with refreshing,loading more,animation and many other features. +POM_URL=https://github.com/cymcsg/UltimateRecyclerView +POM_SCM_URL=https://github.com/cymcsg/UltimateRecyclerView +POM_SCM_CONNECTION=https://github.com/cymcsg/UltimateRecyclerView.git +POM_SCM_DEV_CONNECTION=https://github.com/cymcsg/UltimateRecyclerView.git +POM_LICENCE_NAME=The Apache Software License, Version 2.0 +POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt +POM_LICENCE_DIST=repo +POM_DEVELOPER_ID=cymcsg +POM_DEVELOPER_NAME=marshalchen +SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots +RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2 diff --git a/UltimateRecyclerView/gradle/wrapper/gradle-wrapper.properties b/UltimateRecyclerView/gradle/wrapper/gradle-wrapper.properties index 5ede2e19..72c9aac2 100644 --- a/UltimateRecyclerView/gradle/wrapper/gradle-wrapper.properties +++ b/UltimateRecyclerView/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Apr 12 14:36:52 HKT 2016 +#Fri Apr 07 14:16:52 CST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/UltimateRecyclerView/ultimaterecyclerview/bintray_3_4.gradle b/UltimateRecyclerView/ultimaterecyclerview/bintray_3_4.gradle index ef8157d9..b2fd2638 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/bintray_3_4.gradle +++ b/UltimateRecyclerView/ultimaterecyclerview/bintray_3_4.gradle @@ -8,7 +8,7 @@ publish { version = project.VERSION_NAME uploadName = 'MenuURV' description = "The super recycler for the menu" - website = 'https://github.com/jjhesk/BringItBackAdvanceSlidingMenu' + website = 'https://github.com/cymcsg/UltimateRecyclerView' autoPublish = true dryRun = false issueTracker = "${website}/issues" @@ -16,7 +16,6 @@ publish { bintrayUser = userOrg } - if (hasProperty('APIBKI')) { publish.bintrayKey = property('APIBKI') } else { diff --git a/UltimateRecyclerView/ultimaterecyclerview/build.gradle b/UltimateRecyclerView/ultimaterecyclerview/build.gradle index a822aaae..76c6c9a6 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/build.gradle +++ b/UltimateRecyclerView/ultimaterecyclerview/build.gradle @@ -1,12 +1,49 @@ apply plugin: 'com.android.library' +def versionMajor = 0; +def versionMinor = 9; +def versionPatch = 10; +def versionBuild = 88; +def version_code = 89; +def value = 2; +def val_minor = 0; +def final_version_name = "0.9.0" android { + def versionPropsFile = file('version.properties') + + if (versionPropsFile.canRead()) { + def Properties versionProps = new Properties() + + versionProps.load(new FileInputStream(versionPropsFile)) + + def runTasks = gradle.startParameter.taskNames + + if (runTasks.contains('assemblePlay_store')) { + val_minor = 1; + } + + /* versionMinor = Integer.parseInt(versionProps['VERSION_MINOR']) + val_minor + versionPatch = Integer.parseInt(versionProps['VERSION_PATCH']) + value + versionBuild = Integer.parseInt(versionProps['VERSION_BUILD']) + 1 + version_code = Integer.parseInt(versionProps['VERSION_CODE']) + value + + versionProps['VERSION_PATCH'] = versionPatch.toString() + versionProps['VERSION_BUILD'] = versionBuild.toString() + versionProps['VERSION_CODE'] = version_code.toString() + versionProps['VERSION_MINOR'] = versionMinor.toString() + versionProps['VERSION_NAME'] = "${versionMajor}.${versionMinor}.${versionPatch}"*/ + + versionProps.store(versionPropsFile.newWriter(), null) + final_version_name = "${versionMajor}.${versionMinor}.${versionPatch}" + } + + compileSdkVersion project.ANDROID_BUILD_SDK_VERSION as int buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION defaultConfig { - versionCode project.VERSION_CODE as int - versionName project.VERSION_NAME + versionCode versionBuild as int + versionName final_version_name minSdkVersion project.ANDROID_BUILD_MIN_SDK_VERSION as int targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int @@ -24,19 +61,41 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile supportDependencies.appCompat - compile supportDependencies.annotation - compile supportDependencies.support - compile supportDependencies.rv - compile supportDependencies.cv - + compile "com.android.support:appcompat-v7:${SUPPORT_LIBRARY}" + compile "com.android.support:support-v13:${SUPPORT_LIBRARY}" + compile "com.android.support:recyclerview-v7:${SUPPORT_LIBRARY}" //compile 'com.nineoldandroids:library:2.4.0' - compile 'in.srain.cube:ultra-ptr:1.0.11' + //compile 'in.srain.cube:ultra-com.ptr:1.0.11' compile 'com.github.bumptech.glide:glide:3.7.0' - compile 'jp.wasabeef:recyclerview-animators:2.2.1' + compile 'jp.wasabeef:recyclerview-animators:2.2.3' } //apply from: 'android-release-aar.gradle' //apply from: 'maven-push.gradle' -//apply from: 'bintray-release-aar.gradle' -apply from: 'bintray_3_4.gradle' \ No newline at end of file +//apply from: 'bintray_3_4.gradle' + + +apply plugin: 'com.novoda.bintray-release' + +publish { + userOrg = 'jjhesk' + groupId = 'com.hkm.ui' + artifactId = 'ultimaterecyclerview' + version = final_version_name + uploadName = 'MenuURV' + description = "The super recycler for the menu" + website = 'https://github.com/HKMOpen/UltimateRecyclerView' + autoPublish = true + dryRun = false + issueTracker = "${website}/issues" + licences = [project.POM_LICENCE_NAME] + bintrayUser = userOrg +} + +if (hasProperty('APIBKI')) { + publish.bintrayKey = property('APIBKI') +} else { + publish.bintrayKey = '17479d176480ed0232fe101b6555654a2624d7a0' +} + +apply plugin: 'maven' \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/gradle.properties b/UltimateRecyclerView/ultimaterecyclerview/gradle.properties index b84e8fff..07c303a9 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/gradle.properties +++ b/UltimateRecyclerView/ultimaterecyclerview/gradle.properties @@ -1,19 +1,20 @@ POM_NAME=ultimaterecyclerview POM_ARTIFACT_ID=library POM_PACKAGING=aar -VERSION_NAME=0.5.8 -VERSION_CODE=70 +VERSION_NAME=0.8.5 GROUP=com.marshalchen.ultimaterecyclerview POM_DESCRIPTION=A RecyclerView(advanced and flexible version of ListView) with refreshing,loading more,animation and many other features. -POM_URL=https://github.com/cymcsg/UltimateRecyclerView -POM_SCM_URL=https://github.com/cymcsg/UltimateRecyclerView -POM_SCM_CONNECTION=https://github.com/cymcsg/UltimateRecyclerView.git -POM_SCM_DEV_CONNECTION=https://github.com/cymcsg/UltimateRecyclerView.git +POM_URL=https://github.com/HKMOpen/UltimateRecyclerView +POM_SCM_URL=https://github.com/HKMOpen/UltimateRecyclerView +POM_SCM_CONNECTION=https://github.com/HKMOpen/UltimateRecyclerView.git +POM_SCM_DEV_CONNECTION=https://github.com/HKMOpen/UltimateRecyclerView.git POM_LICENCE_NAME=The Apache Software License, Version 2.0 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt POM_LICENCE_DIST=repo -POM_DEVELOPER_ID=cymcsg ; +POM_DEVELOPER_ID=cymcsg POM_DEVELOPER_NAME=marshalchen SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2 + + diff --git a/UltimateRecyclerView/ultimaterecyclerview/sample.txt b/UltimateRecyclerView/ultimaterecyclerview/sample.txt new file mode 100644 index 00000000..4ebc92c3 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/sample.txt @@ -0,0 +1,5 @@ + +VERSION_MINOR=9 +VERSION_BUILD=80 +VERSION_PATCH=36 +VERSION_CODE=80 diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrClassicDefaultHeader.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrClassicDefaultHeader.java new file mode 100644 index 00000000..db17c603 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrClassicDefaultHeader.java @@ -0,0 +1,325 @@ +package com.insraincubeptr; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.animation.LinearInterpolator; +import android.view.animation.RotateAnimation; +import android.widget.FrameLayout; +import android.widget.TextView; + + +import com.marshalchen.ultimaterecyclerview.R; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.insraincubeptr.indicator.PtrIndicator; + + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public class PtrClassicDefaultHeader extends FrameLayout implements PtrUIHandler { + + private final static String KEY_SharedPreferences = "cube_ptr_classic_last_update"; + private static SimpleDateFormat sDataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private int mRotateAniTime = 150; + private RotateAnimation mFlipAnimation; + private RotateAnimation mReverseFlipAnimation; + private TextView mTitleTextView; + private View mRotateView; + private View mProgressBar; + private long mLastUpdateTime = -1; + private TextView mLastUpdateTextView; + private String mLastUpdateTimeKey; + private boolean mShouldShowLastUpdate; + + private LastUpdateTimeUpdater mLastUpdateTimeUpdater = new LastUpdateTimeUpdater(); + + public PtrClassicDefaultHeader(Context context) { + super(context); + initViews(null); + } + + public PtrClassicDefaultHeader(Context context, AttributeSet attrs) { + super(context, attrs); + initViews(attrs); + } + + public PtrClassicDefaultHeader(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initViews(attrs); + } + + protected void initViews(AttributeSet attrs) { + TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.PtrClassicHeader, 0, 0); + if (arr != null) { + mRotateAniTime = arr.getInt(R.styleable.PtrClassicHeader_ptr_rotate_ani_time, mRotateAniTime); + } + buildAnimation(); + View header = LayoutInflater.from(getContext()).inflate(R.layout.cube_ptr_classic_default_header, this); + + mRotateView = header.findViewById(R.id.ptr_classic_header_rotate_view); + + mTitleTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_title); + mLastUpdateTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_last_update); + mProgressBar = header.findViewById(R.id.ptr_classic_header_rotate_view_progressbar); + + resetView(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mLastUpdateTimeUpdater != null) { + mLastUpdateTimeUpdater.stop(); + } + } + + public void setRotateAniTime(int time) { + if (time == mRotateAniTime || time == 0) { + return; + } + mRotateAniTime = time; + buildAnimation(); + } + + /** + * Specify the last update time by this key string + * + * @param key na + */ + public void setLastUpdateTimeKey(String key) { + if (TextUtils.isEmpty(key)) { + return; + } + mLastUpdateTimeKey = key; + } + + /** + * Using an object to specify the last update time. + * + * @param object na + */ + public void setLastUpdateTimeRelateObject(Object object) { + setLastUpdateTimeKey(object.getClass().getName()); + } + + private void buildAnimation() { + mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); + mFlipAnimation.setInterpolator(new LinearInterpolator()); + mFlipAnimation.setDuration(mRotateAniTime); + mFlipAnimation.setFillAfter(true); + + mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); + mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); + mReverseFlipAnimation.setDuration(mRotateAniTime); + mReverseFlipAnimation.setFillAfter(true); + } + + private void resetView() { + hideRotateView(); + mProgressBar.setVisibility(INVISIBLE); + } + + private void hideRotateView() { + mRotateView.clearAnimation(); + mRotateView.setVisibility(INVISIBLE); + } + + @Override + public void onUIReset(PtrFrameLayout frame) { + resetView(); + mShouldShowLastUpdate = true; + tryUpdateLastUpdateTime(); + } + + @Override + public void onUIRefreshPrepare(PtrFrameLayout frame) { + + mShouldShowLastUpdate = true; + tryUpdateLastUpdateTime(); + mLastUpdateTimeUpdater.start(); + + mProgressBar.setVisibility(INVISIBLE); + + mRotateView.setVisibility(VISIBLE); + mTitleTextView.setVisibility(VISIBLE); + if (frame.isPullToRefresh()) { + mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh)); + } else { + mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down)); + } + } + + @Override + public void onUIRefreshBegin(PtrFrameLayout frame) { + mShouldShowLastUpdate = false; + hideRotateView(); + mProgressBar.setVisibility(VISIBLE); + mTitleTextView.setVisibility(VISIBLE); + mTitleTextView.setText(R.string.cube_ptr_refreshing); + + tryUpdateLastUpdateTime(); + mLastUpdateTimeUpdater.stop(); + } + + @Override + public void onUIRefreshComplete(PtrFrameLayout frame) { + + hideRotateView(); + mProgressBar.setVisibility(INVISIBLE); + + mTitleTextView.setVisibility(VISIBLE); + mTitleTextView.setText(getResources().getString(R.string.cube_ptr_refresh_complete)); + + // update last update time + SharedPreferences sharedPreferences = getContext().getSharedPreferences(KEY_SharedPreferences, 0); + if (!TextUtils.isEmpty(mLastUpdateTimeKey)) { + mLastUpdateTime = new Date().getTime(); + sharedPreferences.edit().putLong(mLastUpdateTimeKey, mLastUpdateTime).commit(); + } + } + + private void tryUpdateLastUpdateTime() { + if (TextUtils.isEmpty(mLastUpdateTimeKey) || !mShouldShowLastUpdate) { + mLastUpdateTextView.setVisibility(GONE); + } else { + String time = getLastUpdateTime(); + if (TextUtils.isEmpty(time)) { + mLastUpdateTextView.setVisibility(GONE); + } else { + mLastUpdateTextView.setVisibility(VISIBLE); + mLastUpdateTextView.setText(time); + } + } + } + + private String getLastUpdateTime() { + + if (mLastUpdateTime == -1 && !TextUtils.isEmpty(mLastUpdateTimeKey)) { + mLastUpdateTime = getContext().getSharedPreferences(KEY_SharedPreferences, 0).getLong(mLastUpdateTimeKey, -1); + } + if (mLastUpdateTime == -1) { + return null; + } + long diffTime = new Date().getTime() - mLastUpdateTime; + int seconds = (int) (diffTime / 1000); + if (diffTime < 0) { + return null; + } + if (seconds <= 0) { + return null; + } + StringBuilder sb = new StringBuilder(); + sb.append(getContext().getString(R.string.cube_ptr_last_update)); + + if (seconds < 60) { + sb.append(seconds + getContext().getString(R.string.cube_ptr_seconds_ago)); + } else { + int minutes = (seconds / 60); + if (minutes > 60) { + int hours = minutes / 60; + if (hours > 24) { + Date date = new Date(mLastUpdateTime); + sb.append(sDataFormat.format(date)); + } else { + sb.append(hours + getContext().getString(R.string.cube_ptr_hours_ago)); + } + + } else { + sb.append(minutes + getContext().getString(R.string.cube_ptr_minutes_ago)); + } + } + return sb.toString(); + } + + @Override + public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) { + + final int mOffsetToRefresh = frame.getOffsetToRefresh(); + final int currentPos = ptrIndicator.getCurrentPosY(); + final int lastPos = ptrIndicator.getLastPosY(); + + if (currentPos < mOffsetToRefresh && lastPos >= mOffsetToRefresh) { + if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) { + crossRotateLineFromBottomUnderTouch(frame); + if (mRotateView != null) { + mRotateView.clearAnimation(); + mRotateView.startAnimation(mReverseFlipAnimation); + } + } + } else if (currentPos > mOffsetToRefresh && lastPos <= mOffsetToRefresh) { + if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) { + crossRotateLineFromTopUnderTouch(frame); + if (mRotateView != null) { + mRotateView.clearAnimation(); + mRotateView.startAnimation(mFlipAnimation); + } + } + } + } + + private void crossRotateLineFromTopUnderTouch(PtrFrameLayout frame) { + if (!frame.isPullToRefresh()) { + mTitleTextView.setVisibility(VISIBLE); + mTitleTextView.setText(R.string.cube_ptr_release_to_refresh); + } + } + + private void crossRotateLineFromBottomUnderTouch(PtrFrameLayout frame) { + mTitleTextView.setVisibility(VISIBLE); + if (frame.isPullToRefresh()) { + mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh)); + } else { + mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down)); + } + } + + private class LastUpdateTimeUpdater implements Runnable { + + private boolean mRunning = false; + + private void start() { + if (TextUtils.isEmpty(mLastUpdateTimeKey)) { + return; + } + mRunning = true; + run(); + } + + private void stop() { + mRunning = false; + removeCallbacks(this); + } + + @Override + public void run() { + tryUpdateLastUpdateTime(); + if (mRunning) { + postDelayed(this, 1000); + } + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrClassicFrameLayout.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrClassicFrameLayout.java new file mode 100644 index 00000000..fc88f156 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrClassicFrameLayout.java @@ -0,0 +1,61 @@ +package com.insraincubeptr; + +import android.content.Context; +import android.util.AttributeSet; + +/** + * This layout view for "Pull to Refresh(Ptr)" support all of the view, you can contain everything you want. + * support: pull to refresh / release to refresh / auto refresh / keep header view while refreshing / hide header view while refreshing + * It defines {@link com.insraincubeptr.PtrUIHandler}, which allows you customize the UI easily. + */ +public class PtrClassicFrameLayout extends PtrFrameLayout { + + private PtrClassicDefaultHeader mPtrClassicHeader; + + public PtrClassicFrameLayout(Context context) { + super(context); + initViews(); + } + + public PtrClassicFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + initViews(); + } + + public PtrClassicFrameLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initViews(); + } + + private void initViews() { + mPtrClassicHeader = new PtrClassicDefaultHeader(getContext()); + setHeaderView(mPtrClassicHeader); + addPtrUIHandler(mPtrClassicHeader); + } + + public PtrClassicDefaultHeader getHeader() { + return mPtrClassicHeader; + } + + /** + * Specify the last update time by this key string + * + * @param key na + */ + public void setLastUpdateTimeKey(String key) { + if (mPtrClassicHeader != null) { + mPtrClassicHeader.setLastUpdateTimeKey(key); + } + } + + /** + * Using an object to specify the last update time. + * + * @param object na + */ + public void setLastUpdateTimeRelateObject(Object object) { + if (mPtrClassicHeader != null) { + mPtrClassicHeader.setLastUpdateTimeRelateObject(object); + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrDefaultHandler.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrDefaultHandler.java new file mode 100644 index 00000000..82fcf1fe --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrDefaultHandler.java @@ -0,0 +1,58 @@ +package com.insraincubeptr; + +import android.view.View; +import android.widget.AbsListView; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public abstract class PtrDefaultHandler implements PtrHandler { + + public static boolean canChildScrollUp(View view) { + if (android.os.Build.VERSION.SDK_INT < 14) { + if (view instanceof AbsListView) { + final AbsListView absListView = (AbsListView) view; + return absListView.getChildCount() > 0 + && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) + .getTop() < absListView.getPaddingTop()); + } else { + return view.getScrollY() > 0; + } + } else { + return view.canScrollVertically(-1); + } + } + + /** + * Default implement for check can perform pull to refresh + * + * @param frame object + * @param content object + * @param header object + * @return can be pulled? + */ + public static boolean checkContentCanBePulledDown(PtrFrameLayout frame, View content, View header) { + return !canChildScrollUp(content); + } + + @Override + public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) { + return checkContentCanBePulledDown(frame, content, header); + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrFrameLayout.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrFrameLayout.java new file mode 100644 index 00000000..ef5a29e6 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrFrameLayout.java @@ -0,0 +1,1072 @@ +package com.insraincubeptr; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.widget.Scroller; +import android.widget.TextView; + +import com.marshalchen.ultimaterecyclerview.R; + +import com.insraincubeptr.indicator.PtrIndicator; +import com.insraincubeptr.util.PtrCLog; + + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +/** + * This layout view for "Pull to Refresh(Ptr)" support all of the view, you can contain everything you want. + * support: pull to refresh / release to refresh / auto refresh / keep header view while refreshing / hide header view while refreshing + * It defines {@link com.insraincubeptr.PtrUIHandler}, which allows you customize the UI easily. + */ +public class PtrFrameLayout extends ViewGroup { + + // status enum + public final static byte PTR_STATUS_INIT = 1; + private byte mStatus = PTR_STATUS_INIT; + public final static byte PTR_STATUS_PREPARE = 2; + public final static byte PTR_STATUS_LOADING = 3; + public final static byte PTR_STATUS_COMPLETE = 4; + private static final boolean DEBUG_LAYOUT = true; + public static boolean DEBUG = false; + private static int ID = 1; + protected final String LOG_TAG = "com.ptr-frame-" + ++ID; + // auto refresh status + private final static byte FLAG_AUTO_REFRESH_AT_ONCE = 0x01; + private final static byte FLAG_AUTO_REFRESH_BUT_LATER = 0x01 << 1; + private final static byte FLAG_ENABLE_NEXT_PTR_AT_ONCE = 0x01 << 2; + private final static byte FLAG_PIN_CONTENT = 0x01 << 3; + private final static byte MASK_AUTO_REFRESH = 0x03; + protected View mContent; + // optional config for define header and content in xml file + private int mHeaderId = 0; + private int mContainerId = 0; + // config + private int mDurationToClose = 200; + private int mDurationToCloseHeader = 1000; + private boolean mKeepHeaderWhenRefresh = true; + private boolean mPullToRefresh = false; + private View mHeaderView; + private PtrUIHandlerHolder mPtrUIHandlerHolder = PtrUIHandlerHolder.create(); + private PtrHandler mPtrHandler; + // working parameters + private ScrollChecker mScrollChecker; + private int mPagingTouchSlop; + private int mHeaderHeight; + private boolean mDisableWhenHorizontalMove = false; + private int mFlag = 0x00; + + // disable when detect moving horizontally + private boolean mPreventForHorizontal = false; + + private MotionEvent mLastMoveEvent; + + private PtrUIHandlerHook mRefreshCompleteHook; + + private int mLoadingMinTime = 500; + private long mLoadingStartTime = 0; + private PtrIndicator mPtrIndicator; + private boolean mHasSendCancelEvent = false; + private Runnable mPerformRefreshCompleteDelay = new Runnable() { + @Override + public void run() { + performRefreshComplete(); + } + }; + + public PtrFrameLayout(Context context) { + this(context, null); + } + + public PtrFrameLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public PtrFrameLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + mPtrIndicator = new PtrIndicator(); + + TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.PtrFrameLayout, 0, 0); + if (arr != null) { + + mHeaderId = arr.getResourceId(R.styleable.PtrFrameLayout_ptr_header, mHeaderId); + mContainerId = arr.getResourceId(R.styleable.PtrFrameLayout_ptr_content, mContainerId); + + mPtrIndicator.setResistance( + arr.getFloat(R.styleable.PtrFrameLayout_ptr_resistance, mPtrIndicator.getResistance())); + + mDurationToClose = arr.getInt(R.styleable.PtrFrameLayout_ptr_duration_to_close, mDurationToClose); + mDurationToCloseHeader = arr.getInt(R.styleable.PtrFrameLayout_ptr_duration_to_close_header, mDurationToCloseHeader); + + float ratio = mPtrIndicator.getRatioOfHeaderToHeightRefresh(); + ratio = arr.getFloat(R.styleable.PtrFrameLayout_ptr_ratio_of_header_height_to_refresh, ratio); + mPtrIndicator.setRatioOfHeaderHeightToRefresh(ratio); + + mKeepHeaderWhenRefresh = arr.getBoolean(R.styleable.PtrFrameLayout_ptr_keep_header_when_refresh, mKeepHeaderWhenRefresh); + + mPullToRefresh = arr.getBoolean(R.styleable.PtrFrameLayout_ptr_pull_to_fresh, mPullToRefresh); + arr.recycle(); + } + + mScrollChecker = new ScrollChecker(); + + final ViewConfiguration conf = ViewConfiguration.get(getContext()); + mPagingTouchSlop = conf.getScaledTouchSlop() * 2; + } + + @Override + protected void onFinishInflate() { + final int childCount = getChildCount(); + if (childCount > 2) { + throw new IllegalStateException("PtrFrameLayout can only contains 2 children"); + } else if (childCount == 2) { + if (mHeaderId != 0 && mHeaderView == null) { + mHeaderView = findViewById(mHeaderId); + } + if (mContainerId != 0 && mContent == null) { + mContent = findViewById(mContainerId); + } + + // not specify header or content + if (mContent == null || mHeaderView == null) { + + View child1 = getChildAt(0); + View child2 = getChildAt(1); + if (child1 instanceof PtrUIHandler) { + mHeaderView = child1; + mContent = child2; + } else if (child2 instanceof PtrUIHandler) { + mHeaderView = child2; + mContent = child1; + } else { + // both are not specified + if (mContent == null && mHeaderView == null) { + mHeaderView = child1; + mContent = child2; + } + // only one is specified + else { + if (mHeaderView == null) { + mHeaderView = mContent == child1 ? child2 : child1; + } else { + mContent = mHeaderView == child1 ? child2 : child1; + } + } + } + } + } else if (childCount == 1) { + mContent = getChildAt(0); + } else { + TextView errorView = new TextView(getContext()); + errorView.setClickable(true); + errorView.setTextColor(0xffff6600); + errorView.setGravity(Gravity.CENTER); + errorView.setTextSize(20); + errorView.setText("The content view in PtrFrameLayout is empty. Do you forget to specify its id in xml layout file?"); + mContent = errorView; + addView(mContent); + } + if (mHeaderView != null) { + mHeaderView.bringToFront(); + } + super.onFinishInflate(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mScrollChecker != null) { + mScrollChecker.destroy(); + } + + if (mPerformRefreshCompleteDelay != null) { + removeCallbacks(mPerformRefreshCompleteDelay); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + if (isDebug()) { + PtrCLog.d(LOG_TAG, "onMeasure frame: width: %s, height: %s, padding: %s %s %s %s", + getMeasuredHeight(), getMeasuredWidth(), + getPaddingLeft(), getPaddingRight(), getPaddingTop(), getPaddingBottom()); + + } + + if (mHeaderView != null) { + measureChildWithMargins(mHeaderView, widthMeasureSpec, 0, heightMeasureSpec, 0); + MarginLayoutParams lp = (MarginLayoutParams) mHeaderView.getLayoutParams(); + mHeaderHeight = mHeaderView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; + mPtrIndicator.setHeaderHeight(mHeaderHeight); + } + + if (mContent != null) { + measureContentView(mContent, widthMeasureSpec, heightMeasureSpec); + if (isDebug()) { + ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) mContent.getLayoutParams(); + PtrCLog.d(LOG_TAG, "onMeasure content, width: %s, height: %s, margin: %s %s %s %s", + getMeasuredWidth(), getMeasuredHeight(), + lp.leftMargin, lp.topMargin, lp.rightMargin, lp.bottomMargin); + PtrCLog.d(LOG_TAG, "onMeasure, currentPos: %s, lastPos: %s, top: %s", + mPtrIndicator.getCurrentPosY(), mPtrIndicator.getLastPosY(), mContent.getTop()); + } + } + } + + private void measureContentView(View child, + int parentWidthMeasureSpec, + int parentHeightMeasureSpec) { + final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); + + final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, + getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin, lp.width); + final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, + getPaddingTop() + getPaddingBottom() + lp.topMargin, lp.height); + + child.measure(childWidthMeasureSpec, childHeightMeasureSpec); + } + + @Override + protected void onLayout(boolean flag, int i, int j, int k, int l) { + layoutChildren(); + } + + private void layoutChildren() { + int offset = mPtrIndicator.getCurrentPosY(); + int paddingLeft = getPaddingLeft(); + int paddingTop = getPaddingTop(); + + if (mHeaderView != null) { + MarginLayoutParams lp = (MarginLayoutParams) mHeaderView.getLayoutParams(); + final int left = paddingLeft + lp.leftMargin; + // enhance readability(header is layout above screen when first init) + final int top = -(mHeaderHeight - paddingTop - lp.topMargin - offset); + final int right = left + mHeaderView.getMeasuredWidth(); + final int bottom = top + mHeaderView.getMeasuredHeight(); + mHeaderView.layout(left, top, right, bottom); + if (isDebug()) { + PtrCLog.d(LOG_TAG, "onLayout header: %s %s %s %s", left, top, right, bottom); + } + } + if (mContent != null) { + if (isPinContent()) { + offset = 0; + } + MarginLayoutParams lp = (MarginLayoutParams) mContent.getLayoutParams(); + final int left = paddingLeft + lp.leftMargin; + final int top = paddingTop + lp.topMargin + offset; + final int right = left + mContent.getMeasuredWidth(); + final int bottom = top + mContent.getMeasuredHeight(); + if (isDebug()) { + PtrCLog.d(LOG_TAG, "onLayout content: %s %s %s %s", left, top, right, bottom); + } + mContent.layout(left, top, right, bottom); + } + } + + @SuppressWarnings({"PointlessBooleanExpression", "ConstantConditions"}) + private boolean isDebug() { + return DEBUG && DEBUG_LAYOUT; + } + + public boolean dispatchTouchEventSupper(MotionEvent e) { + return super.dispatchTouchEvent(e); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent e) { + if (!isEnabled() || mContent == null || mHeaderView == null) { + return dispatchTouchEventSupper(e); + } + int action = e.getAction(); + switch (action) { + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + mPtrIndicator.onRelease(); + if (mPtrIndicator.hasLeftStartPosition()) { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "call onRelease when user release"); + } + onRelease(false); + if (mPtrIndicator.hasMovedAfterPressedDown()) { + sendCancelEvent(); + return true; + } + return dispatchTouchEventSupper(e); + } else { + return dispatchTouchEventSupper(e); + } + + case MotionEvent.ACTION_DOWN: + mHasSendCancelEvent = false; + mPtrIndicator.onPressDown(e.getX(), e.getY()); + + mScrollChecker.abortIfWorking(); + + mPreventForHorizontal = false; + // The cancel event will be sent once the position is moved. + // So let the event pass to children. + // fix #93, #102 + dispatchTouchEventSupper(e); + return true; + + case MotionEvent.ACTION_MOVE: + mLastMoveEvent = e; + mPtrIndicator.onMove(e.getX(), e.getY()); + float offsetX = mPtrIndicator.getOffsetX(); + float offsetY = mPtrIndicator.getOffsetY(); + + if (mDisableWhenHorizontalMove && !mPreventForHorizontal && (Math.abs(offsetX) > mPagingTouchSlop && Math.abs(offsetX) > Math.abs(offsetY))) { + if (mPtrIndicator.isInStartPosition()) { + mPreventForHorizontal = true; + } + } + if (mPreventForHorizontal) { + return dispatchTouchEventSupper(e); + } + + boolean moveDown = offsetY > 0; + boolean moveUp = !moveDown; + boolean canMoveUp = mPtrIndicator.hasLeftStartPosition(); + + if (DEBUG) { + boolean canMoveDown = mPtrHandler != null && mPtrHandler.checkCanDoRefresh(this, mContent, mHeaderView); + PtrCLog.v(LOG_TAG, "ACTION_MOVE: offsetY:%s, currentPos: %s, moveUp: %s, canMoveUp: %s, moveDown: %s: canMoveDown: %s", offsetY, mPtrIndicator.getCurrentPosY(), moveUp, canMoveUp, moveDown, canMoveDown); + } + + // disable move when header not reach top + if (moveDown && mPtrHandler != null && !mPtrHandler.checkCanDoRefresh(this, mContent, mHeaderView)) { + return dispatchTouchEventSupper(e); + } + + if ((moveUp && canMoveUp) || moveDown) { + movePos(offsetY); + return true; + } + } + return dispatchTouchEventSupper(e); + } + + /** + * if deltaY > 0, move the content down + * + * @param deltaY + */ + private void movePos(float deltaY) { + // has reached the top + if ((deltaY < 0 && mPtrIndicator.isInStartPosition())) { + if (DEBUG) { + PtrCLog.e(LOG_TAG, String.format("has reached the top")); + } + return; + } + + int to = mPtrIndicator.getCurrentPosY() + (int) deltaY; + + // over top + if (mPtrIndicator.willOverTop(to)) { + if (DEBUG) { + PtrCLog.e(LOG_TAG, String.format("over top")); + } + to = PtrIndicator.POS_START; + } + + mPtrIndicator.setCurrentPos(to); + int change = to - mPtrIndicator.getLastPosY(); + updatePos(change); + } + + private void updatePos(int change) { + if (change == 0) { + return; + } + + boolean isUnderTouch = mPtrIndicator.isUnderTouch(); + + // once moved, cancel event will be sent to child + if (isUnderTouch && !mHasSendCancelEvent && mPtrIndicator.hasMovedAfterPressedDown()) { + mHasSendCancelEvent = true; + sendCancelEvent(); + } + + // leave initiated position or just refresh complete + if ((mPtrIndicator.hasJustLeftStartPosition() && mStatus == PTR_STATUS_INIT) || + (mPtrIndicator.goDownCrossFinishPosition() && mStatus == PTR_STATUS_COMPLETE && isEnabledNextPtrAtOnce())) { + + mStatus = PTR_STATUS_PREPARE; + mPtrUIHandlerHolder.onUIRefreshPrepare(this); + if (DEBUG) { + PtrCLog.i(LOG_TAG, "PtrUIHandler: onUIRefreshPrepare, mFlag %s", mFlag); + } + } + + // back to initiated position + if (mPtrIndicator.hasJustBackToStartPosition()) { + tryToNotifyReset(); + + // recover event to children + if (isUnderTouch) { + sendDownEvent(); + } + } + + // Pull to Refresh + if (mStatus == PTR_STATUS_PREPARE) { + // reach fresh height while moving from top to bottom + if (isUnderTouch && !isAutoRefresh() && mPullToRefresh + && mPtrIndicator.crossRefreshLineFromTopToBottom()) { + tryToPerformRefresh(); + } + // reach header height while auto refresh + if (performAutoRefreshButLater() && mPtrIndicator.hasJustReachedHeaderHeightFromTopToBottom()) { + tryToPerformRefresh(); + } + } + + if (DEBUG) { + PtrCLog.v(LOG_TAG, "updatePos: change: %s, current: %s last: %s, top: %s, headerHeight: %s", + change, mPtrIndicator.getCurrentPosY(), mPtrIndicator.getLastPosY(), mContent.getTop(), mHeaderHeight); + } + + mHeaderView.offsetTopAndBottom(change); + if (!isPinContent()) { + mContent.offsetTopAndBottom(change); + } + invalidate(); + + if (mPtrUIHandlerHolder.hasHandler()) { + mPtrUIHandlerHolder.onUIPositionChange(this, isUnderTouch, mStatus, mPtrIndicator); + } + onPositionChange(isUnderTouch, mStatus, mPtrIndicator); + } + + protected void onPositionChange(boolean isInTouching, byte status, PtrIndicator mPtrIndicator) { + } + + @SuppressWarnings("unused") + public int getHeaderHeight() { + return mHeaderHeight; + } + + private void onRelease(boolean stayForLoading) { + + tryToPerformRefresh(); + + if (mStatus == PTR_STATUS_LOADING) { + // keep header for fresh + if (mKeepHeaderWhenRefresh) { + // scroll header back + if (mPtrIndicator.isOverOffsetToKeepHeaderWhileLoading() && !stayForLoading) { + mScrollChecker.tryToScrollTo(mPtrIndicator.getOffsetToKeepHeaderWhileLoading(), mDurationToClose); + } else { + // do nothing + } + } else { + tryScrollBackToTopWhileLoading(); + } + } else { + if (mStatus == PTR_STATUS_COMPLETE) { + notifyUIRefreshComplete(false); + } else { + tryScrollBackToTopAbortRefresh(); + } + } + } + + /** + * please DO REMEMBER resume the hook + * + * @param hook object + */ + public void setRefreshCompleteHook(PtrUIHandlerHook hook) { + mRefreshCompleteHook = hook; + hook.setResumeAction(new Runnable() { + @Override + public void run() { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "mRefreshCompleteHook resume."); + } + notifyUIRefreshComplete(true); + } + }); + } + + /** + * Scroll back to to if is not under touch + */ + private void tryScrollBackToTop() { + if (!mPtrIndicator.isUnderTouch()) { + mScrollChecker.tryToScrollTo(PtrIndicator.POS_START, mDurationToCloseHeader); + } + } + + /** + * just make easier to understand + */ + private void tryScrollBackToTopWhileLoading() { + tryScrollBackToTop(); + } + + /** + * just make easier to understand + */ + private void tryScrollBackToTopAfterComplete() { + tryScrollBackToTop(); + } + + /** + * just make easier to understand + */ + private void tryScrollBackToTopAbortRefresh() { + tryScrollBackToTop(); + } + + private boolean tryToPerformRefresh() { + if (mStatus != PTR_STATUS_PREPARE) { + return false; + } + + // + if ((mPtrIndicator.isOverOffsetToKeepHeaderWhileLoading() && isAutoRefresh()) || mPtrIndicator.isOverOffsetToRefresh()) { + mStatus = PTR_STATUS_LOADING; + performRefresh(); + } + return false; + } + + private void performRefresh() { + mLoadingStartTime = System.currentTimeMillis(); + if (mPtrUIHandlerHolder.hasHandler()) { + mPtrUIHandlerHolder.onUIRefreshBegin(this); + if (DEBUG) { + PtrCLog.i(LOG_TAG, "PtrUIHandler: onUIRefreshBegin"); + } + } + if (mPtrHandler != null) { + mPtrHandler.onRefreshBegin(this); + } + } + + /** + * If at the top and not in loading, reset + */ + private boolean tryToNotifyReset() { + if ((mStatus == PTR_STATUS_COMPLETE || mStatus == PTR_STATUS_PREPARE) && mPtrIndicator.isInStartPosition()) { + if (mPtrUIHandlerHolder.hasHandler()) { + mPtrUIHandlerHolder.onUIReset(this); + if (DEBUG) { + PtrCLog.i(LOG_TAG, "PtrUIHandler: onUIReset"); + } + } + mStatus = PTR_STATUS_INIT; + clearFlag(); + return true; + } + return false; + } + + protected void onPtrScrollAbort() { + if (mPtrIndicator.hasLeftStartPosition() && isAutoRefresh()) { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "call onRelease after scroll abort"); + } + onRelease(true); + } + } + + protected void onPtrScrollFinish() { + if (mPtrIndicator.hasLeftStartPosition() && isAutoRefresh()) { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "call onRelease after scroll finish"); + } + onRelease(true); + } + } + + /** + * Detect whether is refreshing. + * + * @return is not refreshing + */ + public boolean isRefreshing() { + return mStatus == PTR_STATUS_LOADING; + } + + /** + * Call this when data is loaded. + * The UI will perform complete at once or after a delay, depends on the time elapsed is greater then {@link #mLoadingMinTime} or not. + */ + final public void refreshComplete() { + if (DEBUG) { + PtrCLog.i(LOG_TAG, "refreshComplete"); + } + + if (mRefreshCompleteHook != null) { + mRefreshCompleteHook.reset(); + } + + int delay = (int) (mLoadingMinTime - (System.currentTimeMillis() - mLoadingStartTime)); + if (delay <= 0) { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "performRefreshComplete at once"); + } + performRefreshComplete(); + } else { + postDelayed(mPerformRefreshCompleteDelay, delay); + if (DEBUG) { + PtrCLog.d(LOG_TAG, "performRefreshComplete after delay: %s", delay); + } + } + } + + /** + * Do refresh complete work when time elapsed is greater than {@link #mLoadingMinTime} + */ + private void performRefreshComplete() { + mStatus = PTR_STATUS_COMPLETE; + + // if is auto refresh do nothing, wait scroller stop + if (mScrollChecker.mIsRunning && isAutoRefresh()) { + // do nothing + if (DEBUG) { + PtrCLog.d(LOG_TAG, "performRefreshComplete do nothing, scrolling: %s, auto refresh: %s", + mScrollChecker.mIsRunning, mFlag); + } + return; + } + + notifyUIRefreshComplete(false); + } + + /** + * Do real refresh work. If there is a hook, execute the hook first. + * + * @param ignoreHook is hooking working + */ + private void notifyUIRefreshComplete(boolean ignoreHook) { + /** + * After hook operation is done, {@link #notifyUIRefreshComplete} will be call in resume action to ignore hook. + */ + if (mPtrIndicator.hasLeftStartPosition() && !ignoreHook && mRefreshCompleteHook != null) { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "notifyUIRefreshComplete mRefreshCompleteHook run."); + } + + mRefreshCompleteHook.takeOver(); + return; + } + if (mPtrUIHandlerHolder.hasHandler()) { + if (DEBUG) { + PtrCLog.i(LOG_TAG, "PtrUIHandler: onUIRefreshComplete"); + } + mPtrUIHandlerHolder.onUIRefreshComplete(this); + } + mPtrIndicator.onUIRefreshComplete(); + tryScrollBackToTopAfterComplete(); + tryToNotifyReset(); + } + + public void autoRefresh() { + autoRefresh(true, mDurationToCloseHeader); + } + + public void autoRefresh(boolean atOnce) { + autoRefresh(atOnce, mDurationToCloseHeader); + } + + private void clearFlag() { + // remove auto fresh flag + mFlag = mFlag & ~MASK_AUTO_REFRESH; + } + + public void autoRefresh(boolean atOnce, int duration) { + + if (mStatus != PTR_STATUS_INIT) { + return; + } + + mFlag |= atOnce ? FLAG_AUTO_REFRESH_AT_ONCE : FLAG_AUTO_REFRESH_BUT_LATER; + + mStatus = PTR_STATUS_PREPARE; + if (mPtrUIHandlerHolder.hasHandler()) { + mPtrUIHandlerHolder.onUIRefreshPrepare(this); + if (DEBUG) { + PtrCLog.i(LOG_TAG, "PtrUIHandler: onUIRefreshPrepare, mFlag %s", mFlag); + } + } + mScrollChecker.tryToScrollTo(mPtrIndicator.getOffsetToRefresh(), duration); + if (atOnce) { + mStatus = PTR_STATUS_LOADING; + performRefresh(); + } + } + + public boolean isAutoRefresh() { + return (mFlag & MASK_AUTO_REFRESH) > 0; + } + + private boolean performAutoRefreshButLater() { + return (mFlag & MASK_AUTO_REFRESH) == FLAG_AUTO_REFRESH_BUT_LATER; + } + + public boolean isEnabledNextPtrAtOnce() { + return (mFlag & FLAG_ENABLE_NEXT_PTR_AT_ONCE) > 0; + } + + /** + * If @param enable has been set to true. The user can perform next PTR at once. + * + * @param enable na + */ + public void setEnabledNextPtrAtOnce(boolean enable) { + if (enable) { + mFlag = mFlag | FLAG_ENABLE_NEXT_PTR_AT_ONCE; + } else { + mFlag = mFlag & ~FLAG_ENABLE_NEXT_PTR_AT_ONCE; + } + } + + public boolean isPinContent() { + return (mFlag & FLAG_PIN_CONTENT) > 0; + } + + /** + * The content view will now move when set to true. + * + * @param pinContent na + */ + public void setPinContent(boolean pinContent) { + if (pinContent) { + mFlag = mFlag | FLAG_PIN_CONTENT; + } else { + mFlag = mFlag & ~FLAG_PIN_CONTENT; + } + } + + /** + * It's useful when working with viewpager. + * + * @param disable na + */ + public void disableWhenHorizontalMove(boolean disable) { + mDisableWhenHorizontalMove = disable; + } + + /** + * loading will last at least for so long + * + * @param time na + */ + public void setLoadingMinTime(int time) { + mLoadingMinTime = time; + } + + /** + * Not necessary any longer. Once moved, cancel event will be sent to child. + * + * @param yes na + */ + @Deprecated + public void setInterceptEventWhileWorking(boolean yes) { + } + + @SuppressWarnings({"unused"}) + public View getContentView() { + return mContent; + } + + public void setPtrHandler(PtrHandler ptrHandler) { + mPtrHandler = ptrHandler; + } + + public void addPtrUIHandler(PtrUIHandler ptrUIHandler) { + PtrUIHandlerHolder.addHandler(mPtrUIHandlerHolder, ptrUIHandler); + } + + @SuppressWarnings({"unused"}) + public void removePtrUIHandler(PtrUIHandler ptrUIHandler) { + mPtrUIHandlerHolder = PtrUIHandlerHolder.removeHandler(mPtrUIHandlerHolder, ptrUIHandler); + } + + public void setPtrIndicator(PtrIndicator slider) { + if (mPtrIndicator != null && mPtrIndicator != slider) { + slider.convertFrom(mPtrIndicator); + } + mPtrIndicator = slider; + } + + @SuppressWarnings({"unused"}) + public float getResistance() { + return mPtrIndicator.getResistance(); + } + + public void setResistance(float resistance) { + mPtrIndicator.setResistance(resistance); + } + + @SuppressWarnings({"unused"}) + public float getDurationToClose() { + return mDurationToClose; + } + + /** + * The duration to return back to the refresh position + * + * @param duration na + */ + public void setDurationToClose(int duration) { + mDurationToClose = duration; + } + + @SuppressWarnings({"unused"}) + public long getDurationToCloseHeader() { + return mDurationToCloseHeader; + } + + /** + * The duration to close time + * + * @param duration na + */ + public void setDurationToCloseHeader(int duration) { + mDurationToCloseHeader = duration; + } + + public void setRatioOfHeaderHeightToRefresh(float ratio) { + mPtrIndicator.setRatioOfHeaderHeightToRefresh(ratio); + } + + public int getOffsetToRefresh() { + return mPtrIndicator.getOffsetToRefresh(); + } + + @SuppressWarnings({"unused"}) + public void setOffsetToRefresh(int offset) { + mPtrIndicator.setOffsetToRefresh(offset); + } + + @SuppressWarnings({"unused"}) + public float getRatioOfHeaderToHeightRefresh() { + return mPtrIndicator.getRatioOfHeaderToHeightRefresh(); + } + + @SuppressWarnings({"unused"}) + public int getOffsetToKeepHeaderWhileLoading() { + return mPtrIndicator.getOffsetToKeepHeaderWhileLoading(); + } + + @SuppressWarnings({"unused"}) + public void setOffsetToKeepHeaderWhileLoading(int offset) { + mPtrIndicator.setOffsetToKeepHeaderWhileLoading(offset); + } + + @SuppressWarnings({"unused"}) + public boolean isKeepHeaderWhenRefresh() { + return mKeepHeaderWhenRefresh; + } + + public void setKeepHeaderWhenRefresh(boolean keepOrNot) { + mKeepHeaderWhenRefresh = keepOrNot; + } + + public boolean isPullToRefresh() { + return mPullToRefresh; + } + + public void setPullToRefresh(boolean pullToRefresh) { + mPullToRefresh = pullToRefresh; + } + + @SuppressWarnings({"unused"}) + public View getHeaderView() { + return mHeaderView; + } + + public void setHeaderView(View header) { + if (mHeaderView != null && header != null && mHeaderView != header) { + removeView(mHeaderView); + } + ViewGroup.LayoutParams lp = header.getLayoutParams(); + if (lp == null) { + lp = new LayoutParams(-1, -2); + header.setLayoutParams(lp); + } + mHeaderView = header; + addView(header); + } + + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p != null && p instanceof LayoutParams; + } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); + } + + @Override + protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + return new LayoutParams(p); + } + + @Override + public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new LayoutParams(getContext(), attrs); + } + + private void sendCancelEvent() { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "send cancel event"); + } + // The ScrollChecker will update position and lead to send cancel event when mLastMoveEvent is null. + // fix #104, #80, #92 + if (mLastMoveEvent == null) { + return; + } + MotionEvent last = mLastMoveEvent; + MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState()); + dispatchTouchEventSupper(e); + } + + private void sendDownEvent() { + if (DEBUG) { + PtrCLog.d(LOG_TAG, "send down event"); + } + final MotionEvent last = mLastMoveEvent; + MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState()); + dispatchTouchEventSupper(e); + } + + public static class LayoutParams extends MarginLayoutParams { + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + } + + public LayoutParams(int width, int height) { + super(width, height); + } + + @SuppressWarnings({"unused"}) + public LayoutParams(MarginLayoutParams source) { + super(source); + } + + public LayoutParams(ViewGroup.LayoutParams source) { + super(source); + } + } + + class ScrollChecker implements Runnable { + + private int mLastFlingY; + private Scroller mScroller; + private boolean mIsRunning = false; + private int mStart; + private int mTo; + + public ScrollChecker() { + mScroller = new Scroller(getContext()); + } + + public void run() { + boolean finish = !mScroller.computeScrollOffset() || mScroller.isFinished(); + int curY = mScroller.getCurrY(); + int deltaY = curY - mLastFlingY; + if (DEBUG) { + if (deltaY != 0) { + PtrCLog.v(LOG_TAG, + "scroll: %s, start: %s, to: %s, currentPos: %s, current :%s, last: %s, delta: %s", + finish, mStart, mTo, mPtrIndicator.getCurrentPosY(), curY, mLastFlingY, deltaY); + } + } + if (!finish) { + mLastFlingY = curY; + movePos(deltaY); + post(this); + } else { + finish(); + } + } + + private void finish() { + if (DEBUG) { + PtrCLog.v(LOG_TAG, "finish, currentPos:%s", mPtrIndicator.getCurrentPosY()); + } + reset(); + onPtrScrollFinish(); + } + + private void reset() { + mIsRunning = false; + mLastFlingY = 0; + removeCallbacks(this); + } + + private void destroy() { + reset(); + if (!mScroller.isFinished()) { + mScroller.forceFinished(true); + } + } + + public void abortIfWorking() { + if (mIsRunning) { + if (!mScroller.isFinished()) { + mScroller.forceFinished(true); + } + onPtrScrollAbort(); + reset(); + } + } + + public void tryToScrollTo(int to, int duration) { + if (mPtrIndicator.isAlreadyHere(to)) { + return; + } + mStart = mPtrIndicator.getCurrentPosY(); + mTo = to; + int distance = to - mStart; + if (DEBUG) { + PtrCLog.d(LOG_TAG, "tryToScrollTo: start: %s, distance:%s, to:%s", mStart, distance, to); + } + removeCallbacks(this); + + mLastFlingY = 0; + + // fix #47: Scroller should be reused, https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh/issues/47 + if (!mScroller.isFinished()) { + mScroller.forceFinished(true); + } + mScroller.startScroll(0, 0, 0, distance, duration); + post(this); + mIsRunning = true; + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrHandler.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrHandler.java new file mode 100644 index 00000000..54ca6947 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrHandler.java @@ -0,0 +1,42 @@ +package com.insraincubeptr; + +import android.view.View; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public interface PtrHandler { + + /** + * Check can do refresh or not. For example the content is empty or the first child is in view. + * + * @param frame object + * @param content object + * @param header object + * @return bool + */ + boolean checkCanDoRefresh(final PtrFrameLayout frame, final View content, final View header); + + /** + * When refresh begin + * + * @param frame object + */ + void onRefreshBegin(final PtrFrameLayout frame); +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandler.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandler.java new file mode 100644 index 00000000..9285a900 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandler.java @@ -0,0 +1,55 @@ +package com.insraincubeptr; + + +import com.insraincubeptr.indicator.PtrIndicator; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ +public interface PtrUIHandler { + + /** + * When the content view has reached top and refresh has been completed, view will be reset. + * + * @param frame na + */ + void onUIReset(PtrFrameLayout frame); + + /** + * prepare for loading + * + * @param frame na + */ + void onUIRefreshPrepare(PtrFrameLayout frame); + + /** + * perform refreshing UI + * + * @param frame na + */ + void onUIRefreshBegin(PtrFrameLayout frame); + + /** + * perform UI after refresh + * + * @param frame na + */ + void onUIRefreshComplete(PtrFrameLayout frame); + + void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator); +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandlerHolder.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandlerHolder.java new file mode 100644 index 00000000..8bbc9d6b --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandlerHolder.java @@ -0,0 +1,179 @@ +package com.insraincubeptr; + + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +import com.insraincubeptr.indicator.PtrIndicator; + +/** + * A single linked list to wrap PtrUIHandler + */ +public class PtrUIHandlerHolder implements PtrUIHandler { + + private PtrUIHandler mHandler; + private PtrUIHandlerHolder mNext; + + private boolean contains(PtrUIHandler handler) { + return mHandler != null && mHandler == handler; + } + + private PtrUIHandlerHolder() { + + } + + public boolean hasHandler() { + return mHandler != null; + } + + private PtrUIHandler getHandler() { + return mHandler; + } + + public static void addHandler(PtrUIHandlerHolder head, PtrUIHandler handler) { + + if (null == handler) { + return; + } + if (head == null) { + return; + } + if (null == head.mHandler) { + head.mHandler = handler; + return; + } + + PtrUIHandlerHolder current = head; + for (; ; current = current.mNext) { + + // duplicated + if (current.contains(handler)) { + return; + } + if (current.mNext == null) { + break; + } + } + + PtrUIHandlerHolder newHolder = new PtrUIHandlerHolder(); + newHolder.mHandler = handler; + current.mNext = newHolder; + } + + public static PtrUIHandlerHolder create() { + return new PtrUIHandlerHolder(); + } + + public static PtrUIHandlerHolder removeHandler(PtrUIHandlerHolder head, PtrUIHandler handler) { + if (head == null || handler == null || null == head.mHandler) { + return head; + } + + PtrUIHandlerHolder current = head; + PtrUIHandlerHolder pre = null; + do { + + // delete current: link pre to next, unlink next from current; + // pre will no change, current move to next element; + if (current.contains(handler)) { + + // current is head + if (pre == null) { + + head = current.mNext; + current.mNext = null; + + current = head; + } else { + + pre.mNext = current.mNext; + current.mNext = null; + current = pre.mNext; + } + } else { + pre = current; + current = current.mNext; + } + + } while (current != null); + + if (head == null) { + head = new PtrUIHandlerHolder(); + } + return head; + } + + @Override + public void onUIReset(PtrFrameLayout frame) { + PtrUIHandlerHolder current = this; + do { + final PtrUIHandler handler = current.getHandler(); + if (null != handler) { + handler.onUIReset(frame); + } + } while ((current = current.mNext) != null); + } + + @Override + public void onUIRefreshPrepare(PtrFrameLayout frame) { + if (!hasHandler()) { + return; + } + PtrUIHandlerHolder current = this; + do { + final PtrUIHandler handler = current.getHandler(); + if (null != handler) { + handler.onUIRefreshPrepare(frame); + } + } while ((current = current.mNext) != null); + } + + @Override + public void onUIRefreshBegin(PtrFrameLayout frame) { + PtrUIHandlerHolder current = this; + do { + final PtrUIHandler handler = current.getHandler(); + if (null != handler) { + handler.onUIRefreshBegin(frame); + } + } while ((current = current.mNext) != null); + } + + @Override + public void onUIRefreshComplete(PtrFrameLayout frame) { + PtrUIHandlerHolder current = this; + do { + final PtrUIHandler handler = current.getHandler(); + if (null != handler) { + handler.onUIRefreshComplete(frame); + } + } while ((current = current.mNext) != null); + } + + @Override + public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) { + PtrUIHandlerHolder current = this; + do { + final PtrUIHandler handler = current.getHandler(); + if (null != handler) { + handler.onUIPositionChange(frame, isUnderTouch, status, ptrIndicator); + } + } while ((current = current.mNext) != null); + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandlerHook.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandlerHook.java new file mode 100644 index 00000000..a6796469 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/PtrUIHandlerHook.java @@ -0,0 +1,73 @@ +package com.insraincubeptr; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + * Run a hook runnable, the runnable will run only once. + * After the runnable is done, call resume to resume. + * Once run, call takeover will directory call the resume action + * + */ +public abstract class PtrUIHandlerHook implements Runnable { + + private Runnable mResumeAction; + private static final byte STATUS_PREPARE = 0; + private static final byte STATUS_IN_HOOK = 1; + private static final byte STATUS_RESUMED = 2; + private byte mStatus = STATUS_PREPARE; + + public void takeOver() { + takeOver(null); + } + + public void takeOver(Runnable resumeAction) { + if (resumeAction != null) { + mResumeAction = resumeAction; + } + switch (mStatus) { + case STATUS_PREPARE: + mStatus = STATUS_IN_HOOK; + run(); + break; + case STATUS_IN_HOOK: + break; + case STATUS_RESUMED: + resume(); + break; + } + } + + public void reset() { + mStatus = STATUS_PREPARE; + } + + public void resume() { + if (mResumeAction != null) { + mResumeAction.run(); + } + mStatus = STATUS_RESUMED; + } + + /** + * Hook should always have a resume action, which is hooked by this hook. + * + * @param runnable object + */ + public void setResumeAction(Runnable runnable) { + mResumeAction = runnable; + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/MaterialHeader.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/MaterialHeader.java new file mode 100644 index 00000000..79377a56 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/MaterialHeader.java @@ -0,0 +1,210 @@ +package com.insraincubeptr.header; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.annotation.ColorRes; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Transformation; + +import com.insraincubeptr.PtrFrameLayout; +import com.insraincubeptr.PtrUIHandler; +import com.insraincubeptr.PtrUIHandlerHook; +import com.insraincubeptr.indicator.PtrIndicator; + + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ +public class MaterialHeader extends View implements PtrUIHandler { + + private MaterialProgressDrawable mDrawable; + private float mScale = 1f; + private PtrFrameLayout mPtrFrameLayout; + + private Animation mScaleAnimation = new Animation() { + @Override + public void applyTransformation(float interpolatedTime, Transformation t) { + mScale = 1f - interpolatedTime; + mDrawable.setAlpha((int) (255 * mScale)); + invalidate(); + } + }; + + public MaterialHeader(Context context) { + super(context); + initView(); + } + + public MaterialHeader(Context context, AttributeSet attrs) { + super(context, attrs); + initView(); + } + + public MaterialHeader(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(); + } + + public void setPtrFrameLayout(PtrFrameLayout layout) { + + final PtrUIHandlerHook mPtrUIHandlerHook = new PtrUIHandlerHook() { + @Override + public void run() { + startAnimation(mScaleAnimation); + } + }; + + mScaleAnimation.setDuration(200); + mScaleAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + + } + + @Override + public void onAnimationEnd(Animation animation) { + mPtrUIHandlerHook.resume(); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + + mPtrFrameLayout = layout; + mPtrFrameLayout.setRefreshCompleteHook(mPtrUIHandlerHook); + } + + private void initView() { + mDrawable = new MaterialProgressDrawable(getContext(), this); + mDrawable.setBackgroundColor(Color.WHITE); + mDrawable.setCallback(this); + } + + @Override + public void invalidateDrawable(Drawable dr) { + if (dr == mDrawable) { + invalidate(); + } else { + super.invalidateDrawable(dr); + } + } + + public void setColorSchemeColors(int[] colors) { + mDrawable.setColorSchemeColors(colors); + invalidate(); + } + + //for single color + public void setColorSchemeColor(@ColorRes int rid) { + int[] colors = new int[]{getResources().getColor(rid)}; + mDrawable.setColorSchemeColors(colors); + invalidate(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int height = mDrawable.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom(); + heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + final int size = mDrawable.getIntrinsicHeight(); + mDrawable.setBounds(0, 0, size, size); + } + + @Override + protected void onDraw(Canvas canvas) { + final int saveCount = canvas.save(); + Rect rect = mDrawable.getBounds(); + int l = getPaddingLeft() + (getMeasuredWidth() - mDrawable.getIntrinsicWidth()) / 2; + canvas.translate(l, getPaddingTop()); + canvas.scale(mScale, mScale, rect.exactCenterX(), rect.exactCenterY()); + mDrawable.draw(canvas); + canvas.restoreToCount(saveCount); + } + + /** + * When the content view has reached top and refresh has been completed, view will be reset. + * + * @param frame na + */ + @Override + public void onUIReset(PtrFrameLayout frame) { + mScale = 1f; + mDrawable.stop(); + } + + /** + * prepare for loading + * + * @param frame na + */ + @Override + public void onUIRefreshPrepare(PtrFrameLayout frame) { + } + + /** + * perform refreshing UI + * + * @param frame na + */ + @Override + public void onUIRefreshBegin(PtrFrameLayout frame) { + mDrawable.setAlpha(255); + mDrawable.start(); + } + + /** + * perform UI after refresh + * + * @param frame na + */ + @Override + public void onUIRefreshComplete(PtrFrameLayout frame) { + mDrawable.stop(); + } + + @Override + public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) { + + float percent = Math.min(1f, ptrIndicator.getCurrentPercent()); + + if (status == PtrFrameLayout.PTR_STATUS_PREPARE) { + mDrawable.setAlpha((int) (255 * percent)); + mDrawable.showArrow(true); + + float strokeStart = ((percent) * .8f); + mDrawable.setStartEndTrim(0f, Math.min(0.8f, strokeStart)); + mDrawable.setArrowScale(Math.min(1f, percent)); + + // magic + float rotation = (-0.25f + .4f * percent + percent * 2) * .5f; + mDrawable.setProgressRotation(rotation); + invalidate(); + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/MaterialProgressDrawable.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/MaterialProgressDrawable.java new file mode 100644 index 00000000..34315302 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/MaterialProgressDrawable.java @@ -0,0 +1,795 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.insraincubeptr.header; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.RadialGradient; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Shader; +import android.graphics.drawable.Animatable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.OvalShape; +import android.os.Build; +import android.util.DisplayMetrics; +import android.view.View; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.Animation; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; +import android.view.animation.Transformation; + +import java.util.ArrayList; + +import com.insraincubeptr.util.PtrLocalDisplay; + + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +/** + * Fancy progress indicator for Material theme. + * It's taken from {@link android.support.v4.widget}. + * I've done some slight changes. + * + */ +public class MaterialProgressDrawable extends Drawable implements Animatable { + + // Maps to ProgressBar.Large style + public static final int LARGE = 0; + // Maps to ProgressBar default style + public static final int DEFAULT = 1; + private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator(); + private static final Interpolator END_CURVE_INTERPOLATOR = new EndCurveInterpolator(); + private static final Interpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator(); + private static final Interpolator EASE_INTERPOLATOR = new AccelerateDecelerateInterpolator(); + // Maps to ProgressBar default style + private static final int CIRCLE_DIAMETER = 40; + private static final float CENTER_RADIUS = 8.75f; //should add up to 10 when + stroke_width + private static final float STROKE_WIDTH = 2.5f; + // Maps to ProgressBar.Large style + private static final int CIRCLE_DIAMETER_LARGE = 56; + private static final float CENTER_RADIUS_LARGE = 12.5f; + private static final float STROKE_WIDTH_LARGE = 3f; + /** + * The duration of a single progress spin in milliseconds. + */ + private static final int ANIMATION_DURATION = 1000 * 80 / 60; + /** + * The number of points in the progress "star". + */ + private static final float NUM_POINTS = 5f; + /** + * Layout info for the arrowhead in dp + */ + private static final int ARROW_WIDTH = 10; + private static final int ARROW_HEIGHT = 5; + private static final float ARROW_OFFSET_ANGLE = 5; + /** + * Layout info for the arrowhead for the large spinner in dp + */ + private static final int ARROW_WIDTH_LARGE = 12; + private static final int ARROW_HEIGHT_LARGE = 6; + private static final float MAX_PROGRESS_ARC = .8f; + private static final int KEY_SHADOW_COLOR = 0x1E000000; + private static final int FILL_SHADOW_COLOR = 0x3D000000; + private static final float SHADOW_RADIUS = 3.5f; + private static final float X_OFFSET = 0f; + private static final float Y_OFFSET = 1.75f; + private final int[] COLORS = new int[]{ + 0xFFC93437, + 0xFF375BF1, + 0xFFF7D23E, + 0xFF34A350 + }; + /** + * The list of animators operating on this drawable. + */ + private final ArrayList mAnimators = new ArrayList(); + /** + * The indicator ring, used to manage animation state. + */ + private final Ring mRing; + private final Callback mCallback = new Callback() { + @Override + public void invalidateDrawable(Drawable d) { + invalidateSelf(); + } + + @Override + public void scheduleDrawable(Drawable d, Runnable what, long when) { + scheduleSelf(what, when); + } + + @Override + public void unscheduleDrawable(Drawable d, Runnable what) { + unscheduleSelf(what); + } + }; + /** + * Canvas rotation in degrees. + */ + private float mRotation; + private Resources mResources; + private View mParent; + private Animation mAnimation; + private float mRotationCount; + private double mWidth; + private double mHeight; + private Animation mFinishAnimation; + private int mBackgroundColor; + private ShapeDrawable mShadow; + + public MaterialProgressDrawable(Context context, View parent) { + mParent = parent; + mResources = context.getResources(); + mRing = new Ring(mCallback); + mRing.setColors(COLORS); + updateSizes(DEFAULT); + setupAnimators(); + } + + private void setSizeParameters(double progressCircleWidth, double progressCircleHeight, + double centerRadius, double strokeWidth, float arrowWidth, float arrowHeight) { + final Ring ring = mRing; + final DisplayMetrics metrics = mResources.getDisplayMetrics(); + final float screenDensity = metrics.density; + mWidth = progressCircleWidth * screenDensity; + mHeight = progressCircleHeight * screenDensity; + ring.setStrokeWidth((float) strokeWidth * screenDensity); + ring.setCenterRadius(centerRadius * screenDensity); + ring.setColorIndex(0); + ring.setArrowDimensions(arrowWidth * screenDensity, arrowHeight * screenDensity); + ring.setInsets((int) mWidth, (int) mHeight); + setUp(mWidth); + } + + private void setUp(final double diameter) { + PtrLocalDisplay.init(mParent.getContext()); + final int shadowYOffset = PtrLocalDisplay.dp2px(Y_OFFSET); + final int shadowXOffset = PtrLocalDisplay.dp2px(X_OFFSET); + int mShadowRadius = PtrLocalDisplay.dp2px(SHADOW_RADIUS); + OvalShape oval = new OvalShadow(mShadowRadius, (int) diameter); + mShadow = new ShapeDrawable(oval); + if (Build.VERSION.SDK_INT >= 11) { + mParent.setLayerType(View.LAYER_TYPE_SOFTWARE, mShadow.getPaint()); + } + mShadow.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset, KEY_SHADOW_COLOR); + } + + /** + * Set the overall size for the progress spinner. This updates the radius + * and stroke width of the ring. + * + * @param size One of {@link MaterialProgressDrawable#LARGE} or + * {@link MaterialProgressDrawable#DEFAULT} + */ + public void updateSizes(int size) { + if (size == LARGE) { + setSizeParameters(CIRCLE_DIAMETER_LARGE, CIRCLE_DIAMETER_LARGE, CENTER_RADIUS_LARGE, + STROKE_WIDTH_LARGE, ARROW_WIDTH_LARGE, ARROW_HEIGHT_LARGE); + } else { + setSizeParameters(CIRCLE_DIAMETER, CIRCLE_DIAMETER, CENTER_RADIUS, STROKE_WIDTH, + ARROW_WIDTH, ARROW_HEIGHT); + } + } + + /** + * @param show Set to true to display the arrowhead on the progress spinner. + */ + public void showArrow(boolean show) { + mRing.setShowArrow(show); + } + + /** + * @param scale Set the scale of the arrowhead for the spinner. + */ + public void setArrowScale(float scale) { + mRing.setArrowScale(scale); + } + + /** + * Set the start and end trim for the progress spinner arc. + * + * @param startAngle start angle + * @param endAngle end angle + */ + public void setStartEndTrim(float startAngle, float endAngle) { + mRing.setStartTrim(startAngle); + mRing.setEndTrim(endAngle); + } + + /** + * Set the amount of rotation to apply to the progress spinner. + * + * @param rotation Rotation is from [0..1] + */ + public void setProgressRotation(float rotation) { + mRing.setRotation(rotation); + } + + /** + * Update the background color of the circle image view. + * + * @param color object + */ + public void setBackgroundColor(int color) { + mBackgroundColor = color; + mRing.setBackgroundColor(color); + } + + /** + * Set the colors used in the progress animation from color resources. + * The first color will also be the color of the bar that grows in response + * to a user swipe gesture. + * + * @param colors na + */ + public void setColorSchemeColors(int... colors) { + mRing.setColors(colors); + mRing.setColorIndex(0); + } + + @Override + public int getIntrinsicHeight() { + return (int) mHeight; + } + + @Override + public int getIntrinsicWidth() { + return (int) mWidth; + } + + @Override + public void draw(Canvas c) { + if (mShadow != null) { + mShadow.getPaint().setColor(mBackgroundColor); + mShadow.draw(c); + } + + final Rect bounds = getBounds(); + final int saveCount = c.save(); + c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY()); + mRing.draw(c, bounds); + c.restoreToCount(saveCount); + } + + public int getAlpha() { + return mRing.getAlpha(); + } + + @Override + public void setAlpha(int alpha) { + mRing.setAlpha(alpha); + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + mRing.setColorFilter(colorFilter); + } + + @SuppressWarnings("unused") + private float getRotation() { + return mRotation; + } + + @SuppressWarnings("unused") + void setRotation(float rotation) { + mRotation = rotation; + invalidateSelf(); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public boolean isRunning() { + final ArrayList animators = mAnimators; + final int N = animators.size(); + for (int i = 0; i < N; i++) { + final Animation animator = animators.get(i); + if (animator.hasStarted() && !animator.hasEnded()) { + return true; + } + } + return false; + } + + @Override + public void start() { + mAnimation.reset(); + mRing.storeOriginals(); + // Already showing some part of the ring + if (mRing.getEndTrim() != mRing.getStartTrim()) { + mParent.startAnimation(mFinishAnimation); + } else { + mRing.setColorIndex(0); + mRing.resetOriginals(); + mParent.startAnimation(mAnimation); + } + } + + @Override + public void stop() { + mParent.clearAnimation(); + setRotation(0); + mRing.setShowArrow(false); + mRing.setColorIndex(0); + mRing.resetOriginals(); + } + + private void setupAnimators() { + final Ring ring = mRing; + final Animation finishRingAnimation = new Animation() { + public void applyTransformation(float interpolatedTime, Transformation t) { + // shrink back down and complete a full rotation before starting other circles + // Rotation goes between [0..1]. + float targetRotation = (float) (Math.floor(ring.getStartingRotation() + / MAX_PROGRESS_ARC) + 1f); + final float startTrim = ring.getStartingStartTrim() + + (ring.getStartingEndTrim() - ring.getStartingStartTrim()) + * interpolatedTime; + ring.setStartTrim(startTrim); + final float rotation = ring.getStartingRotation() + + ((targetRotation - ring.getStartingRotation()) * interpolatedTime); + ring.setRotation(rotation); + ring.setArrowScale(1 - interpolatedTime); + } + }; + finishRingAnimation.setInterpolator(EASE_INTERPOLATOR); + finishRingAnimation.setDuration(ANIMATION_DURATION / 2); + finishRingAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + ring.goToNextColor(); + ring.storeOriginals(); + ring.setShowArrow(false); + mParent.startAnimation(mAnimation); + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + }); + final Animation animation = new Animation() { + @Override + public void applyTransformation(float interpolatedTime, Transformation t) { + // The minProgressArc is calculated from 0 to create an angle that + // matches the stroke width. + final float minProgressArc = (float) Math.toRadians(ring.getStrokeWidth() + / (2 * Math.PI * ring.getCenterRadius())); + final float startingEndTrim = ring.getStartingEndTrim(); + final float startingTrim = ring.getStartingStartTrim(); + final float startingRotation = ring.getStartingRotation(); + // Offset the minProgressArc to where the endTrim is located. + final float minArc = MAX_PROGRESS_ARC - minProgressArc; + final float endTrim = startingEndTrim + + (minArc * START_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime)); + ring.setEndTrim(endTrim); + final float startTrim = startingTrim + + (MAX_PROGRESS_ARC * END_CURVE_INTERPOLATOR + .getInterpolation(interpolatedTime)); + ring.setStartTrim(startTrim); + final float rotation = startingRotation + (0.25f * interpolatedTime); + ring.setRotation(rotation); + float groupRotation = ((720.0f / NUM_POINTS) * interpolatedTime) + + (720.0f * (mRotationCount / NUM_POINTS)); + setRotation(groupRotation); + } + }; + animation.setRepeatCount(Animation.INFINITE); + animation.setRepeatMode(Animation.RESTART); + animation.setInterpolator(LINEAR_INTERPOLATOR); + animation.setDuration(ANIMATION_DURATION); + animation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + mRotationCount = 0; + } + + @Override + public void onAnimationEnd(Animation animation) { + // do nothing + } + + @Override + public void onAnimationRepeat(Animation animation) { + ring.storeOriginals(); + ring.goToNextColor(); + ring.setStartTrim(ring.getEndTrim()); + mRotationCount = (mRotationCount + 1) % (NUM_POINTS); + } + }); + mFinishAnimation = finishRingAnimation; + mAnimation = animation; + } + + private static class Ring { + private final RectF mTempBounds = new RectF(); + private final Paint mArcPaint = new Paint(); + private final Paint mArrowPaint = new Paint(); + private final Callback mRingCallback; + private final Paint mCirclePaint = new Paint(); + private float mStartTrim = 0.0f; + private float mEndTrim = 0.0f; + private float mRotation = 0.0f; + private float mStrokeWidth = 5.0f; + private float mStrokeInset = 2.5f; + private int[] mColors; + // mColorIndex represents the offset into the available mColors that the + // progress circle should currently display. As the progress circle is + // animating, the mColorIndex moves by one to the next available color. + private int mColorIndex; + private float mStartingStartTrim; + private float mStartingEndTrim; + private float mStartingRotation; + private boolean mShowArrow; + private Path mArrow; + private float mArrowScale; + private double mRingCenterRadius; + private int mArrowWidth; + private int mArrowHeight; + private int mAlpha; + private int mBackgroundColor; + + public Ring(Callback callback) { + mRingCallback = callback; + mArcPaint.setStrokeCap(Paint.Cap.SQUARE); + mArcPaint.setAntiAlias(true); + mArcPaint.setStyle(Style.STROKE); + mArrowPaint.setStyle(Style.FILL); + mArrowPaint.setAntiAlias(true); + + mCirclePaint.setAntiAlias(true); + } + + public void setBackgroundColor(int color) { + mBackgroundColor = color; + } + + /** + * Set the dimensions of the arrowhead. + * + * @param width Width of the hypotenuse of the arrow head + * @param height Height of the arrow point + */ + public void setArrowDimensions(float width, float height) { + mArrowWidth = (int) width; + mArrowHeight = (int) height; + } + + /** + * Draw the progress spinner + * + * @param c object + * @param bounds object + */ + public void draw(Canvas c, Rect bounds) { + + mCirclePaint.setColor(mBackgroundColor); + mCirclePaint.setAlpha(mAlpha); + + c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2, mCirclePaint); + + final RectF arcBounds = mTempBounds; + arcBounds.set(bounds); + arcBounds.inset(mStrokeInset, mStrokeInset); + final float startAngle = (mStartTrim + mRotation) * 360; + final float endAngle = (mEndTrim + mRotation) * 360; + float sweepAngle = endAngle - startAngle; + mArcPaint.setColor(mColors[mColorIndex]); + mArcPaint.setAlpha(mAlpha); + c.drawArc(arcBounds, startAngle, sweepAngle, false, mArcPaint); + drawTriangle(c, startAngle, sweepAngle, bounds); + } + + private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) { + if (mShowArrow) { + if (mArrow == null) { + mArrow = new Path(); + mArrow.setFillType(Path.FillType.EVEN_ODD); + } else { + mArrow.reset(); + } + // Adjust the position of the triangle so that it is inset as + // much as the arc, but also centered on the arc. + float inset = (int) mStrokeInset / 2 * mArrowScale; + float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX()); + float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY()); + // Update the path each time. This works around an issue in SKIA + // where concatenating a rotation matrix to a scale matrix + // ignored a starting negative rotation. This appears to have + // been fixed as of API 21. + mArrow.moveTo(0, 0); + mArrow.lineTo(mArrowWidth * mArrowScale, 0); + mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight + * mArrowScale)); + mArrow.offset(x - inset, y); + mArrow.close(); + // draw a triangle + mArrowPaint.setColor(mColors[mColorIndex]); + mArrowPaint.setAlpha(mAlpha); + c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(), + bounds.exactCenterY()); + c.drawPath(mArrow, mArrowPaint); + } + } + + /** + * Set the colors the progress spinner alternates between. + * + * @param colors Array of integers describing the colors. Must be non-null. + */ + public void setColors(int[] colors) { + mColors = colors; + // if colors are reset, make sure to reset the color index as well + setColorIndex(0); + } + + /** + * @param index Index into the color array of the color to display in + * the progress spinner. + */ + public void setColorIndex(int index) { + mColorIndex = index; + } + + /** + * Proceed to the next available ring color. This will automatically + * wrap back to the beginning of colors. + */ + public void goToNextColor() { + mColorIndex = (mColorIndex + 1) % (mColors.length); + } + + public void setColorFilter(ColorFilter filter) { + mArcPaint.setColorFilter(filter); + invalidateSelf(); + } + + /** + * @return Current alpha of the progress spinner and arrowhead. + */ + public int getAlpha() { + return mAlpha; + } + + /** + * @param alpha Set the alpha of the progress spinner and associated arrowhead. + */ + public void setAlpha(int alpha) { + mAlpha = alpha; + } + + @SuppressWarnings("unused") + public float getStrokeWidth() { + return mStrokeWidth; + } + + /** + * @param strokeWidth Set the stroke width of the progress spinner in pixels. + */ + public void setStrokeWidth(float strokeWidth) { + mStrokeWidth = strokeWidth; + mArcPaint.setStrokeWidth(strokeWidth); + invalidateSelf(); + } + + @SuppressWarnings("unused") + public float getStartTrim() { + return mStartTrim; + } + + @SuppressWarnings("unused") + public void setStartTrim(float startTrim) { + mStartTrim = startTrim; + invalidateSelf(); + } + + public float getStartingStartTrim() { + return mStartingStartTrim; + } + + public float getStartingEndTrim() { + return mStartingEndTrim; + } + + @SuppressWarnings("unused") + public float getEndTrim() { + return mEndTrim; + } + + @SuppressWarnings("unused") + public void setEndTrim(float endTrim) { + mEndTrim = endTrim; + invalidateSelf(); + } + + @SuppressWarnings("unused") + public float getRotation() { + return mRotation; + } + + @SuppressWarnings("unused") + public void setRotation(float rotation) { + mRotation = rotation; + invalidateSelf(); + } + + public void setInsets(int width, int height) { + final float minEdge = (float) Math.min(width, height); + float insets; + if (mRingCenterRadius <= 0 || minEdge < 0) { + insets = (float) Math.ceil(mStrokeWidth / 2.0f); + } else { + insets = (float) (minEdge / 2.0f - mRingCenterRadius); + } + mStrokeInset = insets; + } + + @SuppressWarnings("unused") + public float getInsets() { + return mStrokeInset; + } + + public double getCenterRadius() { + return mRingCenterRadius; + } + + /** + * @param centerRadius Inner radius in px of the circle the progress + * spinner arc traces. + */ + public void setCenterRadius(double centerRadius) { + mRingCenterRadius = centerRadius; + } + + /** + * @param show Set to true to show the arrow head on the progress spinner. + */ + public void setShowArrow(boolean show) { + if (mShowArrow != show) { + mShowArrow = show; + invalidateSelf(); + } + } + + /** + * @param scale Set the scale of the arrowhead for the spinner. + */ + public void setArrowScale(float scale) { + if (scale != mArrowScale) { + mArrowScale = scale; + invalidateSelf(); + } + } + + /** + * @return The amount the progress spinner is currently rotated, between [0..1]. + */ + public float getStartingRotation() { + return mStartingRotation; + } + + /** + * If the start / end trim are offset to begin with, store them so that + * animation starts from that offset. + */ + public void storeOriginals() { + mStartingStartTrim = mStartTrim; + mStartingEndTrim = mEndTrim; + mStartingRotation = mRotation; + } + + /** + * Reset the progress spinner to default rotation, start and end angles. + */ + public void resetOriginals() { + mStartingStartTrim = 0; + mStartingEndTrim = 0; + mStartingRotation = 0; + setStartTrim(0); + setEndTrim(0); + setRotation(0); + } + + private void invalidateSelf() { + mRingCallback.invalidateDrawable(null); + } + } + + /** + * Squishes the interpolation curve into the second half of the animation. + */ + private static class EndCurveInterpolator extends AccelerateDecelerateInterpolator { + @Override + public float getInterpolation(float input) { + return super.getInterpolation(Math.max(0, (input - 0.5f) * 2.0f)); + } + } + + /** + * Squishes the interpolation curve into the first half of the animation. + */ + private static class StartCurveInterpolator extends AccelerateDecelerateInterpolator { + @Override + public float getInterpolation(float input) { + return super.getInterpolation(Math.min(1, input * 2.0f)); + } + } + + /** + * Taken from {@link package android.support.v4.widget} + */ + private class OvalShadow extends OvalShape { + private RadialGradient mRadialGradient; + private int mShadowRadius; + private Paint mShadowPaint; + private int mCircleDiameter; + + public OvalShadow(int shadowRadius, int circleDiameter) { + super(); + mShadowPaint = new Paint(); + mShadowRadius = shadowRadius; + mCircleDiameter = circleDiameter; + mRadialGradient = new RadialGradient(mCircleDiameter / 2, mCircleDiameter / 2, + mShadowRadius, new int[]{ + FILL_SHADOW_COLOR, Color.TRANSPARENT + }, null, Shader.TileMode.CLAMP); + mShadowPaint.setShader(mRadialGradient); + } + + @Override + public void draw(Canvas canvas, Paint paint) { + final int viewWidth = getBounds().width(); + final int viewHeight = getBounds().height(); + canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2 + mShadowRadius), + mShadowPaint); + canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2), paint); + } + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHouseBarItem.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHouseBarItem.java new file mode 100644 index 00000000..d3d9f2bc --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHouseBarItem.java @@ -0,0 +1,93 @@ +package com.insraincubeptr.header; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PointF; +import android.view.animation.Animation; +import android.view.animation.Transformation; + +import java.util.Random; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +/** + * Created by srain on 11/6/14. + */ +public class StoreHouseBarItem extends Animation { + + public PointF midPoint; + public float translationX; + public int index; + + private final Paint mPaint = new Paint(); + private float mFromAlpha = 1.0f; + private float mToAlpha = 0.4f; + private PointF mCStartPoint; + private PointF mCEndPoint; + + public StoreHouseBarItem(int index, PointF start, PointF end, int color, int lineWidth) { + this.index = index; + + midPoint = new PointF((start.x + end.x) / 2, (start.y + end.y) / 2); + + mCStartPoint = new PointF(start.x - midPoint.x, start.y - midPoint.y); + mCEndPoint = new PointF(end.x - midPoint.x, end.y - midPoint.y); + + setColor(color); + setLineWidth(lineWidth); + mPaint.setAntiAlias(true); + mPaint.setStyle(Paint.Style.STROKE); + } + + public void setLineWidth(int width) { + mPaint.setStrokeWidth(width); + } + + public void setColor(int color) { + mPaint.setColor(color); + } + + public void resetPosition(int horizontalRandomness) { + Random random = new Random(); + int randomNumber = -random.nextInt(horizontalRandomness) + horizontalRandomness; + translationX = randomNumber; + } + + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + float alpha = mFromAlpha; + alpha = alpha + ((mToAlpha - alpha) * interpolatedTime); + setAlpha(alpha); + } + + public void start(float fromAlpha, float toAlpha) { + mFromAlpha = fromAlpha; + mToAlpha = toAlpha; + super.start(); + } + + public void setAlpha(float alpha) { + mPaint.setAlpha((int) (alpha * 255)); + } + + public void draw(Canvas canvas) { + canvas.drawLine(mCStartPoint.x, mCStartPoint.y, mCEndPoint.x, mCEndPoint.y, mPaint); + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHouseHeader.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHouseHeader.java new file mode 100644 index 00000000..749e5f68 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHouseHeader.java @@ -0,0 +1,352 @@ +package com.insraincubeptr.header; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.PointF; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.Transformation; + +import java.util.ArrayList; + +import com.insraincubeptr.PtrFrameLayout; +import com.insraincubeptr.PtrUIHandler; +import com.insraincubeptr.indicator.PtrIndicator; +import com.insraincubeptr.util.PtrLocalDisplay; + + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public class StoreHouseHeader extends View implements PtrUIHandler { + + public ArrayList mItemList = new ArrayList(); + + private int mLineWidth = -1; + private float mScale = 1; + private int mDropHeight = -1; + private float mInternalAnimationFactor = 0.7f; + private int mHorizontalRandomness = -1; + + private float mProgress = 0; + + private int mDrawZoneWidth = 0; + private int mDrawZoneHeight = 0; + private int mOffsetX = 0; + private int mOffsetY = 0; + private float mBarDarkAlpha = 0.4f; + private float mFromAlpha = 1.0f; + private float mToAlpha = 0.4f; + + private int mLoadingAniDuration = 1000; + private int mLoadingAniSegDuration = 1000; + private int mLoadingAniItemDuration = 400; + + private Transformation mTransformation = new Transformation(); + private boolean mIsInLoading = false; + private AniController mAniController = new AniController(); + private int mTextColor = Color.WHITE; + + public StoreHouseHeader(Context context) { + super(context); + initView(); + } + + public StoreHouseHeader(Context context, AttributeSet attrs) { + super(context, attrs); + initView(); + } + + public StoreHouseHeader(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(); + } + + private void initView() { + PtrLocalDisplay.init(getContext()); + mLineWidth = PtrLocalDisplay.dp2px(1); + mDropHeight = PtrLocalDisplay.dp2px(40); + mHorizontalRandomness = PtrLocalDisplay.SCREEN_WIDTH_PIXELS / 2; + } + + private void setProgress(float progress) { + mProgress = progress; + } + + public int getLoadingAniDuration() { + return mLoadingAniDuration; + } + + public void setLoadingAniDuration(int duration) { + mLoadingAniDuration = duration; + mLoadingAniSegDuration = duration; + } + + public StoreHouseHeader setLineWidth(int width) { + mLineWidth = width; + for (int i = 0; i < mItemList.size(); i++) { + mItemList.get(i).setLineWidth(width); + } + return this; + } + + public StoreHouseHeader setTextColor(int color) { + mTextColor = color; + for (int i = 0; i < mItemList.size(); i++) { + mItemList.get(i).setColor(color); + } + return this; + } + + public StoreHouseHeader setDropHeight(int height) { + mDropHeight = height; + return this; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int height = getTopOffset() + mDrawZoneHeight + getBottomOffset(); + heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + mOffsetX = (getMeasuredWidth() - mDrawZoneWidth) / 2; + mOffsetY = getTopOffset(); + mDropHeight = getTopOffset(); + } + + private int getTopOffset() { + return getPaddingTop() + PtrLocalDisplay.dp2px(10); + } + + private int getBottomOffset() { + return getPaddingBottom() + PtrLocalDisplay.dp2px(10); + } + + public void initWithString(String str) { + initWithString(str, 25); + } + + public void initWithString(String str, int fontSize) { + ArrayList pointList = StoreHousePath.getPath(str, fontSize * 0.01f, 14); + initWithPointList(pointList); + } + + public void initWithStringArray(int id) { + String[] points = getResources().getStringArray(id); + ArrayList pointList = new ArrayList(); + for (int i = 0; i < points.length; i++) { + String[] x = points[i].split(","); + float[] f = new float[4]; + for (int j = 0; j < 4; j++) { + f[j] = Float.parseFloat(x[j]); + } + pointList.add(f); + } + initWithPointList(pointList); + } + + public float getScale() { + return mScale; + } + + public void setScale(float scale) { + mScale = scale; + } + + public void initWithPointList(ArrayList pointList) { + + float drawWidth = 0; + float drawHeight = 0; + boolean shouldLayout = mItemList.size() > 0; + mItemList.clear(); + for (int i = 0; i < pointList.size(); i++) { + float[] line = pointList.get(i); + PointF startPoint = new PointF(PtrLocalDisplay.dp2px(line[0]) * mScale, PtrLocalDisplay.dp2px(line[1]) * mScale); + PointF endPoint = new PointF(PtrLocalDisplay.dp2px(line[2]) * mScale, PtrLocalDisplay.dp2px(line[3]) * mScale); + + drawWidth = Math.max(drawWidth, startPoint.x); + drawWidth = Math.max(drawWidth, endPoint.x); + + drawHeight = Math.max(drawHeight, startPoint.y); + drawHeight = Math.max(drawHeight, endPoint.y); + + StoreHouseBarItem item = new StoreHouseBarItem(i, startPoint, endPoint, mTextColor, mLineWidth); + item.resetPosition(mHorizontalRandomness); + mItemList.add(item); + } + mDrawZoneWidth = (int) Math.ceil(drawWidth); + mDrawZoneHeight = (int) Math.ceil(drawHeight); + if (shouldLayout) { + requestLayout(); + } + } + + private void beginLoading() { + mIsInLoading = true; + mAniController.start(); + invalidate(); + } + + private void loadFinish() { + mIsInLoading = false; + mAniController.stop(); + } + + @Override + public void onDraw(Canvas canvas) { + super.onDraw(canvas); + float progress = mProgress; + int c1 = canvas.save(); + int len = mItemList.size(); + + for (int i = 0; i < len; i++) { + + canvas.save(); + StoreHouseBarItem storeHouseBarItem = mItemList.get(i); + float offsetX = mOffsetX + storeHouseBarItem.midPoint.x; + float offsetY = mOffsetY + storeHouseBarItem.midPoint.y; + + if (mIsInLoading) { + storeHouseBarItem.getTransformation(getDrawingTime(), mTransformation); + canvas.translate(offsetX, offsetY); + } else { + + if (progress == 0) { + storeHouseBarItem.resetPosition(mHorizontalRandomness); + continue; + } + + float startPadding = (1 - mInternalAnimationFactor) * i / len; + float endPadding = 1 - mInternalAnimationFactor - startPadding; + + // done + if (progress == 1 || progress >= 1 - endPadding) { + canvas.translate(offsetX, offsetY); + storeHouseBarItem.setAlpha(mBarDarkAlpha); + } else { + float realProgress; + if (progress <= startPadding) { + realProgress = 0; + } else { + realProgress = Math.min(1, (progress - startPadding) / mInternalAnimationFactor); + } + offsetX += storeHouseBarItem.translationX * (1 - realProgress); + offsetY += -mDropHeight * (1 - realProgress); + Matrix matrix = new Matrix(); + matrix.postRotate(360 * realProgress); + matrix.postScale(realProgress, realProgress); + matrix.postTranslate(offsetX, offsetY); + storeHouseBarItem.setAlpha(mBarDarkAlpha * realProgress); + canvas.concat(matrix); + } + } + storeHouseBarItem.draw(canvas); + canvas.restore(); + } + if (mIsInLoading) { + invalidate(); + } + canvas.restoreToCount(c1); + } + + @Override + public void onUIReset(PtrFrameLayout frame) { + loadFinish(); + for (int i = 0; i < mItemList.size(); i++) { + mItemList.get(i).resetPosition(mHorizontalRandomness); + + } + } + + @Override + public void onUIRefreshPrepare(PtrFrameLayout frame) { + + } + + @Override + public void onUIRefreshBegin(PtrFrameLayout frame) { + beginLoading(); + } + + @Override + public void onUIRefreshComplete(PtrFrameLayout frame) { + loadFinish(); + } + + @Override + public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) { + + float currentPercent = Math.min(1f, ptrIndicator.getCurrentPercent()); + setProgress(currentPercent); + invalidate(); + } + + private class AniController implements Runnable { + + private int mTick = 0; + private int mCountPerSeg = 0; + private int mSegCount = 0; + private int mInterval = 0; + private boolean mRunning = true; + + private void start() { + mRunning = true; + mTick = 0; + + mInterval = mLoadingAniDuration / mItemList.size(); + mCountPerSeg = mLoadingAniSegDuration / mInterval; + mSegCount = mItemList.size() / mCountPerSeg + 1; + run(); + } + + @Override + public void run() { + + int pos = mTick % mCountPerSeg; + for (int i = 0; i < mSegCount; i++) { + + int index = i * mCountPerSeg + pos; + if (index > mTick) { + continue; + } + + index = index % mItemList.size(); + StoreHouseBarItem item = mItemList.get(index); + + item.setFillAfter(false); + item.setFillEnabled(true); + item.setFillBefore(false); + item.setDuration(mLoadingAniItemDuration); + item.start(mFromAlpha, mToAlpha); + } + + mTick++; + if (mRunning) { + postDelayed(this, mInterval); + } + } + + private void stop() { + mRunning = false; + removeCallbacks(this); + } + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHousePath.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHousePath.java new file mode 100644 index 00000000..da9a3f98 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/header/StoreHousePath.java @@ -0,0 +1,388 @@ +package com.insraincubeptr.header; + +import android.util.SparseArray; + +import java.util.ArrayList; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +/** + * Created by srain on 11/7/14. + */ +public class StoreHousePath { + + private static final SparseArray sPointList; + + static { + sPointList = new SparseArray(); + float[][] LETTERS = new float[][]{ + new float[]{ + // A + 24, 0, 1, 22, + 1, 22, 1, 72, + 24, 0, 47, 22, + 47, 22, 47, 72, + 1, 48, 47, 48 + }, + + new float[]{ + // B + 0, 0, 0, 72, + 0, 0, 37, 0, + 37, 0, 47, 11, + 47, 11, 47, 26, + 47, 26, 38, 36, + 38, 36, 0, 36, + 38, 36, 47, 46, + 47, 46, 47, 61, + 47, 61, 38, 71, + 37, 72, 0, 72, + }, + + new float[]{ + // C + 47, 0, 0, 0, + 0, 0, 0, 72, + 0, 72, 47, 72, + }, + + new float[]{ + // D + 0, 0, 0, 72, + 0, 0, 24, 0, + 24, 0, 47, 22, + 47, 22, 47, 48, + 47, 48, 23, 72, + 23, 72, 0, 72, + }, + + new float[]{ + // E + 0, 0, 0, 72, + 0, 0, 47, 0, + 0, 36, 37, 36, + 0, 72, 47, 72, + }, + + new float[]{ + // F + 0, 0, 0, 72, + 0, 0, 47, 0, + 0, 36, 37, 36, + }, + + new float[]{ + // G + 47, 23, 47, 0, + 47, 0, 0, 0, + 0, 0, 0, 72, + 0, 72, 47, 72, + 47, 72, 47, 48, + 47, 48, 24, 48, + }, + + new float[]{ + // H + 0, 0, 0, 72, + 0, 36, 47, 36, + 47, 0, 47, 72, + }, + + new float[]{ + // I + 0, 0, 47, 0, + 24, 0, 24, 72, + 0, 72, 47, 72, + }, + + new float[]{ + // J + 47, 0, 47, 72, + 47, 72, 24, 72, + 24, 72, 0, 48, + }, + + new float[]{ + // K + 0, 0, 0, 72, + 47, 0, 3, 33, + 3, 38, 47, 72, + }, + + new float[]{ + // L + 0, 0, 0, 72, + 0, 72, 47, 72, + }, + + new float[]{ + // M + 0, 0, 0, 72, + 0, 0, 24, 23, + 24, 23, 47, 0, + 47, 0, 47, 72, + }, + + new float[]{ + // N + 0, 0, 0, 72, + 0, 0, 47, 72, + 47, 72, 47, 0, + }, + + new float[]{ + // O + 0, 0, 0, 72, + 0, 72, 47, 72, + 47, 72, 47, 0, + 47, 0, 0, 0, + }, + + new float[]{ + // P + 0, 0, 0, 72, + 0, 0, 47, 0, + 47, 0, 47, 36, + 47, 36, 0, 36, + }, + + new float[]{ + // Q + 0, 0, 0, 72, + 0, 72, 23, 72, + 23, 72, 47, 48, + 47, 48, 47, 0, + 47, 0, 0, 0, + 24, 28, 47, 71, + }, + + new float[]{ + // R + 0, 0, 0, 72, + 0, 0, 47, 0, + 47, 0, 47, 36, + 47, 36, 0, 36, + 0, 37, 47, 72, + }, + + new float[]{ + // S + 47, 0, 0, 0, + 0, 0, 0, 36, + 0, 36, 47, 36, + 47, 36, 47, 72, + 47, 72, 0, 72, + }, + + new float[]{ + // T + 0, 0, 47, 0, + 24, 0, 24, 72, + }, + + new float[]{ + // U + 0, 0, 0, 72, + 0, 72, 47, 72, + 47, 72, 47, 0, + }, + + new float[]{ + // V + 0, 0, 24, 72, + 24, 72, 47, 0, + }, + + new float[]{ + // W + 0, 0, 0, 72, + 0, 72, 24, 49, + 24, 49, 47, 72, + 47, 72, 47, 0 + }, + + new float[]{ + // X + 0, 0, 47, 72, + 47, 0, 0, 72 + }, + + new float[]{ + // Y + 0, 0, 24, 23, + 47, 0, 24, 23, + 24, 23, 24, 72 + }, + + new float[]{ + // Z + 0, 0, 47, 0, + 47, 0, 0, 72, + 0, 72, 47, 72 + }, + }; + final float[][] NUMBERS = new float[][]{ + new float[]{ + // 0 + 0, 0, 0, 72, + 0, 72, 47, 72, + 47, 72, 47, 0, + 47, 0, 0, 0, + }, + new float[]{ + // 1 + 24, 0, 24, 72, + }, + + new float[]{ + // 2 + 0, 0, 47, 0, + 47, 0, 47, 36, + 47, 36, 0, 36, + 0, 36, 0, 72, + 0, 72, 47, 72 + }, + + new float[]{ + // 3 + 0, 0, 47, 0, + 47, 0, 47, 36, + 47, 36, 0, 36, + 47, 36, 47, 72, + 47, 72, 0, 72, + }, + + new float[]{ + // 4 + 0, 0, 0, 36, + 0, 36, 47, 36, + 47, 0, 47, 72, + }, + + new float[]{ + // 5 + 0, 0, 0, 36, + 0, 36, 47, 36, + 47, 36, 47, 72, + 47, 72, 0, 72, + 0, 0, 47, 0 + }, + + new float[]{ + // 6 + 0, 0, 0, 72, + 0, 72, 47, 72, + 47, 72, 47, 36, + 47, 36, 0, 36 + }, + + new float[]{ + // 7 + 0, 0, 47, 0, + 47, 0, 47, 72 + }, + + new float[]{ + // 8 + 0, 0, 0, 72, + 0, 72, 47, 72, + 47, 72, 47, 0, + 47, 0, 0, 0, + 0, 36, 47, 36 + }, + + new float[]{ + // 9 + 47, 0, 0, 0, + 0, 0, 0, 36, + 0, 36, 47, 36, + 47, 0, 47, 72, + } + }; + // A - Z + for (int i = 0; i < LETTERS.length; i++) { + sPointList.append(i + 65, LETTERS[i]); + } + // a - z + for (int i = 0; i < LETTERS.length; i++) { + sPointList.append(i + 65 + 32, LETTERS[i]); + } + // 0 - 9 + for (int i = 0; i < NUMBERS.length; i++) { + sPointList.append(i + 48, NUMBERS[i]); + } + // blank + addChar(' ', new float[]{}); + // - + addChar('-', new float[]{ + 0, 36, 47, 36 + }); + // . + addChar('.', new float[]{ + 24, 60, 24, 72 + }); + } + + public static void addChar(char c, float[] points) { + sPointList.append(c, points); + } + + public static ArrayList getPath(String str) { + return getPath(str, 1, 14); + } + + /** + * @param str na + * @param scale na + * @param gapBetweenLetter na + * @return ArrayList of float[] {x1, y1, x2, y2} + */ + public static ArrayList getPath(String str, float scale, int gapBetweenLetter) { + ArrayList list = new ArrayList(); + float offsetForWidth = 0; + for (int i = 0; i < str.length(); i++) { + int pos = str.charAt(i); + int key = sPointList.indexOfKey(pos); + if (key == -1) { + continue; + } + float[] points = sPointList.get(pos); + int pointCount = points.length / 4; + + for (int j = 0; j < pointCount; j++) { + float[] line = new float[4]; + for (int k = 0; k < 4; k++) { + float l = points[j * 4 + k]; + // x + if (k % 2 == 0) { + line[k] = (l + offsetForWidth) * scale; + } + // y + else { + line[k] = l * scale; + } + } + list.add(line); + } + offsetForWidth += 57 + gapBetweenLetter; + } + return list; + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/indicator/PtrIndicator.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/indicator/PtrIndicator.java new file mode 100644 index 00000000..795eee97 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/indicator/PtrIndicator.java @@ -0,0 +1,218 @@ +package com.insraincubeptr.indicator; + +import android.graphics.PointF; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public class PtrIndicator { + + public final static int POS_START = 0; + protected int mOffsetToRefresh = 0; + private PointF mPtLastMove = new PointF(); + private float mOffsetX; + private float mOffsetY; + private int mCurrentPos = 0; + private int mLastPos = 0; + private int mHeaderHeight; + private int mPressedPos = 0; + + private float mRatioOfHeaderHeightToRefresh = 1.2f; + private float mResistance = 1.7f; + private boolean mIsUnderTouch = false; + private int mOffsetToKeepHeaderWhileLoading = -1; + // record the refresh complete position + private int mRefreshCompleteY = 0; + + public boolean isUnderTouch() { + return mIsUnderTouch; + } + + public float getResistance() { + return mResistance; + } + + public void setResistance(float resistance) { + mResistance = resistance; + } + + public void onRelease() { + mIsUnderTouch = false; + } + + public void onUIRefreshComplete() { + mRefreshCompleteY = mCurrentPos; + } + + public boolean goDownCrossFinishPosition() { + return mCurrentPos >= mRefreshCompleteY; + } + + protected void processOnMove(float currentX, float currentY, float offsetX, float offsetY) { + setOffset(offsetX, offsetY / mResistance); + } + + public void setRatioOfHeaderHeightToRefresh(float ratio) { + mRatioOfHeaderHeightToRefresh = ratio; + mOffsetToRefresh = (int) (mHeaderHeight * ratio); + } + + public float getRatioOfHeaderToHeightRefresh() { + return mRatioOfHeaderHeightToRefresh; + } + + public int getOffsetToRefresh() { + return mOffsetToRefresh; + } + + public void setOffsetToRefresh(int offset) { + mRatioOfHeaderHeightToRefresh = mHeaderHeight * 1f / offset; + mOffsetToRefresh = offset; + } + + public void onPressDown(float x, float y) { + mIsUnderTouch = true; + mPressedPos = mCurrentPos; + mPtLastMove.set(x, y); + } + + public final void onMove(float x, float y) { + float offsetX = x - mPtLastMove.x; + float offsetY = (y - mPtLastMove.y); + processOnMove(x, y, offsetX, offsetY); + mPtLastMove.set(x, y); + } + + protected void setOffset(float x, float y) { + mOffsetX = x; + mOffsetY = y; + } + + public float getOffsetX() { + return mOffsetX; + } + + public float getOffsetY() { + return mOffsetY; + } + + public int getLastPosY() { + return mLastPos; + } + + public int getCurrentPosY() { + return mCurrentPos; + } + + /** + * Update current position before update the UI + * + * @param current na + */ + public final void setCurrentPos(int current) { + mLastPos = mCurrentPos; + mCurrentPos = current; + onUpdatePos(current, mLastPos); + } + + protected void onUpdatePos(int current, int last) { + + } + + public int getHeaderHeight() { + return mHeaderHeight; + } + + public void setHeaderHeight(int height) { + mHeaderHeight = height; + updateHeight(); + } + + protected void updateHeight() { + mOffsetToRefresh = (int) (mRatioOfHeaderHeightToRefresh * mHeaderHeight); + } + + public void convertFrom(PtrIndicator ptrSlider) { + mCurrentPos = ptrSlider.mCurrentPos; + mLastPos = ptrSlider.mLastPos; + mHeaderHeight = ptrSlider.mHeaderHeight; + } + + public boolean hasLeftStartPosition() { + return mCurrentPos > POS_START; + } + + public boolean hasJustLeftStartPosition() { + return mLastPos == POS_START && hasLeftStartPosition(); + } + + public boolean hasJustBackToStartPosition() { + return mLastPos != POS_START && isInStartPosition(); + } + + public boolean isOverOffsetToRefresh() { + return mCurrentPos >= getOffsetToRefresh(); + } + + public boolean hasMovedAfterPressedDown() { + return mCurrentPos != mPressedPos; + } + + public boolean isInStartPosition() { + return mCurrentPos == POS_START; + } + + public boolean crossRefreshLineFromTopToBottom() { + return mLastPos < getOffsetToRefresh() && mCurrentPos >= getOffsetToRefresh(); + } + + public boolean hasJustReachedHeaderHeightFromTopToBottom() { + return mLastPos < mHeaderHeight && mCurrentPos >= mHeaderHeight; + } + + public boolean isOverOffsetToKeepHeaderWhileLoading() { + return mCurrentPos > getOffsetToKeepHeaderWhileLoading(); + } + + public void setOffsetToKeepHeaderWhileLoading(int offset) { + mOffsetToKeepHeaderWhileLoading = offset; + } + + public int getOffsetToKeepHeaderWhileLoading() { + return mOffsetToKeepHeaderWhileLoading >= 0 ? mOffsetToKeepHeaderWhileLoading : mHeaderHeight; + } + + public boolean isAlreadyHere(int to) { + return mCurrentPos == to; + } + + public float getLastPercent() { + final float oldPercent = mHeaderHeight == 0 ? 0 : mLastPos * 1f / mHeaderHeight; + return oldPercent; + } + + public float getCurrentPercent() { + final float currentPercent = mHeaderHeight == 0 ? 0 : mCurrentPos * 1f / mHeaderHeight; + return currentPercent; + } + + public boolean willOverTop(int to) { + return to < POS_START; + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/indicator/PtrTensionIndicator.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/indicator/PtrTensionIndicator.java new file mode 100644 index 00000000..f8a40b7c --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/indicator/PtrTensionIndicator.java @@ -0,0 +1,138 @@ +package com.insraincubeptr.indicator; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public class PtrTensionIndicator extends PtrIndicator { + + private float DRAG_RATE = 0.5f; + private float mDownY; + private float mDownPos; + private float mOneHeight = 0; + + private float mCurrentDragPercent; + + private int mReleasePos; + private float mReleasePercent = -1; + + @Override + public void onPressDown(float x, float y) { + super.onPressDown(x, y); + mDownY = y; + mDownPos = getCurrentPosY(); + } + + @Override + public void onRelease() { + super.onRelease(); + mReleasePos = getCurrentPosY(); + mReleasePercent = mCurrentDragPercent; + } + + @Override + public void onUIRefreshComplete() { + mReleasePos = getCurrentPosY(); + mReleasePercent = getOverDragPercent(); + } + + @Override + public void setHeaderHeight(int height) { + super.setHeaderHeight(height); + mOneHeight = height * 4f / 5; + } + + @Override + protected void processOnMove(float currentX, float currentY, float offsetX, float offsetY) { + + if (currentY < mDownY) { + super.processOnMove(currentX, currentY, offsetX, offsetY); + return; + } + + // distance from top + final float scrollTop = (currentY - mDownY) * DRAG_RATE + mDownPos; + final float currentDragPercent = scrollTop / mOneHeight; + + if (currentDragPercent < 0) { + setOffset(offsetX, 0); + return; + } + + mCurrentDragPercent = currentDragPercent; + + // 0 ~ 1 + float boundedDragPercent = Math.min(1f, Math.abs(currentDragPercent)); + float extraOS = scrollTop - mOneHeight; + + // 0 ~ 2 + // if extraOS lower than 0, which means scrollTop lower than onHeight, tensionSlingshotPercent will be 0. + float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, mOneHeight * 2) / mOneHeight); + + float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f; + float extraMove = (mOneHeight) * tensionPercent / 2; + int targetY = (int) ((mOneHeight * boundedDragPercent) + extraMove); + int change = targetY - getCurrentPosY(); + + setOffset(currentX, change); + } + + private float offsetToTarget(float scrollTop) { + + // distance from top + final float currentDragPercent = scrollTop / mOneHeight; + + mCurrentDragPercent = currentDragPercent; + + // 0 ~ 1 + float boundedDragPercent = Math.min(1f, Math.abs(currentDragPercent)); + float extraOS = scrollTop - mOneHeight; + + // 0 ~ 2 + // if extraOS lower than 0, which means scrollTop lower than mOneHeight, tensionSlingshotPercent will be 0. + float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, mOneHeight * 2) / mOneHeight); + + float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f; + float extraMove = (mOneHeight) * tensionPercent / 2; + int targetY = (int) ((mOneHeight * boundedDragPercent) + extraMove); + + return 0; + } + + @Override + public int getOffsetToKeepHeaderWhileLoading() { + return getOffsetToRefresh(); + } + + @Override + public int getOffsetToRefresh() { + return (int) mOneHeight; + } + + public float getOverDragPercent() { + if (isUnderTouch()) { + return mCurrentDragPercent; + } else { + if (mReleasePercent <= 0) { + return 1.0f * getCurrentPosY() / getOffsetToKeepHeaderWhileLoading(); + } + // after release + return mReleasePercent * getCurrentPosY() / mReleasePos; + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/util/PtrCLog.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/util/PtrCLog.java new file mode 100644 index 00000000..e77cbaaf --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/util/PtrCLog.java @@ -0,0 +1,312 @@ +package com.insraincubeptr.util; + +import android.util.Log; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +/** + * An encapsulation of {@link Log}, enable log level and print log with parameters. + * + * @author http://www.liaohuqiu.net/ + */ +public class PtrCLog { + + public static final int LEVEL_VERBOSE = 0; + public static final int LEVEL_DEBUG = 1; + public static final int LEVEL_INFO = 2; + public static final int LEVEL_WARNING = 3; + public static final int LEVEL_ERROR = 4; + public static final int LEVEL_FATAL = 5; + + private static int sLevel = LEVEL_VERBOSE; + + /** + * set log level, the level lower than this level will not be logged + * + * @param level object + */ + public static void setLogLevel(int level) { + sLevel = level; + } + + /** + * Send a VERBOSE log message. + * + * @param tag object + * @param msg object + */ + public static void v(String tag, String msg) { + if (sLevel > LEVEL_VERBOSE) { + return; + } + Log.v(tag, msg); + } + + /** + * Send a VERBOSE log message. + * + * @param tag object + * @param msg object + * @param throwable object + */ + public static void v(String tag, String msg, Throwable throwable) { + if (sLevel > LEVEL_VERBOSE) { + return; + } + Log.v(tag, msg, throwable); + } + + /** + * Send a VERBOSE log message. + * + * @param tag object + * @param msg object + * @param args object + */ + public static void v(String tag, String msg, Object... args) { + if (sLevel > LEVEL_VERBOSE) { + return; + } + if (args.length > 0) { + msg = String.format(msg, args); + } + Log.v(tag, msg); + } + + /** + * Send a DEBUG log message + * + * @param tag object + * @param msg object + */ + public static void d(String tag, String msg) { + if (sLevel > LEVEL_DEBUG) { + return; + } + Log.d(tag, msg); + } + + /** + * Send a DEBUG log message + * + * @param tag object + * @param msg object + * @param args object + */ + public static void d(String tag, String msg, Object... args) { + if (sLevel > LEVEL_DEBUG) { + return; + } + if (args.length > 0) { + msg = String.format(msg, args); + } + Log.d(tag, msg); + } + + /** + * Send a DEBUG log message + * + * @param tag na + * @param msg na + * @param throwable na + */ + public static void d(String tag, String msg, Throwable throwable) { + if (sLevel > LEVEL_DEBUG) { + return; + } + Log.d(tag, msg, throwable); + } + + /** + * Send an INFO log message + * + * @param tag na + * @param msg na + */ + public static void i(String tag, String msg) { + if (sLevel > LEVEL_INFO) { + return; + } + Log.i(tag, msg); + } + + /** + * Send an INFO log message + * + * @param tag na + * @param msg na + * @param args na + */ + public static void i(String tag, String msg, Object... args) { + if (sLevel > LEVEL_INFO) { + return; + } + if (args.length > 0) { + msg = String.format(msg, args); + } + Log.i(tag, msg); + } + + /** + * Send an INFO log message + * + * @param tag object + * @param msg object + * @param throwable object + */ + public static void i(String tag, String msg, Throwable throwable) { + if (sLevel > LEVEL_INFO) { + return; + } + Log.i(tag, msg, throwable); + } + + /** + * Send a WARNING log message + * + * @param tag na + * @param msg na + */ + public static void w(String tag, String msg) { + if (sLevel > LEVEL_WARNING) { + return; + } + Log.w(tag, msg); + } + + /** + * Send a WARNING log message + * + * @param tag na + * @param msg na + * @param args na + */ + public static void w(String tag, String msg, Object... args) { + if (sLevel > LEVEL_WARNING) { + return; + } + if (args.length > 0) { + msg = String.format(msg, args); + } + Log.w(tag, msg); + } + + /** + * Send a WARNING log message + * + * @param tag na + * @param msg na + * @param throwable na + */ + public static void w(String tag, String msg, Throwable throwable) { + if (sLevel > LEVEL_WARNING) { + return; + } + Log.w(tag, msg, throwable); + } + + /** + * Send an ERROR log message + * + * @param tag na + * @param msg na + */ + public static void e(String tag, String msg) { + if (sLevel > LEVEL_ERROR) { + return; + } + Log.e(tag, msg); + } + + /** + * Send an ERROR log message + * + * @param tag na + * @param msg na + * @param args na + */ + public static void e(String tag, String msg, Object... args) { + if (sLevel > LEVEL_ERROR) { + return; + } + if (args.length > 0) { + msg = String.format(msg, args); + } + Log.e(tag, msg); + } + + /** + * Send an ERROR log message + * + * @param tag na + * @param msg na + * @param throwable na + */ + public static void e(String tag, String msg, Throwable throwable) { + if (sLevel > LEVEL_ERROR) { + return; + } + Log.e(tag, msg, throwable); + } + + /** + * Send a FATAL ERROR log message + * + * @param tag na + * @param msg na + */ + public static void f(String tag, String msg) { + if (sLevel > LEVEL_FATAL) { + return; + } + Log.wtf(tag, msg); + } + + /** + * Send a FATAL ERROR log message + * + * @param tag na + * @param msg na + * @param args na + */ + public static void f(String tag, String msg, Object... args) { + if (sLevel > LEVEL_FATAL) { + return; + } + if (args.length > 0) { + msg = String.format(msg, args); + } + Log.wtf(tag, msg); + } + + /** + * Send a FATAL ERROR log message + * + * @param tag na + * @param msg na + * @param throwable na + */ + public static void f(String tag, String msg, Throwable throwable) { + if (sLevel > LEVEL_FATAL) { + return; + } + Log.wtf(tag, msg, throwable); + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/util/PtrLocalDisplay.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/util/PtrLocalDisplay.java new file mode 100644 index 00000000..9c901d13 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/insraincubeptr/util/PtrLocalDisplay.java @@ -0,0 +1,64 @@ +package com.insraincubeptr.util; + +import android.content.Context; +import android.util.DisplayMetrics; +import android.view.View; +import android.view.WindowManager; + +/* + * Copyright 2016 https://github.com/liaohuqiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * from https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh + * + */ + +public class PtrLocalDisplay { + + public static int SCREEN_WIDTH_PIXELS; + public static int SCREEN_HEIGHT_PIXELS; + public static float SCREEN_DENSITY; + public static int SCREEN_WIDTH_DP; + public static int SCREEN_HEIGHT_DP; + + public static void init(Context context) { + if (context == null) { + return; + } + DisplayMetrics dm = new DisplayMetrics(); + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + wm.getDefaultDisplay().getMetrics(dm); + SCREEN_WIDTH_PIXELS = dm.widthPixels; + SCREEN_HEIGHT_PIXELS = dm.heightPixels; + SCREEN_DENSITY = dm.density; + SCREEN_WIDTH_DP = (int) (SCREEN_WIDTH_PIXELS / dm.density); + SCREEN_HEIGHT_DP = (int) (SCREEN_HEIGHT_PIXELS / dm.density); + } + + public static int dp2px(float dp) { + final float scale = SCREEN_DENSITY; + return (int) (dp * scale + 0.5f); + } + + public static int designedDP2px(float designedDp) { + if (SCREEN_WIDTH_DP != 320) { + designedDp = designedDp * SCREEN_WIDTH_DP / 320f; + } + return dp2px(designedDp); + } + + public static void setPadding(final View view, float left, float top, float right, float bottom) { + view.setPadding(designedDP2px(left), dp2px(top), designedDP2px(right), dp2px(bottom)); + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/CustomUltimateRecyclerview.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/CustomUltimateRecyclerview.java deleted file mode 100644 index 72b10857..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/CustomUltimateRecyclerview.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.marshalchen.ultimaterecyclerview; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewStub; - -import com.marshalchen.ultimaterecyclerview.ui.VerticalSwipeRefreshLayout; -import com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton.FloatingActionButton; - -import in.srain.cube.views.ptr.PtrFrameLayout; - -/** - * Created by cym on 15/3/21. - */ -public class CustomUltimateRecyclerview extends UltimateRecyclerView { - - public PtrFrameLayout mPtrFrameLayout; - - public CustomUltimateRecyclerview(Context context) { - super(context); - } - - public CustomUltimateRecyclerview(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public CustomUltimateRecyclerview(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - protected void initViews() { - //super.initViews(); - LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.custom_recycler_view_layout, this); - mRecyclerView = (RecyclerView) view.findViewById(R.id.ultimate_list); - mSwipeRefreshLayout = null; - - if (mRecyclerView != null) { - - mRecyclerView.setClipToPadding(mClipToPadding); - if (mPadding != -1.1f) { - mRecyclerView.setPadding(mPadding, mPadding, mPadding, mPadding); - } else { - mRecyclerView.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); - } - } - - defaultFloatingActionButton = (FloatingActionButton) view.findViewById(R.id.defaultFloatingActionButton); - setDefaultScrollListener(); - - mEmpty = (ViewStub) view.findViewById(R.id.emptyview); - mFloatingButtonViewStub = (ViewStub) view.findViewById(R.id.floatingActionViewStub); - - mEmpty.setLayoutResource(mEmptyId); - - mFloatingButtonViewStub.setLayoutResource(mFloatingButtonId); - - if (mEmptyId != 0) - mEmptyView = mEmpty.inflate(); - mEmpty.setVisibility(View.GONE); - - if (mFloatingButtonId != 0) { - mFloatingButtonView = mFloatingButtonViewStub.inflate(); - mFloatingButtonView.setVisibility(View.VISIBLE); - } - - } - - public void setCustomSwipeToRefresh() { - mPtrFrameLayout = (PtrFrameLayout) findViewById(R.id.store_house_ptr_frame); - mPtrFrameLayout.setResistance(1.7f); - mPtrFrameLayout.setRatioOfHeaderHeightToRefresh(1.2f); - mPtrFrameLayout.setDurationToClose(200); - mPtrFrameLayout.setDurationToCloseHeader(1000); - mPtrFrameLayout.setPullToRefresh(false); - mPtrFrameLayout.setKeepHeaderWhenRefresh(true); - } - -} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/NormalUltimateViewAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/NormalUltimateViewAdapter.java deleted file mode 100644 index 058eb32d..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/NormalUltimateViewAdapter.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.marshalchen.ultimaterecyclerview; - -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.annotation.TargetApi; -import android.os.Build; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.ViewGroup; - -import com.marshalchen.ultimaterecyclerview.itemTouchHelper.ItemTouchHelperAdapter; -import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter; - -import java.util.Collections; -import java.util.List; - -/** - * An abstract adapter which can be extended for Recyclerview - */ -public abstract class NormalUltimateViewAdapter extends RecyclerView.Adapter - implements StickyRecyclerHeadersAdapter, ItemTouchHelperAdapter { - - - protected View customLoadMoreView = null; - - /** - * Set the header view of the adapter. - * - * @param customHeaderView na - */ - public void setCustomHeaderView(UltimateRecyclerView.CustomRelativeWrapper customHeaderView) { - this.customHeaderView = customHeaderView; - } - - public UltimateRecyclerView.CustomRelativeWrapper getCustomHeaderView() { - return customHeaderView; - } - - protected UltimateRecyclerView.CustomRelativeWrapper customHeaderView = null; - - @Override - public UltimateRecyclerviewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - if (viewType == VIEW_TYPES.FOOTER) { - UltimateRecyclerviewViewHolder viewHolder = new UltimateRecyclerviewViewHolder(customLoadMoreView); - if (getAdapterItemCount() == 0) - viewHolder.itemView.setVisibility(View.GONE); - return viewHolder; - } else if (viewType == VIEW_TYPES.HEADER) { - if (customHeaderView != null) - return new UltimateRecyclerviewViewHolder(customHeaderView); - } else if (viewType == VIEW_TYPES.CHANGED_FOOTER) { - UltimateRecyclerviewViewHolder viewHolder = new UltimateRecyclerviewViewHolder(customLoadMoreView); - if (getAdapterItemCount() == 0) - viewHolder.itemView.setVisibility(View.GONE); - return viewHolder; - } -// else if (viewType==VIEW_TYPES.STICKY_HEADER){ -// return new UltimateRecyclerviewViewHolder(LayoutInflater.from(parent.getContext()) -// .inflate(R.layout.stick_header_item, parent, false)); -// } - - return onCreateViewHolder(parent); - - } - - - public abstract UltimateRecyclerviewViewHolder onCreateViewHolder(ViewGroup parent); - - /** - * Using a custom LoadMoreView - * - * @param customview the inflated view - */ - public void setCustomLoadMoreView(View customview) { - customLoadMoreView = customview; - } - - /** - * Changing the loadmore view - * - * @param customview the inflated view - */ - public void swipeCustomLoadMoreView(View customview) { - customLoadMoreView = customview; - isLoadMoreChanged = true; - } - - public View getCustomLoadMoreView() { - return customLoadMoreView; - } - - public boolean isLoadMoreChanged = false; - - @Override - public int getItemViewType(int position) { - if (position == getItemCount() - 1 && customLoadMoreView != null) { - if (isLoadMoreChanged) { - return VIEW_TYPES.CHANGED_FOOTER; - } else { - return VIEW_TYPES.FOOTER; - } - - - } else if (position == 0 && customHeaderView != null) { - return VIEW_TYPES.HEADER; - } else - return VIEW_TYPES.NORMAL; - } - - - /** - * Returns the total number of items in the data set hold by the adapter. - * - * @return The total number of items in this adapter. - */ - @Override - public int getItemCount() { - int headerOrFooter = 0; - if (customHeaderView != null) headerOrFooter++; - if (customLoadMoreView != null) headerOrFooter++; - return getAdapterItemCount() + headerOrFooter; - } - - /** - * Returns the number of items in the adapter bound to the parent RecyclerView. - * - * @return The number of items in the bound adapter - */ - public abstract int getAdapterItemCount(); - - public void toggleSelection(int pos) { - notifyItemChanged(pos); - } - - public void clearSelection(int pos) { - notifyItemChanged(pos); - } - - public void setSelected(int pos) { - notifyItemChanged(pos); - } - - /** - * Swap the item of list - * - * @param list data list - * @param from position from - * @param to position to - */ - public void swapPositions(List list, int from, int to) { - if (customHeaderView != null) { - from--; - to--; - } - Collections.swap(list, from, to); - } - - - /** - * Insert a item to the list of the adapter - * - * @param list data list - * @param object object T - * @param position position - * @param in T - */ - public void insert(List list, T object, int position) { - list.add(position, object); - if (customHeaderView != null) position++; - notifyItemInserted(position); - } - - /** - * Remove a item of the list of the adapter - * - * @param list data list - * @param position position - */ - public void remove(List list, int position) { - if (list.size() > 0) { - list.remove(customHeaderView != null ? position - 1 : position); - notifyItemRemoved(position); - } - } - - /** - * Clear the list of the adapter - * - * @param list data list - */ - public void clear(List list) { - int size = list.size(); - list.clear(); - notifyItemRangeRemoved(0, size); - } - - @Override - public long getHeaderId(int position) { - if (customHeaderView != null && position == 0) return -1; - if (customLoadMoreView != null && position >= getItemCount() - 1) return -1; - if (getAdapterItemCount() > 0) - return generateHeaderId(position); - else return -1; - } - - public abstract long generateHeaderId(int position); - - - protected class VIEW_TYPES { - public static final int NORMAL = 0; - public static final int HEADER = 1; - public static final int FOOTER = 2; - public static final int CHANGED_FOOTER = 3; - } - - protected enum AdapterAnimationType { - AlphaIn, - SlideInBottom, - ScaleIn, - SlideInLeft, - SlideInRight, - } - - /** - * Animations when loading the adapter - * - * @param view the view - * @param type the type of the animation - * @return the animator in array - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - protected Animator[] getAdapterAnimations(View view, AdapterAnimationType type) { - if (type == AdapterAnimationType.ScaleIn) { - ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", .5f, 1f); - ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", .5f, 1f); - return new ObjectAnimator[]{scaleX, scaleY}; - } else if (type == AdapterAnimationType.AlphaIn) { - return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", .5f, 1f)}; - } else if (type == AdapterAnimationType.SlideInBottom) { - return new Animator[]{ - ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0) - }; - } else if (type == AdapterAnimationType.SlideInLeft) { - return new Animator[]{ - ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0) - }; - } else if (type == AdapterAnimationType.SlideInRight) { - return new Animator[]{ - ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0) - }; - } - return null; - } - - @Override - public void onItemMove(int fromPosition, int toPosition) { - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onItemDismiss(int position) { - notifyDataSetChanged(); - } - - - protected OnStartDragListener mDragStartListener = null; - - /** - * Listener for manual initiation of a drag. - */ - public interface OnStartDragListener { - - /** - * Called when a view is requesting a start of a drag. - * - * @param viewHolder The holder of the view to drag. - */ - void onStartDrag(RecyclerView.ViewHolder viewHolder); - } -} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/Scrollable.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/Scrollable.java index c59f6deb..f7ae9fe2 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/Scrollable.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/Scrollable.java @@ -5,7 +5,7 @@ import com.marshalchen.ultimaterecyclerview.ObservableScrollViewCallbacks; /** - * Provides common API for observable and scrollable widgets. + * Provides com.ml93.kp.common API for observable and scrollable widgets. */ public interface Scrollable { /** diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeDismissTouchListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeDismissTouchListener.java deleted file mode 100755 index 9a80321a..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeDismissTouchListener.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.marshalchen.ultimaterecyclerview; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; - -@Deprecated -public class SwipeDismissTouchListener implements View.OnTouchListener { - // Cached ViewConfiguration and system-wide constant values - private int mSlop; - private int mMinFlingVelocity; - private int mMaxFlingVelocity; - private long mAnimationTime; - - // Fixed properties - private View mView; - private SwipeDismissCallbacks mCallbacks; - private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero - - // Transient properties - private float mDownX; - private float mDownY; - private boolean mSwiping; - private int mSwipingSlop; - private Object mToken; - private VelocityTracker mVelocityTracker; - private float mTranslationX; - - /** - * The callback interface used by {@link com.marshalchen.ultimaterecyclerview.SwipeDismissTouchListener} to inform its client - * about a successful dismissal of the view for which it was created. - */ - public interface SwipeDismissCallbacks { - /** - * Called to determine whether the view can be dismissed. - * - * @param token na - * @return na - */ - boolean canDismiss(Object token); - - /** - * Called when the user has indicated they she would like to dismiss the view. - * - * @param view The originating {@link android.view.View} to be dismissed. - * @param token The optional token passed to this object's constructor. - */ - void onDismiss(View view, Object token); - } - - /** - * Constructs a new swipe-to-dismiss touch listener for the given view. - * - * @param view The view to make dismissable. - * @param token An optional token/cookie object to be passed through to the callback. - * @param callbacks The callback to trigger when the user has indicated that she would like to - * dismiss this view. - */ - public SwipeDismissTouchListener(View view, Object token, SwipeDismissCallbacks callbacks) { - ViewConfiguration vc = ViewConfiguration.get(view.getContext()); - mSlop = vc.getScaledTouchSlop(); - mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16; - mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity(); - mAnimationTime = view.getContext().getResources().getInteger( - android.R.integer.config_shortAnimTime); - mView = view; - mToken = token; - mCallbacks = callbacks; - } - - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - // offset because the view is translated during swipe - motionEvent.offsetLocation(mTranslationX, 0); - - if (mViewWidth < 2) { - mViewWidth = mView.getWidth(); - } - - switch (motionEvent.getActionMasked()) { - case MotionEvent.ACTION_DOWN: { - // TODO: ensure this is a finger, and set a flag - mDownX = motionEvent.getRawX(); - mDownY = motionEvent.getRawY(); - if (mCallbacks.canDismiss(mToken)) { - mVelocityTracker = VelocityTracker.obtain(); - mVelocityTracker.addMovement(motionEvent); - } - return true; - } - - case MotionEvent.ACTION_UP: { - if (mVelocityTracker == null) { - break; - } - - float deltaX = motionEvent.getRawX() - mDownX; - mVelocityTracker.addMovement(motionEvent); - mVelocityTracker.computeCurrentVelocity(1000); - float velocityX = mVelocityTracker.getXVelocity(); - float absVelocityX = Math.abs(velocityX); - float absVelocityY = Math.abs(mVelocityTracker.getYVelocity()); - boolean dismiss = false; - boolean dismissRight = false; - if (Math.abs(deltaX) > mViewWidth / 2 && mSwiping) { - dismiss = true; - dismissRight = deltaX > 0; - } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity - && absVelocityY < absVelocityX - && absVelocityY < absVelocityX && mSwiping) { - // dismiss only if flinging in the same direction as dragging - dismiss = (velocityX < 0) == (deltaX < 0); - dismissRight = mVelocityTracker.getXVelocity() > 0; - } - if (dismiss) { - // dismiss - mView.animate() - .translationX(dismissRight ? mViewWidth : -mViewWidth) - .alpha(0) - .setDuration(mAnimationTime) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - performDismiss(); - } - }); - } else if (mSwiping) { - // cancel - mView.animate() - .translationX(0) - .alpha(1) - .setDuration(mAnimationTime) - .setListener(null); - } - mVelocityTracker.recycle(); - mVelocityTracker = null; - mTranslationX = 0; - mDownX = 0; - mDownY = 0; - mSwiping = false; - break; - } - - case MotionEvent.ACTION_CANCEL: { - if (mVelocityTracker == null) { - break; - } - - mView.animate() - .translationX(0) - .alpha(1) - .setDuration(mAnimationTime) - .setListener(null); - mVelocityTracker.recycle(); - mVelocityTracker = null; - mTranslationX = 0; - mDownX = 0; - mDownY = 0; - mSwiping = false; - break; - } - - case MotionEvent.ACTION_MOVE: { - if (mVelocityTracker == null) { - break; - } - - mVelocityTracker.addMovement(motionEvent); - float deltaX = motionEvent.getRawX() - mDownX; - float deltaY = motionEvent.getRawY() - mDownY; - if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { - mSwiping = true; - mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop); - mView.getParent().requestDisallowInterceptTouchEvent(true); - - // Cancel listview's touch - MotionEvent cancelEvent = MotionEvent.obtain(motionEvent); - cancelEvent.setAction(MotionEvent.ACTION_CANCEL | - (motionEvent.getActionIndex() << - MotionEvent.ACTION_POINTER_INDEX_SHIFT)); - mView.onTouchEvent(cancelEvent); - cancelEvent.recycle(); - } - - if (mSwiping) { - mTranslationX = deltaX; - mView.setTranslationX(deltaX - mSwipingSlop); - // TODO: use an ease-out interpolator or such - mView.setAlpha(Math.max(0f, Math.min(1f, - 1f - 2f * Math.abs(deltaX) / mViewWidth))); - return true; - } - break; - } - } - return false; - } - - private void performDismiss() { - // Animate the dismissed view to zero-height and then fire the dismiss callback. - // This triggers layout on each animation frame; in the future we may want to do something - // smarter and more performant. - URLogs.d("performDismiss"); - final ViewGroup.LayoutParams lp = mView.getLayoutParams(); - final int originalHeight = mView.getHeight(); - - ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime); - - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mCallbacks.onDismiss(mView, mToken); - // Reset view presentation - mView.setAlpha(1f); - mView.setTranslationX(0); - lp.height = originalHeight; - mView.setLayoutParams(lp); - } - }); - - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - lp.height = (Integer) valueAnimator.getAnimatedValue(); - // if (lp.height > 100) - mView.setLayoutParams(lp); - // mView.setVisibility(View.GONE); - } - }); - - animator.start(); - } -} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeableUltimateRecyclerview.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeableUltimateRecyclerview.java index cd063c9f..a5d600de 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeableUltimateRecyclerview.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/SwipeableUltimateRecyclerview.java @@ -1,33 +1,30 @@ package com.marshalchen.ultimaterecyclerview; import android.content.Context; -import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewStub; import com.marshalchen.ultimaterecyclerview.swipelistview.SwipeListView; import com.marshalchen.ultimaterecyclerview.swipelistview.SwipeListViewListener; -import com.marshalchen.ultimaterecyclerview.ui.VerticalSwipeRefreshLayout; -import com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton.FloatingActionButton; +import com.ml93.captainmiaoUtil.ui.VerticalSwipeRefreshLayout; /** * Created by MarshalChen on 15-6-5. */ -public class SwipeableUltimateRecyclerview extends UltimateRecyclerView { +public class SwipeableUltimateRecyclerview extends UltimateRecyclerView { public SwipeableUltimateRecyclerview(Context context) { super(context); } public SwipeableUltimateRecyclerview(Context context, AttributeSet attrs) { super(context, attrs); - ((SwipeListView)mRecyclerView).init(attrs); + ((SwipeListView) mRecyclerView).init(attrs); } public SwipeableUltimateRecyclerview(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - ((SwipeListView)mRecyclerView).init(attrs); + ((SwipeListView) mRecyclerView).init(attrs); } @Override @@ -36,7 +33,7 @@ protected void initViews() { View view = inflater.inflate(R.layout.swipeable_ultimate_recycler_view_layout, this); mRecyclerView = (SwipeListView) view.findViewById(R.id.ultimate_list); - mSwipeRefreshLayout = (VerticalSwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout); + mSwipeRefreshLayout = (VerticalSwipeRefreshLayout) view.findViewById(R.id.urv_vertical_swiperefresher); setScrollbars(); mSwipeRefreshLayout.setEnabled(false); @@ -49,30 +46,19 @@ protected void initViews() { mRecyclerView.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); } } - - defaultFloatingActionButton = (FloatingActionButton) view.findViewById(R.id.defaultFloatingActionButton); + //defaultFloatingActionButton = (FloatingActionButton) view.findViewById(R.id.defaultFloatingActionButton); setDefaultScrollListener(); - - mEmpty = (ViewStub) view.findViewById(R.id.emptyview); - mFloatingButtonViewStub = (ViewStub) view.findViewById(R.id.floatingActionViewStub); - - mEmpty.setLayoutResource(mEmptyId); - - mFloatingButtonViewStub.setLayoutResource(mFloatingButtonId); - - if (mEmptyId != 0) - mEmptyView = mEmpty.inflate(); - mEmpty.setVisibility(View.GONE); - - if (mFloatingButtonId != 0) { + //mEmpty = (ViewStub) view.findViewById(R.id.emptyview); + // mFloatingButtonViewStub = (ViewStub) view.findViewById(R.id.floatingActionViewStub); + // mEmpty.setLayoutResource(mEmptyId); + // mFloatingButtonViewStub.setLayoutResource(mFloatingButtonId); + /* if (mFloatingButtonId != 0) { mFloatingButtonView = mFloatingButtonViewStub.inflate(); mFloatingButtonView.setVisibility(View.VISIBLE); - } - - + }*/ } public void setSwipeListViewListener(SwipeListViewListener swipeListViewListener) { - ((SwipeListView)mRecyclerView).swipeListViewListener = swipeListViewListener; + ((SwipeListView) mRecyclerView).swipeListViewListener = swipeListViewListener; } } diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateDifferentViewTypeAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateDifferentViewTypeAdapter.java index 4f3fb120..b660e105 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateDifferentViewTypeAdapter.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateDifferentViewTypeAdapter.java @@ -27,13 +27,13 @@ public UltimateRecyclerviewViewHolder onCreateViewHolder(ViewGroup parent, int v // } else return getDataBinder(viewType).newViewHolder(parent); } - +/* @Override public void onBindViewHolder(UltimateRecyclerviewViewHolder viewHolder, int position) { //int binderPosition = getBinderPosition(position); getDataBinder(viewHolder.getItemViewType()).bindViewHolder(viewHolder, position); - } + }*/ @Override public int getItemCount() { diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateGridLayoutAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateGridLayoutAdapter.java deleted file mode 100644 index 90fb5eb0..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateGridLayoutAdapter.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.marshalchen.ultimaterecyclerview; - -import android.annotation.TargetApi; -import android.os.Build; -import android.support.annotation.LayoutRes; -import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; - -import java.util.List; - -/** - * Created by hesk on 27/1/16. - */ -public abstract class UltimateGridLayoutAdapter extends easyRegularAdapter { - private boolean mValid = true; - private int span_columns; - - public UltimateGridLayoutAdapter(List items) { - super(items); - span_columns = 1; - } - - public void setSpanColumns(int columns) { - span_columns = columns; - } - - - private int normalDataConv(final int rpos) { - int orgin = rpos; - int size = getAdapterItemCount(); - if (hasHeaderView()) orgin -= 1; - int out = orgin >= size - 1 ? size - 1 : orgin; - return out; - } - - - - protected View getViewById(@LayoutRes final int layoutId, ViewGroup parent) { - View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); - return view; - } - - @Override - public UltimateRecyclerviewViewHolder onCreateHeaderViewHolder(ViewGroup parent) { - return new UltimateRecyclerviewViewHolder(parent); - } - - @Override - public int getAdapterItemCount() { - return mValid ? super.getAdapterItemCount() : 0; - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - @Override - public long generateHeaderId(int position) { - return View.generateViewId(); - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - final int current_type = getItemViewType(position); - if (VIEW_TYPES.HEADER == current_type) { - onBindHeaderViewHolder(holder, position); - } else if (VIEW_TYPES.NORMAL == current_type) { - bindNormal((BINDER) holder, getItem(getItemDataPosFromInternalPos(position)), position); - } else if (VIEW_TYPES.FOOTER == current_type) { - onFooterCustomerization(holder, position); - } - } - - protected void onFooterCustomerization(RecyclerView.ViewHolder view, int position) { - - } - - /** - * normally you dont need to do anything for this implementation. - * - * @param holder the data holder - * @param position position to render - */ - @Override - public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder, int position) { - // Log.d("ascc", position + " : "); - } - - protected abstract void bindNormal(BINDER b, DATA data, final int position); - -} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerView.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerView.java index 5307c822..6013aeac 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerView.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerView.java @@ -20,13 +20,10 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Rect; import android.os.Build; import android.os.Parcelable; import android.support.annotation.ColorInt; import android.support.annotation.LayoutRes; -import android.support.annotation.Nullable; import android.support.v4.view.ViewCompat; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.GridLayoutManager; @@ -41,19 +38,23 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewStub; -import android.view.animation.TranslateAnimation; import android.widget.FrameLayout; import android.widget.RelativeLayout; -import com.marshalchen.ultimaterecyclerview.ui.DividerItemDecoration; -import com.marshalchen.ultimaterecyclerview.ui.VerticalSwipeRefreshLayout; -import com.marshalchen.ultimaterecyclerview.ui.emptyview.emptyViewOnShownListener; -import com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton.FloatingActionButton; -import com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton.FloatingActionsMenu; +import com.marshalchen.ultimaterecyclerview.expanx.LinearExpanxURVAdapter; +import com.marshalchen.ultimaterecyclerview.gridSection.SectionedRecyclerViewAdapter; +import com.marshalchen.ultimaterecyclerview.quickAdapter.AdmobAdapter; +import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; +import com.ml93.captainmiaoUtil.ui.DividerItemDecoration; +import com.ml93.captainmiaoUtil.ui.VerticalSwipeRefreshLayout; +import com.ml93.captainmiaoUtil.ui.emptyview.emptyViewOnShownListener; import com.marshalchen.ultimaterecyclerview.uiUtils.RecyclerViewPositionHelper; import com.marshalchen.ultimaterecyclerview.uiUtils.SavedStateScrolling; +import com.ml93.captainmiaoUtil.common.CustomRelativeWrapper; +import com.insraincubeptr.PtrFrameLayout; +import com.insraincubeptr.PtrHandler; + /** * UltimateRecyclerView is a recyclerview which contains many features like swipe to dismiss,animations,drag drop etc. @@ -75,7 +76,7 @@ public class UltimateRecyclerView extends FrameLayout implements Scrollable { private int policy_empty, policy_init; public RecyclerView mRecyclerView; - protected FloatingActionButton defaultFloatingActionButton; + // protected FloatingActionButton defaultFloatingActionButton; private OnLoadMoreListener onLoadMoreListener; private int lastVisibleItemPosition; protected RecyclerView.OnScrollListener mOnScrollListener; @@ -110,11 +111,12 @@ public class UltimateRecyclerView extends FrameLayout implements Scrollable { /** * custom load more progress bar */ - private View mLoadMoreView; + @LayoutRes + private int mLoadMoreView; /** * empty view group */ - protected ViewStub mEmpty; + protected RelativeLayout mEmptyViewContainer; protected View mEmptyView; protected int mEmptyId; protected emptyViewOnShownListener mEmptyViewListener; @@ -123,22 +125,19 @@ public class UltimateRecyclerView extends FrameLayout implements Scrollable { /** * the floating button group */ - protected ViewStub mFloatingButtonViewStub; protected View mFloatingButtonView; protected int mFloatingButtonId; protected int[] defaultSwipeToDismissColors = null; public int showLoadMoreItemNum = 3; - public VerticalSwipeRefreshLayout mSwipeRefreshLayout; private RecyclerViewPositionHelper mRecyclerViewHelper; private CustomRelativeWrapper mHeader; - private int mTotalYScrolled; + private final float SCROLL_MULTIPLIER = 0.5f; private OnParallaxScroll mParallaxScroll; - private static boolean isParallaxHeader = false; private LayoutInflater inflater; /** @@ -155,8 +154,12 @@ public class UltimateRecyclerView extends FrameLayout implements Scrollable { private int mVisibleItemCount = 0; private int mTotalItemCount = 0; private int previousTotal = 0; + private int refreshType = 0; private int mFirstVisibleItem; + public VerticalSwipeRefreshLayout mSwipeRefreshLayout; + public PtrFrameLayout mPtrFrameLayout; + public UltimateRecyclerView(Context context) { super(context); initViews(); @@ -178,14 +181,61 @@ public void setRecylerViewBackgroundColor(@ColorInt int color) { mRecyclerView.setBackgroundColor(color); } + private void initDefaultPtrSettings(View view) { + mPtrFrameLayout = (PtrFrameLayout) view.findViewById(R.id.urv_ptr_module); + mPtrFrameLayout.setResistance(1.7f); + mPtrFrameLayout.setRatioOfHeaderHeightToRefresh(1.2f); + mPtrFrameLayout.setDurationToClose(200); + mPtrFrameLayout.setDurationToCloseHeader(1000); + mPtrFrameLayout.setPullToRefresh(false); + mPtrFrameLayout.setKeepHeaderWhenRefresh(true); + } + + private void initDefaultSwipeRefreshLayout(View view) { + mSwipeRefreshLayout = (VerticalSwipeRefreshLayout) view.findViewById(R.id.urv_vertical_swiperefresher); + mSwipeRefreshLayout.setEnabled(false); + mSwipeRefreshLayout.setProgressViewEndTarget(false, 150); + } + + private void initSwipableDismissLayout(View view) { + // mSwipeRefreshLayout = (VerticalSwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout); + } + + private void initFloatingActionButton(View view) { + // defaultFloatingActionButton = (FloatingActionButton) view.findViewById(R.id.defaultFloatingActionButton); + } + + @LayoutRes + private int getLayoutId() { + if (refreshType == 1) { + return R.layout.urv_ptr; + } else if (refreshType == 2) { + return R.layout.urv_normal; + } else if (refreshType == 3) { + return R.layout.swipeable_ultimate_recycler_view_layout; + } else { + return R.layout.urv_normal; + } + } + + private void initRefresher(View view) { + if (refreshType == 1) { + initDefaultPtrSettings(view); + } else if (refreshType == 2) { + initDefaultSwipeRefreshLayout(view); + } else if (refreshType == 3) { + // initDefaultSwipeRefreshLayout(view); + } else { + initDefaultSwipeRefreshLayout(view); + } + } + protected void initViews() { inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.ultimate_recycler_view_layout, this); - mRecyclerView = (RecyclerView) view.findViewById(R.id.ultimate_list); - mSwipeRefreshLayout = (VerticalSwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout); + View view = inflater.inflate(getLayoutId(), this); + mRecyclerView = (RecyclerView) view.findViewById(R.id.urv_core); + initRefresher(view); setScrollbars(); - mSwipeRefreshLayout.setEnabled(false); - if (mRecyclerView != null) { mRecyclerView.setClipToPadding(mClipToPadding); if (mPadding != -1.1f) { @@ -194,34 +244,11 @@ protected void initViews() { mRecyclerView.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); } } - - defaultFloatingActionButton = (FloatingActionButton) view.findViewById(R.id.defaultFloatingActionButton); setDefaultScrollListener(); - /** * empty view setup */ - mEmpty = (ViewStub) view.findViewById(R.id.emptyview); - if (mEmptyId != 0) { - mEmpty.setLayoutResource(mEmptyId); - mEmptyView = mEmpty.inflate(); - mEmpty.setVisibility(View.GONE); - } - - /** - * floating button setup - */ - mFloatingButtonViewStub = (ViewStub) view.findViewById(R.id.floatingActionViewStub); - mFloatingButtonViewStub.setLayoutResource(mFloatingButtonId); - } - - /** - * retrieve the empty view from the core - * - * @return the view item - */ - public View getEmptyView() { - return mEmptyView; + mEmptyViewContainer = (RelativeLayout) view.findViewById(R.id.urv_empty_view_loc); } private void setPolicies(final int policyEmtpyView, final int policyInitialization) { @@ -236,51 +263,29 @@ public void setInflater(LayoutInflater inflater) { private void setEmptyView(@LayoutRes final int emptyResourceId) { if (mEmptyView == null && emptyResourceId > 0) { - mEmptyId = emptyResourceId; - mEmpty.setLayoutResource(emptyResourceId); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - mEmpty.setLayoutInflater(inflater); - } - mEmptyView = mEmpty.inflate(); + View container = inflater.inflate(emptyResourceId, null, false); + mEmptyView = container; + mEmptyViewContainer.addView(container); } else { Log.d(VIEW_LOG_TAG, "unabled to set empty view because the empty has been set"); } } - private void setEmptyView(@Nullable View mInflatedView) { - if (mInflatedView != null) - mEmptyView = mInflatedView; - } - - /** - * Set custom empty view.The view will be shown if the adapter is null or the size of the adapter is zero. - * You can customize it as loading view. - * - * @param emptyResourceId the Resource Id from the empty view - * @param emptyViewPolicy the Resource Id from the empty view - */ public final void setEmptyView(@LayoutRes int emptyResourceId, final int emptyViewPolicy) { - // mEmptyViewPolicy = emptyViewPolicy; setEmptyView(emptyResourceId); setPolicies(emptyViewPolicy, UltimateRecyclerView.STARTWITH_OFFLINE_ITEMS); - mEmpty.setVisibility(View.GONE); - } - - public final void setEmptyView(@LayoutRes int emptyResourceId, final int emptyViewPolicy, final int mEmptyViewInitPolicy) { - setEmptyView(emptyResourceId); - setPolicies(emptyViewPolicy, mEmptyViewInitPolicy); } - public final void setEmptyView(@LayoutRes int emptyResourceId, final int emptyViewPolicy, final emptyViewOnShownListener listener) { + public final void setEmptyView(@LayoutRes int emptyResourceId, final int emptyViewPolicy, final int emptyViewInitPolicy) { setEmptyView(emptyResourceId); - setPolicies(emptyViewPolicy, UltimateRecyclerView.STARTWITH_OFFLINE_ITEMS); - mEmptyViewListener = listener; + setPolicies(emptyViewPolicy, emptyViewInitPolicy); } - public final void setEmptyView(@LayoutRes int emptyResourceId, final int emptyViewPolicy, final int emptyViewInitPolicy, final emptyViewOnShownListener listener) { - setEmptyView(emptyResourceId); - setPolicies(emptyViewPolicy, emptyViewInitPolicy); - mEmptyViewListener = listener; + public void setOnBindEmptyView(final emptyViewOnShownListener onbind) { + mEmptyViewListener = onbind; + if (mEmptyView != null) { + onbind.onEmptyViewShow(mEmptyView); + } } /** @@ -289,56 +294,38 @@ public final void setEmptyView(@LayoutRes int emptyResourceId, final int emptyVi * * @return is the empty shown */ - public boolean showEmptyView() { - if (mEmpty != null && mEmptyView != null && mAdapter != null) { - if (mAdapter.getEmptyViewPolicy() == EMPTY_CLEAR_ALL || mAdapter.getEmptyViewPolicy() == EMPTY_KEEP_HEADER) { - mEmpty.setVisibility(View.VISIBLE); - if (mEmptyViewListener != null) { - mEmptyViewListener.onEmptyViewShow(mEmptyView); - } - } - return true; - } else { - Log.d(VIEW_LOG_TAG, "it is unable to show empty view"); - return false; - } + public View showEmptyView() { + mEmptyViewContainer.setVisibility(VISIBLE); + return mEmptyView; } /** * Hide the custom or default empty view */ public void hideEmptyView() { - if (mEmpty != null && mEmptyView != null) { - mEmpty.setVisibility(View.GONE); - } else { - Log.d(VIEW_LOG_TAG, "there is no such empty view"); - } - } - - public void setLoadMoreView(View mlayoutView) { - if (mLoadMoreView != null) { - Log.d(VIEW_LOG_TAG, "The loading more layout has already been initiated."); - return; - } - if (mlayoutView == null) { - mLoadMoreView = LayoutInflater.from(getContext()).inflate(R.layout.bottom_progressbar, null); - Log.d(VIEW_LOG_TAG, "Layout Resource view is null. This system will use the default loading view instead."); - } else { - mLoadMoreView = mlayoutView; + if (mEmptyViewContainer.getVisibility() != View.GONE) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + mEmptyViewContainer.animate().alpha(0).withEndAction(new Runnable() { + @Override + public void run() { + mEmptyViewContainer.setVisibility(View.GONE); + mEmptyViewContainer.setOnClickListener(null); + } + }); + } else { + mEmptyViewContainer.setVisibility(View.GONE); + mEmptyViewContainer.setOnClickListener(null); + } } } /** * setting up the loading more layout * - * @param layout the res layout + * @param layout_id the res layout */ - public void setLoadMoreView(@LayoutRes final int layout) { - if (layout > 0) { - mLoadMoreView = LayoutInflater.from(getContext()).inflate(layout, null); - } else { - Log.d(VIEW_LOG_TAG, "Layout Resource Id is not found for load more view for ulitmaterecyclerview"); - } + public void setLoadMoreView(@LayoutRes final int layout_id) { + mLoadMoreView = layout_id; } /** @@ -346,8 +333,6 @@ public void setLoadMoreView(@LayoutRes final int layout) { */ public void showFloatingButtonView() { if (mFloatingButtonId != 0 && mFloatingButtonView == null) { - mFloatingButtonView = mFloatingButtonViewStub.inflate(); - mFloatingButtonView.setVisibility(View.VISIBLE); } else { Log.d(VIEW_LOG_TAG, "floating button cannot be inflated because it has inflated already"); } @@ -387,6 +372,7 @@ protected void initAttrs(AttributeSet attrs) { mEmptyId = typedArray.getResourceId(R.styleable.UltimateRecyclerview_recyclerviewEmptyView, 0); mFloatingButtonId = typedArray.getResourceId(R.styleable.UltimateRecyclerview_recyclerviewFloatingActionView, 0); mScrollbarsStyle = typedArray.getInt(R.styleable.UltimateRecyclerview_recyclerviewScrollbars, SCROLLBARS_NONE); + refreshType = typedArray.getInt(R.styleable.UltimateRecyclerview_recyclerviewRefreshType, 2); int colorList = typedArray.getResourceId(R.styleable.UltimateRecyclerview_recyclerviewDefaultSwipeColor, 0); if (colorList != 0) { defaultSwipeToDismissColors = getResources().getIntArray(colorList); @@ -436,6 +422,7 @@ private void scroll_load_more_detection(RecyclerView recyclerView) { mFirstVisibleItem = mRecyclerViewHelper.findFirstVisibleItemPosition(); lastVisibleItemPosition = mRecyclerViewHelper.findLastVisibleItemPosition(); break; + case GRID: if (layoutManager instanceof GridLayoutManager) { GridLayoutManager ly = (GridLayoutManager) layoutManager; @@ -443,6 +430,7 @@ private void scroll_load_more_detection(RecyclerView recyclerView) { mFirstVisibleItem = ly.findFirstVisibleItemPosition(); } break; + case STAGGERED_GRID: if (layoutManager instanceof StaggeredGridLayoutManager) { StaggeredGridLayoutManager sy = (StaggeredGridLayoutManager) layoutManager; @@ -460,7 +448,6 @@ private void scroll_load_more_detection(RecyclerView recyclerView) { } if (automaticLoadMoreEnabled) { - if (mTotalItemCount > previousTotal) { automaticLoadMoreEnabled = false; previousTotal = mTotalItemCount; @@ -485,31 +472,51 @@ private void scroll_load_more_detection(RecyclerView recyclerView) { protected void setDefaultScrollListener() { mRecyclerView.removeOnScrollListener(mOnScrollListener); mOnScrollListener = new RecyclerView.OnScrollListener() { - @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (mHeader != null) { - mTotalYScrolled += dy; - if (isParallaxHeader) - translateHeader(mTotalYScrolled); - } + switch (mScrollbarsStyle) { + case SCROLLBARS_VERTICAL: + mTotalScrolledOffset = mRecyclerView.computeVerticalScrollOffset(); + break; + case SCROLLBARS_HORIZONTAL: + mTotalScrolledOffset = mRecyclerView.computeHorizontalScrollOffset(); + break; + default: + break; + } + if (mHeader.isParallaxHeader()) { + if (mUpdateScroll != null) { + mUpdateScroll.update(mTotalScrolledOffset); + } + mHeader.translateHeader(mTotalScrolledOffset, mParallaxScroll, recyclerView.findViewHolderForAdapterPosition(0)); + } + } scroll_load_more_detection(recyclerView); - enableShoworHideToolbarAndFloatingButton(recyclerView); } }; mRecyclerView.addOnScrollListener(mOnScrollListener); } + private int mTotalScrolledOffset; + private updateScroll mUpdateScroll; + public interface updateScroll { + void update(int local); + } + + public final void setUpdateScrollLocation(updateScroll e) { + mUpdateScroll = e; + } /** * If you have used {@link #disableLoadmore()} and want to enable loading more again,you can use this method. */ public void reenableLoadmore() { - if (mAdapter != null && mLoadMoreView != null) { + if (mAdapter != null && mLoadMoreView > 0) { mAdapter.enableLoadMore(true); } mIsLoadMoreWidgetEnabled = true; @@ -524,7 +531,7 @@ public boolean isLoadMoreEnabled() { */ public void disableLoadmore() { mIsLoadMoreWidgetEnabled = false; - if (mAdapter != null && mLoadMoreView != null) { + if (mAdapter != null && mLoadMoreView > 0) { mAdapter.enableLoadMore(false); } } @@ -721,7 +728,7 @@ public RecyclerView.ItemAnimator getItemAnimator() { * @param listener SwipeRefreshLayout */ public void setDefaultOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) { - + if (mSwipeRefreshLayout == null) return; mSwipeRefreshLayout.setEnabled(true); if (defaultSwipeToDismissColors != null && defaultSwipeToDismissColors.length > 0) { mSwipeRefreshLayout.setColorSchemeColors(defaultSwipeToDismissColors); @@ -749,10 +756,10 @@ public void setDefaultSwipeToRefreshColorScheme(int... colors) { /** * Set the load more listener of recyclerview * - * @param onLoadMoreListener load listen + * @param listenSymbol load listen */ - public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) { - this.onLoadMoreListener = onLoadMoreListener; + public void setOnLoadMoreListener(OnLoadMoreListener listenSymbol) { + onLoadMoreListener = listenSymbol; } @@ -782,8 +789,8 @@ public RecyclerView.Adapter getAdapter() { */ private void setAdapterInternal(UltimateViewAdapter adapter) { mAdapter = adapter; - if (mSwipeRefreshLayout != null) - mSwipeRefreshLayout.setRefreshing(false); + // if (mSwipeRefreshLayout != null) + //mSwipeRefreshLayout.setRefreshing(false); if (mAdapter != null) mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override @@ -818,20 +825,11 @@ public void onChanged() { }); mRecyclerViewHelper = RecyclerViewPositionHelper.createHelper(mRecyclerView); - mAdapter.setEmptyViewPolicy(policy_empty); mAdapter.setEmptyViewOnInitPolicy(policy_init); - if (mAdapter.getAdapterItemCount() == 0 && policy_init == UltimateRecyclerView.STARTWITH_OFFLINE_ITEMS) { - showEmptyView(); - } - - if (policy_init == UltimateRecyclerView.STARTWITH_ONLINE_ITEMS) { - hideEmptyView(); - } - - if (mAdapter.getCustomLoadMoreView() == null && mLoadMoreView != null) { - mAdapter.setCustomLoadMoreView(mLoadMoreView); + if (mAdapter.getCustomLoadMoreView() == null && mLoadMoreView > 0) { + mAdapter.setCustomLoadMoreView(mLoadMoreView, getContext()); mAdapter.enableLoadMore(true); mAdapter.notifyDataSetChanged(); mIsLoadMoreWidgetEnabled = true; @@ -841,13 +839,33 @@ public void onChanged() { mAdapter.setCustomHeaderView(mHeader); //getLayoutManager().ignoreView(mHeader); } + if (mAdapter instanceof LinearExpanxURVAdapter) { + mIsLoadMoreWidgetEnabled = false; + mAdapter.enableLoadMore(false); + } + + if (mAdapter instanceof easyRegularAdapter) { + + } + + if (mAdapter instanceof UltimateDifferentViewTypeAdapter) { + + } + + if (mAdapter instanceof SwipeableUltimateViewAdapter) { + + } + + if (mAdapter instanceof AdmobAdapter) { + + } + + data_length_check(); } private void updateHelperDisplays() { automaticLoadMoreEnabled = false; - if (mSwipeRefreshLayout != null) - mSwipeRefreshLayout.setRefreshing(false); if (mAdapter == null) return; /** @@ -856,21 +874,31 @@ private void updateHelperDisplays() { * + getItemCount is zero */ if (!isFirstLoadingOnlineAdapter) { - if (mAdapter.getAdapterItemCount() == 0) { - - mEmpty.setVisibility(mEmptyView == null ? View.VISIBLE : View.GONE); - + isFirstLoadingOnlineAdapter = true; - } else if (mEmptyId != 0) { - implementLoadMorebehavior(); - mEmpty.setVisibility(View.GONE); - } } else { - isFirstLoadingOnlineAdapter = false; + //isFirstLoadingOnlineAdapter = false; setRefreshing(false); implementLoadMorebehavior(); } + data_length_check(); + } + private void data_length_check() { + + if (mAdapter.getAdapterItemCount() == 0) { + showEmptyView(); + } else { + hideEmptyView(); + } + + if (mAdapter.getAdapterItemCount() == 0 && policy_init == UltimateRecyclerView.STARTWITH_OFFLINE_ITEMS) { + showEmptyView(); + } + + if (policy_init == UltimateRecyclerView.STARTWITH_ONLINE_ITEMS) { + hideEmptyView(); + } } private void implementLoadMorebehavior() { @@ -892,9 +920,21 @@ public void setHasFixedSize(boolean hasFixedSize) { * * @param refreshing enable the refresh loading icon */ - public void setRefreshing(boolean refreshing) { - if (mSwipeRefreshLayout != null) - mSwipeRefreshLayout.setRefreshing(refreshing); + public void setRefreshing(final boolean refreshing) { + if (mSwipeRefreshLayout != null) { + mSwipeRefreshLayout.post(new Runnable() { + @Override + public void run() { + mSwipeRefreshLayout.setRefreshing(refreshing); + } + }); + } + // if (mPtrFrameLayout != null && refreshing) + // mPtrFrameLayout.autoRefresh(true); + if (mPtrFrameLayout != null && !refreshing) { + mPtrFrameLayout.setPullToRefresh(false); + mPtrFrameLayout.refreshComplete(); + } } @@ -904,9 +944,13 @@ public void setRefreshing(boolean refreshing) { * * @param isSwipeRefresh is now operating in refresh */ - public void enableDefaultSwipeRefresh(boolean isSwipeRefresh) { + public void setEnabledRefresh(boolean isSwipeRefresh) { if (mSwipeRefreshLayout != null) mSwipeRefreshLayout.setEnabled(isSwipeRefresh); + + if (mPtrFrameLayout != null) { + mPtrFrameLayout.setEnabledNextPtrAtOnce(isSwipeRefresh); + } } @@ -957,22 +1001,23 @@ public void setParallaxHeader(@LayoutRes int mLayout) { */ public void setParallaxHeader(View header) { mHeader = new CustomRelativeWrapper(header.getContext()); - mHeader.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - mHeader.addView(header, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - isParallaxHeader = true; + mHeader.setParallax(true); + mHeader.embedView(header); } - /** * Set the normal header of the recyclerview * * @param header na */ public void setNormalHeader(View header) { - setParallaxHeader(header); - isParallaxHeader = false; + mHeader = new CustomRelativeWrapper(header.getContext()); + mHeader.setParallax(false); + mHeader.embedView(header); } + private float mScrollMultiplier = 0.5f; + /** * Set the on scroll method of parallax header * @@ -983,51 +1028,33 @@ public void setOnParallaxScroll(OnParallaxScroll parallaxScroll) { mParallaxScroll.onParallaxScroll(0, 0, mHeader); } - private void translateHeader(float of) { - float ofCalculated = of * SCROLL_MULTIPLIER; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - //Logs.d("ofCalculated " + ofCalculated+" "+mHeader.getHeight()); - mHeader.setTranslationY(ofCalculated); - } else { - TranslateAnimation anim = new TranslateAnimation(0, 0, ofCalculated, ofCalculated); - anim.setFillAfter(true); - anim.setDuration(0); - mHeader.startAnimation(anim); - } - mHeader.setClipY(Math.round(ofCalculated)); - if (mParallaxScroll != null) { - float left = Math.min(1, ((ofCalculated) / (mHeader.getHeight() * SCROLL_MULTIPLIER))); - mParallaxScroll.onParallaxScroll(left, of, mHeader); - } - } - - public interface OnParallaxScroll { - void onParallaxScroll(float percentage, float offset, View parallax); + /** + * Set parallax scroll multiplier. + * + * @param mul The multiplier + */ + public void setScrollMultiplier(float mul) { + this.mScrollMultiplier = mul; } /** - * Custom layout for the Parallax Header. + * Get the current parallax scroll multiplier. + * + * @return the value in float */ - public static class CustomRelativeWrapper extends RelativeLayout { - - private int mOffset; + public float getScrollMultiplier() { + return this.mScrollMultiplier; + } - public CustomRelativeWrapper(Context context) { - super(context); - } - @Override - protected void dispatchDraw(Canvas canvas) { - if (isParallaxHeader) - canvas.clipRect(new Rect(getLeft(), getTop(), getRight(), getBottom() + mOffset)); - super.dispatchDraw(canvas); - } + public interface OnParallaxScroll { + void onParallaxScroll(float percentage, float offset, View parallax); + } - public void setClipY(int offset) { - mOffset = offset; - invalidate(); + public void setPtrHandler(final PtrHandler listen) { + if (mPtrFrameLayout != null) { + mPtrFrameLayout.setPtrHandler(listen); } - } /** @@ -1053,7 +1080,6 @@ public void onRestoreInstanceState(Parcelable state) { mScrollY = ss.scrollY; mChildrenHeights = ss.childrenHeights; RecyclerView.LayoutManager layoutManager = getLayoutManager(); - /** * enhanced and store the previous scroll position */ @@ -1063,7 +1089,6 @@ public void onRestoreInstanceState(Parcelable state) { layoutManager.scrollToPosition(mPrevScrollY); } } - super.onRestoreInstanceState(ss.getSuperState()); } @@ -1215,18 +1240,6 @@ public boolean toolbarIsHidden(Toolbar mToolbar) { return ViewCompat.getTranslationY(mToolbar) == -mToolbar.getHeight(); } - @Deprecated - public void showToolbarAndFAB(Toolbar mToolbar, UltimateRecyclerView ultimateRecyclerView, int screenHeight) { - showToolbar(mToolbar, ultimateRecyclerView, screenHeight); - showDefaultFloatingActionButton(); - } - - @Deprecated - public void hideToolbarAndFAB(Toolbar mToolbar, UltimateRecyclerView ultimateRecyclerView, int screenHeight) { - hideToolbar(mToolbar, ultimateRecyclerView, screenHeight); - hideDefaultFloatingActionButton(); - } - public void showToolbar(Toolbar mToolbar, UltimateRecyclerView ultimateRecyclerView, int screenHeight) { moveToolbar(mToolbar, ultimateRecyclerView, screenHeight, 0); } @@ -1286,47 +1299,10 @@ public void onAnimationUpdate(ValueAnimator animation) { } - public FloatingActionButton getDefaultFloatingActionButton() { - return defaultFloatingActionButton; - } - - public void setDefaultFloatingActionButton(FloatingActionButton defaultFloatingActionButton) { - this.defaultFloatingActionButton = defaultFloatingActionButton; - } - public View getCustomFloatingActionView() { return mFloatingButtonView; } -// public void setCustomFloatingActionView(View customFloatingActionView) { -// this.floatingActionMenu = floatingActionMenu; -// } - - public void showFloatingActionMenu() { - if (mFloatingButtonView != null) - ((FloatingActionsMenu) mFloatingButtonView).hide(false); - } - - public void hideFloatingActionMenu() { - if (mFloatingButtonView != null) ((FloatingActionsMenu) mFloatingButtonView).hide(true); - } - - public void showFloatingActionButton() { - if (mFloatingButtonView != null) - ((FloatingActionButton) mFloatingButtonView).hide(false); - } - - public void hideFloatingActionButton() { - if (mFloatingButtonView != null) ((FloatingActionButton) mFloatingButtonView).hide(true); - } - - public void showDefaultFloatingActionButton() { - defaultFloatingActionButton.hide(false); - } - - public void hideDefaultFloatingActionButton() { - defaultFloatingActionButton.hide(true); - } public void displayCustomFloatingActionView(boolean b) { if (mFloatingButtonView != null) @@ -1334,7 +1310,7 @@ public void displayCustomFloatingActionView(boolean b) { } public void displayDefaultFloatingActionButton(boolean b) { - defaultFloatingActionButton.setVisibility(b ? VISIBLE : INVISIBLE); + // defaultFloatingActionButton.setVisibility(b ? VISIBLE : INVISIBLE); } public void removeItemDecoration(RecyclerView.ItemDecoration decoration) { diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerviewViewHolder.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerviewViewHolder.java index 40c45d44..09a3a1fb 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerviewViewHolder.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateRecyclerviewViewHolder.java @@ -22,7 +22,6 @@ public class UltimateRecyclerviewViewHolder extends RecyclerView.ViewHolder i private View mView; private T mObject; - public SwipeLayout swipeLayout = null; public SwipeLayout.OnLayout onLayoutListener = null; public SwipeLayout.SwipeListener swipeMemory = null; @@ -32,6 +31,7 @@ public UltimateRecyclerviewViewHolder(View itemView) { super(itemView); swipeLayout = (SwipeLayout) itemView.findViewById(R.id.recyclerview_swipe); mView = itemView; + } /** diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateViewAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateViewAdapter.java index a249256a..b203be0f 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateViewAdapter.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/UltimateViewAdapter.java @@ -3,10 +3,12 @@ import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.TargetApi; +import android.content.Context; import android.os.Build; import android.os.Handler; -import android.support.annotation.Nullable; +import android.support.annotation.LayoutRes; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -18,14 +20,17 @@ import java.util.Iterator; import java.util.List; +import com.ml93.captainmiaoUtil.common.BaseLoadMoreFooterView; +import com.ml93.captainmiaoUtil.common.CustomRelativeWrapper; +import com.ml93.captainmiaoUtil.common.UnRecyclableViewHolder; + /** * An abstract adapter which can be extended for Recyclerview */ -public abstract class UltimateViewAdapter extends RecyclerView.Adapter implements StickyRecyclerHeadersAdapter, ItemTouchHelperAdapter { +public abstract class UltimateViewAdapter extends RecyclerView.Adapter implements StickyRecyclerHeadersAdapter, ItemTouchHelperAdapter { protected Handler timer = new Handler(); - protected UltimateRecyclerView.CustomRelativeWrapper customHeaderView = null; - protected View customLoadMoreView = null; - protected View customLoadMoreItemView = null; + protected CustomRelativeWrapper customHeaderView = null; + protected BaseLoadMoreFooterView customLoadMoreView = null; private boolean customHeader = false; /** * this watches how many times does this loading more triggered @@ -47,12 +52,12 @@ public abstract class UltimateViewAdapter ex * * @param customHeaderView na */ - public void setCustomHeaderView(UltimateRecyclerView.CustomRelativeWrapper customHeaderView) { + public void setCustomHeaderView(CustomRelativeWrapper customHeaderView) { this.customHeaderView = customHeaderView; customHeader = true; } - public UltimateRecyclerView.CustomRelativeWrapper getCustomHeaderView() { + public CustomRelativeWrapper getCustomHeaderView() { return customHeaderView; } @@ -64,13 +69,23 @@ public boolean hasHeaderView() { * Using a custom LoadMoreView * * @param customview the inflated view + * @param ctx context */ - public final void setCustomLoadMoreView(@Nullable View customview) { - customLoadMoreView = customview; + public final void setCustomLoadMoreView(final @LayoutRes int customview, Context ctx) { + customLoadMoreView = new BaseLoadMoreFooterView(ctx) { + @Override + public int getLoadMoreLayoutResource() { + return customview; + } + }; } - - public final View getCustomLoadMoreView() { + /** + * base load more footer view custom + * + * @return the base load more footer + */ + public final BaseLoadMoreFooterView getCustomLoadMoreView() { return customLoadMoreView; } @@ -84,10 +99,10 @@ public final boolean enableLoadMore() { } - private class delayenableloadmore implements Runnable { + private class delayEnableLoadmore implements Runnable { private boolean enabled; - public delayenableloadmore(final boolean b) { + public delayEnableLoadmore(final boolean b) { enabled = b; } @@ -96,7 +111,7 @@ public void run() { if (!enabled && loadmoresetingswatch > 0 && customLoadMoreView != null) { final int displaySize = getItemCount(); final int dataSize = getAdapterItemCount(); - if (dataSize > 0 && customLoadMoreItemView != null) { + if (dataSize > 0 && customLoadMoreView != null) { notifyItemRemoved(displaySize - 1); } detectDispatchLoadMoreDisplay(getAdapterItemCount(), getItemCount()); @@ -111,7 +126,7 @@ public void run() { } } - public delayenableloadmore cbloadmore; + public delayEnableLoadmore cbloadmore; /** * as the set function to switching load more feature @@ -119,7 +134,11 @@ public void run() { * @param b bool */ public final void enableLoadMore(final boolean b) { - cbloadmore = new delayenableloadmore(b); + if (b) { + cbloadmore = new delayEnableLoadmore(b); + } else { + cbloadmore = null; + } } public final void internalExecuteLoadingView() { @@ -158,6 +177,23 @@ public final int getEmptyViewInitPolicy() { return mEmptyViewOnInitPolicy; } + @Override + @SuppressWarnings("unchecked") + public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { + super.onViewAttachedToWindow(holder); + int position = holder.getLayoutPosition(); + if (getItemViewType(position) != VIEW_TYPES.NORMAL) { + ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams(); + if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) { + StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams) layoutParams; + lp.setFullSpan(true); + } + } + } + + private RecyclerView.ViewHolder initNonRecycleableView(View normalView) { + return new UnRecyclableViewHolder(normalView); + } /** * the basic view holder creation @@ -167,22 +203,25 @@ public final int getEmptyViewInitPolicy() { * @return expected a typed view holder */ @Override - public VH onCreateViewHolder(ViewGroup parent, int viewType) { + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPES.FOOTER) { - VH viewHolder = newFooterHolder(customLoadMoreView); + // RecyclerView.ViewHolder viewHolder = initNonRecycleableView(customLoadMoreView); + UltimateRecyclerviewViewHolder viewHolder = new UltimateRecyclerviewViewHolder<>(customLoadMoreView); /** * this is only for the first time rendering of the adapter */ - customLoadMoreItemView = viewHolder.itemView; + // customLoadMoreItemView = viewHolder.itemView; + if (getAdapterItemCount() == 0) { removeDispatchLoadMoreView(); } + if (enabled_custom_load_more_view && getAdapterItemCount() > 0) { revealDispatchLoadMoreView(); } return viewHolder; } else if (viewType == VIEW_TYPES.HEADER) { - return newHeaderHolder(customHeaderView); + return initNonRecycleableView(customHeaderView); } else if (viewType == VIEW_TYPES.ADVIEW) { return getAdViewHolder(customHeaderView); } else if (viewType == VIEW_TYPES.CUSTOMVIEW) { @@ -224,17 +263,6 @@ public VH getNoViewHolder(View view) { } - /** - * requirement: FOOTER, HEADER. it does not bind and need to do that in the header binding - * - * @param view with no binding view of nothing - * @return v - */ - public abstract VH newFooterHolder(View view); - - - public abstract VH newHeaderHolder(View view); - /** * for all NORMAL type holder * @@ -246,7 +274,6 @@ public VH getNoViewHolder(View view) { @Override public int getItemViewType(int position) { - // int k = getAdapterItemCount(); if (getAdapterItemCount() == 0) { if (position == 0) { if (enableLoadMore() && hasHeaderView()) { @@ -291,7 +318,7 @@ public int getItemViewType(int position) { return VIEW_TYPES.NORMAL; } } else { - return VIEW_TYPES.NORMAL; + return -1; } } @@ -357,10 +384,10 @@ public void swapPositions(List list, int from, int to) { from--; to--; } - if (enableLoadMore() && to == getItemCount() - 1) return; - if (hasHeaderView() && to == 0) return; - if (hasHeaderView() && from == 0) return; - if (enableLoadMore() && from == getItemCount() - 1) return; + if (enableLoadMore() && getItemViewType(to) == VIEW_TYPES.FOOTER) return; + if (hasHeaderView() && getItemViewType(to) == VIEW_TYPES.HEADER) return; + if (hasHeaderView() && getItemViewType(from) == VIEW_TYPES.HEADER) return; + if (enableLoadMore() && getItemViewType(from) == VIEW_TYPES.FOOTER) return; Collections.swap(list, from, to); } @@ -476,7 +503,6 @@ public final void clearInternal(List list) { protected boolean detectDispatchLoadMoreDisplay(final int data_size_before_remove, final int display_size_before_remove) { if (data_size_before_remove == 0) { if (display_size_before_remove == 2) { - if (mEmptyViewPolicy == UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE) { } else if (mEmptyViewPolicy == UltimateRecyclerView.EMPTY_KEEP_HEADER) { @@ -484,7 +510,6 @@ protected boolean detectDispatchLoadMoreDisplay(final int data_size_before_remov } else if (mEmptyViewPolicy == UltimateRecyclerView.EMPTY_CLEAR_ALL) { removeDispatchLoadMoreView(); } - } else if (display_size_before_remove == 1) { if (mEmptyViewPolicy == UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE) { @@ -494,9 +519,7 @@ protected boolean detectDispatchLoadMoreDisplay(final int data_size_before_remov } else if (mEmptyViewPolicy == UltimateRecyclerView.EMPTY_CLEAR_ALL) { removeDispatchLoadMoreView(); } - return true; - } else if (display_size_before_remove == 0) { if (mEmptyViewPolicy == UltimateRecyclerView.EMPTY_KEEP_HEADER_AND_LOARMORE) { notifyDataSetChanged(); @@ -514,19 +537,19 @@ protected boolean detectDispatchLoadMoreDisplay(final int data_size_before_remov } protected void revealDispatchLoadMoreView() { - if (customLoadMoreItemView != null) { + /* if (customLoadMoreItemView != null) { if (customLoadMoreItemView.getVisibility() != View.VISIBLE) { customLoadMoreItemView.setVisibility(View.VISIBLE); } - } + }*/ } protected void removeDispatchLoadMoreView() { - if (customLoadMoreItemView != null) { + /* if (customLoadMoreItemView != null) { if (customLoadMoreItemView.getVisibility() != View.GONE) { customLoadMoreItemView.setVisibility(View.GONE); } - } + }*/ } /** diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/LinearExpanxURVAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/LinearExpanxURVAdapter.java index e5bd652c..bc1d3a49 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/LinearExpanxURVAdapter.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/LinearExpanxURVAdapter.java @@ -1,6 +1,7 @@ package com.marshalchen.ultimaterecyclerview.expanx; import android.content.Context; +import android.os.Build; import android.support.annotation.LayoutRes; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -35,7 +36,7 @@ protected ExpandableViewTypes() { } private Context mContext; - private List mDataSet; + private final List mDataSet; private List monScrollToListenerList = new ArrayList<>(); private OnScrollToListener onScrollToListener; public static final String TAG = "expAdapter"; @@ -127,7 +128,6 @@ private ItemDataClickListener getBehavior() { } } - @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { switch (getItemViewType(position)) { @@ -144,7 +144,6 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { } } - @Override public BaseViewHolder onCreateViewHolder(ViewGroup viewGroup) { return new BaseViewHolder(viewGroup); @@ -193,7 +192,11 @@ public int getAdapterItemCount() { @Override public long generateHeaderId(int i) { - return 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + return View.generateViewId(); + } else { + return 0; + } } private int getChildrenCount(T item) { @@ -222,10 +225,15 @@ private void printChild(Object item, List list) { * @param itemCount 删除的数目 */ protected void removeAll(int position, int itemCount) { - for (int i = 0; i < itemCount; i++) { - mDataSet.remove(position); + if (position < getAdapterItemCount()) { + notifyItemRangeRemoved(position, itemCount); + for (int i = 0; i < itemCount; i++) { + mDataSet.remove(position); + } + int after_count = mDataSet.size(); + //notifyItemRangeRemoved(position, itemCount); + // notifyItemMoved(position, position + itemCount); } - notifyItemRangeRemoved(position, itemCount); } /** @@ -245,7 +253,11 @@ protected int getCurrentPosition(String uuid) { @Override public int getItemViewType(int position) { - return mDataSet.get(position).getType(); + if (position < mDataSet.size()) { + return mDataSet.get(position).getType(); + } else { + return -1; + } } public void add(T text, int position) { diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/Util/BaseViewHolder.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/Util/BaseViewHolder.java index 38578b7f..6db04496 100755 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/Util/BaseViewHolder.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/expanx/Util/BaseViewHolder.java @@ -25,6 +25,16 @@ public BaseViewHolder(View itemView) { getMarginBy(); } + @Override + public void onViewAttachedToWindow() { + super.onViewAttachedToWindow(); + } + + @Override + public void onViewDetachedFromWindow() { + super.onViewDetachedFromWindow(); + } + protected View getView(final Context m, final ViewGroup parent, final @LayoutRes int layout) { return LayoutInflater.from(m).inflate(layout, parent, false); } diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/BasicGridLayoutManager.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/BasicGridLayoutManager.java deleted file mode 100644 index 9e7b747a..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/BasicGridLayoutManager.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.marshalchen.ultimaterecyclerview.grid; - -import android.content.Context; -import android.support.v7.widget.GridLayoutManager; - -import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; - -/** - * Created by hesk on 24/8/15. - */ -public class BasicGridLayoutManager extends GridLayoutManager { - private final UltimateViewAdapter mAdapter; - protected int headerSpan = 2; - - - protected GridLayoutManager.SpanSizeLookup mSpanSizeLookUp = new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - if (mAdapter.getItemViewType(position) == UltimateViewAdapter.VIEW_TYPES.FOOTER) { - return getSpanCount(); - } else if (mAdapter.getItemViewType(position) == UltimateViewAdapter.VIEW_TYPES.HEADER) { - return getSpanCount(); - } else - return getNormalSpanCount(position); - } - }; - - protected int getSpanInterval(int position) { - int mIntervalHeader = getSpanCount() * 10; - int h = position % mIntervalHeader == 0 ? getSpanCount() : 1; - return h; - - } - - protected int getHeaderSpanCount(int n) { - return headerSpan; - } - - protected int getNormalSpanCount(int item_position) { - return 1; - } - - protected GridLayoutManager.SpanSizeLookup decideSpanSizeCal() { - return mSpanSizeLookUp; - } - - public BasicGridLayoutManager(Context context, int spanCount, UltimateViewAdapter mAdapter) { - super(context, spanCount); - this.mAdapter = mAdapter; - setSpanSizeLookup(decideSpanSizeCal()); - } - - public BasicGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout, UltimateViewAdapter mAdapter) { - super(context, spanCount, orientation, reverseLayout); - this.mAdapter = mAdapter; - setSpanSizeLookup(decideSpanSizeCal()); - } -} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/customSectionGridAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/customSectionGridAdapter.java deleted file mode 100644 index 2f5d5c06..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/customSectionGridAdapter.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.marshalchen.ultimaterecyclerview.grid; - -/** - * Created by hesk on 29/2/16. - */ -public class customSectionGridAdapter { -} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/itemTouchHelper/SimpleItemTouchHelperCallback.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/itemTouchHelper/SimpleItemTouchHelperCallback.java index a026ac22..82e62899 100755 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/itemTouchHelper/SimpleItemTouchHelperCallback.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/itemTouchHelper/SimpleItemTouchHelperCallback.java @@ -91,9 +91,11 @@ public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHo @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { - // Let the view holder know that this item is being moved or dragged - ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder; - itemViewHolder.onItemSelected(); + if (viewHolder instanceof ItemTouchHelperViewHolder) { + // Let the view holder know that this item is being moved or dragged + ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder; + itemViewHolder.onItemSelected(); + } } super.onSelectedChanged(viewHolder, actionState); } diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/easyRegularAdapter.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/easyRegularAdapter.java index 72feccf7..0b75d84b 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/easyRegularAdapter.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/easyRegularAdapter.java @@ -34,7 +34,6 @@ public easyRegularAdapter(List list) { source = list; } - /** * Constructor * @@ -44,6 +43,9 @@ public easyRegularAdapter(T... objects) { this(new ArrayList(Arrays.asList(objects))); } + public easyRegularAdapter() { + this(new ArrayList()); + } /** * the layout id for the normal data @@ -60,15 +62,6 @@ public easyRegularAdapter(T... objects) { */ protected abstract BINDHOLDER newViewHolder(View view); - @Override - public BINDHOLDER newFooterHolder(View view) { - return null; - } - - @Override - public BINDHOLDER newHeaderHolder(View view) { - return null; - } /** * this MUST BE USING THE NORMAL VIEW diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/extBaseAdapter/BaseAdapterHelper.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/extBaseAdapter/BaseAdapterHelper.java index f9d0c08e..1b4aaa02 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/extBaseAdapter/BaseAdapterHelper.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/quickAdapter/extBaseAdapter/BaseAdapterHelper.java @@ -118,7 +118,7 @@ static BaseAdapterHelper get(Context context, View convertView, /** * This method allows you to retrieve a view and perform custom operations * on it, not covered by the BaseAdapterHelper. - * If you think it's a common use case, please consider creating a new issue + * If you think it's a com.ml93.kp.common use case, please consider creating a new issue * at https://github.com/JoanZapata/base-adapter-helper/issues. * * @param viewId The id of the view you want to retrieve. diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/swipelistview/SwipeListView.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/swipelistview/SwipeListView.java index a122f64b..e3b2c5af 100755 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/swipelistview/SwipeListView.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/swipelistview/SwipeListView.java @@ -134,7 +134,7 @@ public class SwipeListView extends RecyclerView { private LinearLayoutManager mLayoutManager; /** - * Internal listener for common swipe events + * Internal listener for com.ml93.kp.common swipe events */ public SwipeListViewListener swipeListViewListener; @@ -307,40 +307,23 @@ public void unselectedChoiceStates() { public void setAdapter(Adapter adapter) { super.setAdapter(adapter); touchListener.resetItems(); -// adapter.registerDataSetObserver(new DataSetObserver() { -// -// @Override -// public void onChanged() { -// super.onChanged(); -// onListChanged(); -// touchListener.resetItems(); -// } -// }); - adapter.registerAdapterDataObserver(new AdapterDataObserver() { - @Override public void onChanged() { - super.onChanged(); onListChanged(); touchListener.resetItems(); - } - }); } @Override public void setLayoutManager(LayoutManager layoutManager) { - super.setLayoutManager(layoutManager); mLayoutManager = (LinearLayoutManager) layoutManager; if (touchListener != null) { - touchListener.setLayoutManager(mLayoutManager); } - } /** @@ -679,13 +662,10 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { int action = MotionEventCompat.getActionMasked(ev); final float x = ev.getX(); final float y = ev.getY(); - if (isEnabled() && touchListener.isSwipeEnabled()) { - if (touchState == TOUCH_STATE_SCROLLING_X) { return touchListener.onTouch(this, ev); } - switch (action) { case MotionEvent.ACTION_MOVE: checkInMoving(x, y); @@ -707,7 +687,6 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { break; } } - return super.onInterceptTouchEvent(ev); } diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/uiUtils/RecyclerViewPositionHelper.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/uiUtils/RecyclerViewPositionHelper.java index 39dbaec0..88944e1d 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/uiUtils/RecyclerViewPositionHelper.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/uiUtils/RecyclerViewPositionHelper.java @@ -20,7 +20,6 @@ public class RecyclerViewPositionHelper { RecyclerViewPositionHelper(RecyclerView recyclerView) { this.recyclerView = recyclerView; this.layoutManager = recyclerView.getLayoutManager(); - } public static RecyclerViewPositionHelper createHelper(RecyclerView recyclerView) { @@ -87,8 +86,7 @@ public int findLastCompletelyVisibleItemPosition() { return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child); } - private View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, - boolean acceptPartiallyVisible) { + private View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, boolean acceptPartiallyVisible) { OrientationHelper helper; if (layoutManager.canScrollVertically()) { helper = OrientationHelper.createVerticalHelper(layoutManager); diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/CardViewDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/CardViewDecoration.java new file mode 100644 index 00000000..5dda7aef --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/CardViewDecoration.java @@ -0,0 +1,201 @@ +package com.ml93.captainmiaoUtil.ItemDecoration; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RadialGradient; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Shader; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.RecyclerView; +import android.util.TypedValue; +import android.view.View; + +import com.marshalchen.ultimaterecyclerview.R; +import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; + +/** + * Created by hesk on 2016/9/17. + */ + +public class CardViewDecoration extends RecyclerView.ItemDecoration { + final static float SHADOW_MULTIPLIER = 1.5f; + /* + * This helper is set by CardView implementations.

Prior to API 17, canvas.drawRoundRect is expensive; which is + * why we need this interface to draw efficient rounded rectangles before 17. + */ + //static RoundRectHelper sRoundRectHelper; + private Paint mPaint; + private Paint mCornerShadowPaint; + private Paint mEdgeShadowPaint; + private final RectF mPreShadowBounds; + private float mCornerRadius; + private Path mCornerShadowPath; + private float mShadowSize; + private boolean mDirty = true; + private final int mShadowStartColor; + private final int mShadowEndColor; + private float mPadding; + + public CardViewDecoration(Context resources, int backgroundColor, float radius) { + mShadowStartColor = ContextCompat.getColor(resources, R.color.cardview_shadow_start_color); + mShadowEndColor = ContextCompat.getColor(resources, R.color.cardview_shadow_end_color); + mShadowSize = resources.getResources().getDimension(R.dimen.cardview_shadow_size) * SHADOW_MULTIPLIER; + + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); + mPaint.setColor(backgroundColor); + mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); + mCornerShadowPaint.setStyle(Paint.Style.FILL); + mCornerShadowPaint.setDither(true); + mCornerRadius = radius; + mPreShadowBounds = new RectF(); + mEdgeShadowPaint = new Paint(mCornerShadowPaint); + + buildShadowCorners(); + } + + @Override + public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { + Rect bounds = new Rect(); + float edgeShadowTop = -mCornerRadius - mShadowSize; + + RecyclerView.LayoutManager lm = parent.getLayoutManager(); + float size16dp = 16f; + int padding16dp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size16dp, parent.getContext().getResources().getDisplayMetrics()); + + for (int i = 0; i < parent.getChildCount(); i++) { + int save = c.save(); + + // using decorated values, remove what we set before + View child = parent.getChildAt(i); + bounds.set(lm.getDecoratedLeft(child) + padding16dp - (int) mPadding, + lm.getDecoratedTop(child), + lm.getDecoratedRight(child) - padding16dp + (int) mPadding, + lm.getDecoratedBottom(child)); + + RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + int position = params.getViewAdapterPosition(); + int viewType = parent.getAdapter().getItemViewType(position); + + if (viewType == UltimateViewAdapter.VIEW_TYPES.HEADER) { + bounds.top = (int) (bounds.top + padding16dp - mPadding); + + // LT + c.translate(bounds.left + mCornerRadius, bounds.top + mCornerRadius); + c.drawPath(mCornerShadowPath, mCornerShadowPaint); + c.drawRect(0, edgeShadowTop, bounds.width() - 2 * mCornerRadius, -mCornerRadius, mEdgeShadowPaint); + + // RT + c.rotate(90f); + c.translate(0, -bounds.width() + 2 * mCornerRadius); + c.drawPath(mCornerShadowPath, mCornerShadowPaint); + c.drawRect(0, edgeShadowTop, bounds.height() - mCornerRadius, -mCornerRadius, mEdgeShadowPaint); + + // LBorder + c.rotate(180f); + c.translate(-bounds.height(), -bounds.width() + 2 * mCornerRadius); + c.drawRect(mCornerRadius, edgeShadowTop, bounds.height(), -mCornerRadius, mEdgeShadowPaint); + + } else { + if (parent.getAdapter().getItemViewType(position + 1) == UltimateViewAdapter.VIEW_TYPES.HEADER) { + bounds.bottom = (int) (bounds.bottom - padding16dp + mPadding); + + // last item before next header + c.rotate(180f); + c.translate(-bounds.left - bounds.width() + mCornerRadius, -bounds.top - bounds.height() + mCornerRadius); + + c.drawPath(mCornerShadowPath, mCornerShadowPaint); + c.drawRect(0, edgeShadowTop, bounds.width() - 2 * mCornerRadius, -mCornerRadius, mEdgeShadowPaint); + + // RT / Right border + c.rotate(90f); + c.translate(0, -bounds.width() + 2 * mCornerRadius); + c.drawPath(mCornerShadowPath, mCornerShadowPaint); + c.drawRect(0, edgeShadowTop, bounds.height() - mCornerRadius, -mCornerRadius, mEdgeShadowPaint); + + // Left border + c.rotate(180f); + c.translate(-bounds.height(), -bounds.width() + 2 * mCornerRadius); + c.drawRect(mCornerRadius, edgeShadowTop, bounds.height(), -mCornerRadius, mEdgeShadowPaint); + } else { + // Right border + c.translate(bounds.left, bounds.top); + c.rotate(90f); + c.translate(0, -bounds.width() + mCornerRadius); + c.drawRect(0, edgeShadowTop, bounds.height(), -mCornerRadius, mEdgeShadowPaint); + + // Left border + c.rotate(180f); + c.translate(-bounds.height(), -bounds.width() + 2 * mCornerRadius); + c.drawRect(0, edgeShadowTop, bounds.height(), -mCornerRadius, mEdgeShadowPaint); + } + } + c.restoreToCount(save); + } + } + + private void buildShadowCorners() { + //mPadding = (float) (Math.sqrt((double) mCornerRadius * (double) mCornerRadius * 2) - (double) mCornerRadius); + mPadding = 0f; + + RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius); + RectF outerBounds = new RectF(innerBounds); + outerBounds.inset(-mShadowSize, -mShadowSize); + + if (mCornerShadowPath == null) { + mCornerShadowPath = new Path(); + } else { + mCornerShadowPath.reset(); + } + mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD); + mCornerShadowPath.moveTo(-mCornerRadius, 0); + mCornerShadowPath.rLineTo(-mShadowSize, 0); + // outer arc + mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false); + // inner arc + mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false); + mCornerShadowPath.close(); + + float startRatio = mCornerRadius / (mCornerRadius + mShadowSize); + mCornerShadowPaint.setShader(new RadialGradient(0, 0, mCornerRadius + mShadowSize, new int[]{ + mShadowStartColor, mShadowStartColor, mShadowEndColor}, new float[]{0f, startRatio, 1f}, + Shader.TileMode.CLAMP)); + + // we offset the content shadowSize/2 pixels up to make it more realistic. + // this is why edge shadow shader has some extra space + // When drawing bottom edge shadow, we use that extra space. + mEdgeShadowPaint.setShader(new LinearGradient(0, -mCornerRadius + mShadowSize, 0, -mCornerRadius - mShadowSize, + new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor}, new float[]{0f, .5f, 1f}, + Shader.TileMode.CLAMP)); + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); + Resources resources = parent.getContext().getResources(); + + float size16dp = 16f; + int padding16dp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size16dp, resources.getDisplayMetrics()); + + RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams(); + int position = params.getViewAdapterPosition(); + int viewType = parent.getAdapter().getItemViewType(position); + + if (viewType == UltimateViewAdapter.VIEW_TYPES.HEADER) { + // header + outRect.set(0, (int) (padding16dp), 0, 0); + } else { + if (parent.getAdapter().getItemViewType(position + 1) == UltimateViewAdapter.VIEW_TYPES.HEADER) { + // last item before next header + outRect.set(0, 0, 0, (int) (padding16dp)); + } + } + //outRect.inset((int) size16dp, 0); + outRect.left = (int) padding16dp; + outRect.right = (int) padding16dp; + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/DismissDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/DismissDecoration.java new file mode 100644 index 00000000..88d45e5e --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/DismissDecoration.java @@ -0,0 +1,67 @@ +package com.ml93.captainmiaoUtil.ItemDecoration; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; +import android.support.annotation.ColorInt; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/** + * Created by hesk on 2016/9/17. + */ + +public class DismissDecoration extends RecyclerView.ItemDecoration { + private final int mColor; + private Bitmap mIcon; + private float mDensity; + + public DismissDecoration(@ColorInt int color, Bitmap icon, float density) { + mColor = color; + mIcon = icon; + mDensity = density; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + // no offset, just drawing background + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + for (int i = 0; i < parent.getChildCount(); i++) { + final View view = parent.getChildAt(i); + + float translationX = view.getTranslationX(); + if (translationX == 0) { + continue; + } + + final int save = c.save(); + final int xpos; + final int ypos = (int) (view.getTop() + view.getTranslationY() + (view.getHeight() / 2 - mIcon.getHeight() / 2)); + if (translationX < 0) { + c.clipRect(view.getRight() + view.getTranslationX(), + view.getTop() + view.getTranslationY(), + view.getRight(), + view.getBottom() + view.getTranslationY()); + xpos = (int) (view.getRight() - 36 * mDensity - mIcon.getWidth() / 2); + } else { + c.clipRect(view.getLeft() + view.getTranslationX(), + view.getTop() + view.getTranslationY(), + view.getLeft(), + view.getBottom() + view.getTranslationY()); + xpos = (int) (view.getLeft() + 36 * mDensity - mIcon.getWidth() / 2); + } + c.drawColor(mColor); + Paint color = new Paint(); + color.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)); + c.drawBitmap(mIcon, xpos, ypos, color); + c.restoreToCount(save); + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/DividerDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/DividerDecoration.java new file mode 100644 index 00000000..a197adeb --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/DividerDecoration.java @@ -0,0 +1,58 @@ +package com.ml93.captainmiaoUtil.ItemDecoration; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.support.v7.widget.RecyclerView; +import android.util.TypedValue; +import android.view.View; + +import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; + +/** + * Created by David on 17.06.2015 + */ + +public class DividerDecoration extends RecyclerView.ItemDecoration { + + private final Paint mPaint; + private int mHeightDp; + + public DividerDecoration(Context context) { + this(context, Color.argb((int) (255 * 0.2), 0, 0, 0), 1f); + } + + public DividerDecoration(Context context, int color, float heightDp) { + mPaint = new Paint(); + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(color); + mHeightDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, heightDp, context.getResources().getDisplayMetrics()); + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + if (hasDividerOnBottom(view, parent, state)) { + outRect.set(0, 0, 0, mHeightDp); + } else { + outRect.setEmpty(); + } + } + + private boolean hasDividerOnBottom(View view, RecyclerView parent, RecyclerView.State state) { + int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition(); + return position < state.getItemCount() && parent.getAdapter().getItemViewType(position) != UltimateViewAdapter.VIEW_TYPES.HEADER + && parent.getAdapter().getItemViewType(position + 1) != UltimateViewAdapter.VIEW_TYPES.HEADER; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + for (int i = 0; i < parent.getChildCount(); i++) { + View view = parent.getChildAt(i); + if (hasDividerOnBottom(view, parent, state)) { + c.drawRect(view.getLeft(), view.getBottom(), view.getRight(), view.getBottom() + mHeightDp, mPaint); + } + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/FlexibleDividerDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/FlexibleDividerDecoration.java old mode 100755 new mode 100644 similarity index 99% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/FlexibleDividerDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/FlexibleDividerDecoration.java index b5acd387..e12b3fa2 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/FlexibleDividerDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/FlexibleDividerDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.divideritemdecoration; +package com.ml93.captainmiaoUtil.ItemDecoration; import android.content.Context; import android.content.res.Resources; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/GridPaddingDecorator.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/GridPaddingDecorator.java similarity index 96% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/GridPaddingDecorator.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/GridPaddingDecorator.java index 60f53a34..57749104 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/GridPaddingDecorator.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/GridPaddingDecorator.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.grid; +package com.ml93.captainmiaoUtil.ItemDecoration; import android.graphics.Rect; import android.support.v7.widget.RecyclerView; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/GridSpacingItemDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/GridSpacingItemDecoration.java similarity index 96% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/GridSpacingItemDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/GridSpacingItemDecoration.java index a685ab0d..348b46bb 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/grid/GridSpacingItemDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/GridSpacingItemDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.grid; +package com.ml93.captainmiaoUtil.ItemDecoration; import android.graphics.Rect; import android.support.v7.widget.RecyclerView; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/HeaderDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/HeaderDecoration.java new file mode 100644 index 00000000..302c0bed --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/HeaderDecoration.java @@ -0,0 +1,209 @@ +package com.ml93.captainmiaoUtil.ItemDecoration; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Shader; +import android.support.annotation.DimenRes; +import android.support.annotation.FloatRange; +import android.support.annotation.IntRange; +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; +import android.view.LayoutInflater; +import android.view.View; + +/** + * Created by hesk on 2016/9/17. + */ + +public class HeaderDecoration extends RecyclerView.ItemDecoration { + + private final View mView; + private final boolean mHorizontal; + private final float mParallax; + private final float mShadowSize; + private final int mColumns; + private final Paint mShadowPaint; + + public HeaderDecoration(View view, boolean scrollsHorizontally, float parallax, float shadowSize, int columns) { + mView = view; + mHorizontal = scrollsHorizontally; + mParallax = parallax; + mShadowSize = shadowSize; + mColumns = columns; + + if (mShadowSize > 0) { + mShadowPaint = new Paint(); + mShadowPaint.setShader(mHorizontal ? + new LinearGradient(mShadowSize, 0, 0, 0, + new int[]{Color.argb(55, 0, 0, 0), Color.argb(55, 0, 0, 0), Color.argb(3, 0, 0, 0)}, + new float[]{0f, .5f, 1f}, + Shader.TileMode.CLAMP) : + new LinearGradient(0, mShadowSize, 0, 0, + new int[]{Color.argb(55, 0, 0, 0), Color.argb(55, 0, 0, 0), Color.argb(3, 0, 0, 0)}, + new float[]{0f, .5f, 1f}, + Shader.TileMode.CLAMP)); + } else { + mShadowPaint = null; + } + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + super.onDraw(c, parent, state); + // layout basically just gets drawn on the reserved space on top of the first view + mView.layout(parent.getLeft(), 0, parent.getRight(), mView.getMeasuredHeight()); + + for (int i = 0; i < parent.getChildCount(); i++) { + View view = parent.getChildAt(i); + if (parent.getChildAdapterPosition(view) == 0) { + c.save(); + if (mHorizontal) { + c.clipRect(parent.getLeft(), parent.getTop(), view.getLeft(), parent.getBottom()); + final int width = mView.getMeasuredWidth(); + final float left = (view.getLeft() - width) * mParallax; + c.translate(left, 0); + mView.draw(c); + if (mShadowSize > 0) { + c.translate(view.getLeft() - left - mShadowSize, 0); + c.drawRect(parent.getLeft(), parent.getTop(), mShadowSize, parent.getBottom(), mShadowPaint); + } + } else { + c.clipRect(parent.getLeft(), parent.getTop(), parent.getRight(), view.getTop()); + final int height = mView.getMeasuredHeight(); + final float top = (view.getTop() - height) * mParallax; + c.translate(0, top); + mView.draw(c); + if (mShadowSize > 0) { + c.translate(0, view.getTop() - top - mShadowSize); + c.drawRect(parent.getLeft(), parent.getTop(), parent.getRight(), mShadowSize, mShadowPaint); + } + } + c.restore(); + break; + } + } + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + if (parent.getChildAdapterPosition(view) < mColumns) { + if (mHorizontal) { + if (mView.getMeasuredWidth() <= 0) { + mView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST), + View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST)); + } + outRect.set(mView.getMeasuredWidth(), 0, 0, 0); + } else { + if (mView.getMeasuredHeight() <= 0) { + mView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST), + View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST)); + } + outRect.set(0, mView.getMeasuredHeight(), 0, 0); + } + } else { + outRect.setEmpty(); + } + } + + public static Builder with(Context context) { + return new Builder(context); + } + + public static Builder with(RecyclerView recyclerView) { + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + if (layoutManager instanceof GridLayoutManager) { + GridLayoutManager manager = (GridLayoutManager) layoutManager; + return new Builder(recyclerView.getContext(), manager.getSpanCount()); + } else if (layoutManager instanceof LinearLayoutManager) { + LinearLayoutManager manager = (LinearLayoutManager) layoutManager; + return new Builder(recyclerView.getContext(), manager.getOrientation() == LinearLayoutManager.HORIZONTAL); + } else if (layoutManager instanceof StaggeredGridLayoutManager) { + StaggeredGridLayoutManager manager = (StaggeredGridLayoutManager) layoutManager; + return new Builder(recyclerView.getContext(), manager.getSpanCount()); + } else { + return new Builder(recyclerView.getContext()); + } + } + + + public static class Builder { + private Context mContext; + + private View mView; + private boolean mHorizontal; + private float mParallax = 1f; + private float mShadowSize; + private int mColumns = 1; + + public Builder(@NonNull Context context) { + mContext = context; + } + + public Builder(@NonNull Context context, @IntRange(from = 1) int columns) { + mContext = context; + mColumns = columns; + } + + public Builder(@NonNull Context context, boolean horizontal) { + mContext = context; + mHorizontal = horizontal; + } + + + public Builder setView(@NonNull View view) { + mView = view; + return this; + } + + public Builder inflate(@LayoutRes int layoutRes) { + mView = LayoutInflater.from(mContext).inflate(layoutRes, null, false); + return this; + } + + /** + * Adds a parallax effect. + * + * @param parallax the multiplier to use, 0f would be the view standing still, 1f moves along with the first item. + * @return this builder + */ + public Builder parallax(@FloatRange(from = 0f, to = 1f) float parallax) { + mParallax = parallax; + return this; + } + + public Builder scrollsHorizontally(boolean isHorizontal) { + mHorizontal = isHorizontal; + return this; + } + + public Builder dropShadowDp(@IntRange(from = 0, to = 80) int dp) { + mShadowSize = mContext.getResources().getDisplayMetrics().density * dp; + return this; + } + + public Builder dropShadow(@DimenRes int dimenResource) { + mShadowSize = mContext.getResources().getDimensionPixelSize(dimenResource); + return this; + } + + public HeaderDecoration build() { + if (mView == null) { + throw new IllegalStateException("View must be set with either setView or inflate"); + } + return new HeaderDecoration(mView, mHorizontal, mParallax, mShadowSize * 1.5f, mColumns); + } + + public Builder columns(@IntRange(from = 1) int columns) { + mColumns = columns; + return this; + } + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/HorizontalDividerItemDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/HorizontalDividerItemDecoration.java old mode 100755 new mode 100644 similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/HorizontalDividerItemDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/HorizontalDividerItemDecoration.java index 3c6d6089..32aa48a7 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/HorizontalDividerItemDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/HorizontalDividerItemDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.divideritemdecoration; +package com.ml93.captainmiaoUtil.ItemDecoration; import android.content.Context; import android.graphics.Rect; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/ParallaxHeaderDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/ParallaxHeaderDecoration.java new file mode 100644 index 00000000..8f718b6f --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/ParallaxHeaderDecoration.java @@ -0,0 +1,36 @@ +package com.ml93.captainmiaoUtil.ItemDecoration; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.support.annotation.DrawableRes; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/** + * Created by hesk on 2016/9/17. + */ + +public class ParallaxHeaderDecoration extends RecyclerView.ItemDecoration { + + private Bitmap mImage; + + public ParallaxHeaderDecoration(final Context context, @DrawableRes int resId) { + mImage = BitmapFactory.decodeResource(context.getResources(), resId); + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + super.onDraw(c, parent, state); + for (int i = 0; i < parent.getChildCount(); i++) { + View view = parent.getChildAt(i); + if (parent.getChildAdapterPosition(view) == 20) { + int offset = view.getTop() / 3; + c.drawBitmap(mImage, new Rect(0, offset, mImage.getWidth(), view.getHeight() + offset), new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()), null); + } + } + + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/SeparatorDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/SeparatorDecoration.java new file mode 100644 index 00000000..5616c315 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/SeparatorDecoration.java @@ -0,0 +1,189 @@ +package com.ml93.captainmiaoUtil.ItemDecoration; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; +import android.support.annotation.FloatRange; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.View; + +import com.marshalchen.ultimaterecyclerview.R; + +/** + * Created by hesk on 2016/9/17. + */ + +public class SeparatorDecoration extends RecyclerView.ItemDecoration { + + private final Paint mPaint; + + private final float mMarginLeft; + private final float mMarginRight; + + public SeparatorDecoration(@ColorInt int color, + @FloatRange(from = 0, fromInclusive = false) float width, + @FloatRange(from = 0) float marginLeft, + @FloatRange(from = 0) float marginRight) { + mPaint = new Paint(); + mPaint.setColor(color); + mPaint.setStrokeWidth(width); + mMarginLeft = marginLeft; + mMarginRight = marginRight; + } + + /** + * A builder to easily create the decoration. + * + * @param context a context to use + * @return the builder + */ + public static Builder with(@NonNull Context context) { + return new Builder(context); + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams(); + + // we want to retrieve the position in the list + final int position = params.getViewAdapterPosition(); + + // and add a separator to any view but the last one + if (position < state.getItemCount()) { + outRect.set(0, 0, 0, (int) mPaint.getStrokeWidth()); // left, top, right, bottom + } else { + outRect.setEmpty(); // 0, 0, 0, 0 + } + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + // we set the stroke width before, so as to correctly draw the line we have to offset by width / 2 + final int offset = (int) (mPaint.getStrokeWidth() / 2); + + // this will iterate over every visible view + for (int i = 0; i < parent.getChildCount(); i++) { + // get the view + final View view = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams(); + + // get the position + final int position = params.getViewAdapterPosition(); + + // and finally draw the separator + if (position < state.getItemCount()) { + c.drawLine(view.getLeft() + mMarginLeft, view.getBottom() + offset, + view.getRight() - mMarginRight, view.getBottom() + offset, mPaint); + } + } + } + + /** + * Builder to create a SeparatorDecoration. + */ + public static class Builder { + private final Context mContext; + + private float mWidth; + private int mColor; + private float mMarginLeft = 0f; + private float mMarginRight = 0f; + + /** + * Create the builder with a context to configure a SeparatorDecoration. + * + * @param context the context + */ + public Builder(@NonNull Context context) { + mContext = context; + color(getDefaultColor()); + width(1f); + } + + /** + * Set the separator color from a resource. + * + * @param colorResId the resource id to use + * @return the builder + */ + public Builder colorFromResources(@ColorRes int colorResId) { + mColor = mContext.getResources().getColor(colorResId); + return this; + } + + /** + * Set the separator color from a color. + * + * @param color the color to use + * @return the builder + * @see android.graphics.Color + */ + public Builder color(@ColorInt int color) { + mColor = color; + return this; + } + + /** + * Set the width of the separator. + * + * @param width the width in dp + * @return the builder + */ + public Builder width(@FloatRange(from = 0, fromInclusive = false) float width) { + mWidth = width; + return this; + } + + /** + * Set the margin of the separator + * + * @param margin the margin in dp + * @return the builder + */ + public Builder setMargin(float margin) { + setMargin(margin, margin); + return this; + } + + /** + * Set the margin of the separator + * + * @param left the left margin in dp + * @param right the right margin in dp + * @return the builder + */ + public Builder setMargin(float left, float right) { + final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); + mMarginLeft = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + left, metrics); + mMarginRight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + right, metrics); + return this; + } + + @ColorInt + private int getDefaultColor() { + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = mContext.getTheme(); + theme.resolveAttribute(R.attr.colorControlHighlight, typedValue, true); + return typedValue.data; + } + + /** + * Get the configured SeparatorDecoration. + * + * @return the separatorDecoration + * @see SeparatorDecoration + */ + public SeparatorDecoration build() { + return new SeparatorDecoration(mColor, mWidth, mMarginLeft, mMarginRight); + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/VerticalDividerItemDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/VerticalDividerItemDecoration.java old mode 100755 new mode 100644 similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/VerticalDividerItemDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/VerticalDividerItemDecoration.java index 8a2367c1..0ce75c17 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/divideritemdecoration/VerticalDividerItemDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ItemDecoration/VerticalDividerItemDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.divideritemdecoration; +package com.ml93.captainmiaoUtil.ItemDecoration; import android.content.Context; import android.graphics.Rect; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/BaseLoadMoreFooterView.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/BaseLoadMoreFooterView.java new file mode 100644 index 00000000..88f251e9 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/BaseLoadMoreFooterView.java @@ -0,0 +1,103 @@ +package com.ml93.captainmiaoUtil.common; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.support.annotation.StringRes; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; + +import com.marshalchen.ultimaterecyclerview.R; + + +/** + * @author YanLu + * @since 16/4/10 + */ +public abstract class BaseLoadMoreFooterView extends FrameLayout { + private static final String TAG = "LoadMoreFooterViewHolder"; + + public View mProgressView; + public TextView mTvContent; + + //when loading more data, display content + private String loadingText; + //when no more data, display content + private String noMoreText; + + public abstract int getLoadMoreLayoutResource(); + + public BaseLoadMoreFooterView(Context context) { + super(context); + initViews(context, null); + } + + public BaseLoadMoreFooterView(Context context, AttributeSet attrs) { + super(context, attrs); + initViews(context, attrs); + } + + public BaseLoadMoreFooterView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initViews(context, attrs); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public BaseLoadMoreFooterView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + initViews(context, attrs); + } + + protected void initViews(Context context, AttributeSet attrs) { + View header = LayoutInflater.from(context).inflate(getLoadMoreLayoutResource(), this); + final LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + header.setLayoutParams(lp); + mTvContent = (TextView) header.findViewById(R.id.urv_tv_content); + mProgressView = header.findViewById(R.id.urv_progress_view); + loadingText = context.getString(R.string.app_loading_more); + noMoreText = context.getString(R.string.app_no_more_data); + } + + protected void updateLoadMoreView(String content, boolean isVisible) { + //for AVLoadingIndicatorView + mProgressView.setVisibility(!isVisible ? VISIBLE : GONE); + mProgressView.setVisibility(isVisible ? VISIBLE : GONE); + mTvContent.setText(content); + } + + public void showLoading() { + updateLoadMoreView(loadingText, true); + } + + public void showNoMoreData() { + updateLoadMoreView(noMoreText, false); + } + + public String getLoadingText() { + return loadingText; + } + + public void setLoadingText(@StringRes int rid) { + this.loadingText = getContext().getString(rid); + } + + public void setLoadingText(String loadingText) { + this.loadingText = loadingText; + } + + public String getNoMoreText() { + return noMoreText; + } + + public void setNoMoreText(@StringRes int rid) { + this.noMoreText = getContext().getString(rid); + } + + public void setNoMoreText(String noMoreText) { + this.noMoreText = noMoreText; + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/ClickableViewHolder.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/ClickableViewHolder.java new file mode 100644 index 00000000..30dad0ff --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/ClickableViewHolder.java @@ -0,0 +1,45 @@ +package com.ml93.captainmiaoUtil.common; + +import android.support.v7.widget.RecyclerView; +import android.view.View; + +import com.ml93.captainmiaoUtil.listener.OnRecyclerItemClickListener; + + +/** + * @author YanLu + * @since 15/11/1 + */ +public abstract class ClickableViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + OnRecyclerItemClickListener mClickListener; + + public ClickableViewHolder(View itemView) { + super(itemView); + } + + @Override + public void onClick(View v) { + if(mClickListener != null){ + mClickListener.onClick(v, getAdapterPosition()); + } + } + + public void addOnViewClickListener(View v){ + if(v != null) { + v.setOnClickListener(this); + } + } + public void addOnItemViewClickListener(){ + if(itemView != null) { + itemView.setOnClickListener(this); + } + } + + public OnRecyclerItemClickListener getOnRecyclerItemClickListener() { + return mClickListener; + } + + public void setOnRecyclerItemClickListener(OnRecyclerItemClickListener mClickListener) { + this.mClickListener = mClickListener; + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/CustomRelativeWrapper.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/CustomRelativeWrapper.java new file mode 100644 index 00000000..291ef749 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/CustomRelativeWrapper.java @@ -0,0 +1,84 @@ +package com.ml93.captainmiaoUtil.common; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.os.Build; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.TranslateAnimation; +import android.widget.RelativeLayout; + +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerView; + +/** + * Created by hesk on 2016/9/15. + * Custom layout for the Parallax Header. + */ +public class CustomRelativeWrapper extends RelativeLayout { + + private int mOffset; + private boolean isParallaxHeader; + private float mScrollMultiplier = 0.5f; + + public CustomRelativeWrapper(Context context) { + super(context); + isParallaxHeader = false; + } + + public void embedView(View content) { + setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + addView(content, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + } + + public void setParallax(boolean parallax) { + isParallaxHeader = parallax; + } + + public final boolean isParallaxHeader() { + return isParallaxHeader; + } + + @Override + protected void dispatchDraw(Canvas canvas) { + if (isParallaxHeader) { + canvas.clipRect(new Rect(getLeft(), getTop(), getRight(), getBottom() + mOffset)); + } + super.dispatchDraw(canvas); + } + + public void setClipY(int offset) { + mOffset = offset; + invalidate(); + } + + /** + * Translates the adapter in Y + * + * @param of offset in px + * @param mParallaxScroll object + * @param headerView object + */ + public void translateHeader(float of, UltimateRecyclerView.OnParallaxScroll mParallaxScroll, final RecyclerView.ViewHolder headerView) { + float ofCalculated = of * mScrollMultiplier; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && of < getHeight()) { + setTranslationY(ofCalculated); + } else if (of < getHeight()) { + TranslateAnimation anim = new TranslateAnimation(0, 0, ofCalculated, ofCalculated); + anim.setFillAfter(true); + anim.setDuration(0); + startAnimation(anim); + } + setClipY(Math.round(ofCalculated)); + if (mParallaxScroll != null) { + float left; + if (headerView != null) { + left = Math.min(1, ((ofCalculated) / (getHeight() * mScrollMultiplier))); + } else { + left = 1; + } + mParallaxScroll.onParallaxScroll(left, of, this); + } + } +} \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/UnRecyclableViewHolder.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/UnRecyclableViewHolder.java new file mode 100644 index 00000000..42cc8dd5 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/common/UnRecyclableViewHolder.java @@ -0,0 +1,48 @@ +package com.ml93.captainmiaoUtil.common; + +import android.content.Context; +import android.view.View; + +import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder; + +/** + * @author YanLu + * @since 16/4/10 + */ +public class UnRecyclableViewHolder extends UltimateRecyclerviewViewHolder { + private CustomRelativeWrapper header; + + public UnRecyclableViewHolder(View itemView) { + super(itemView); + setIsRecyclable(false); + if (itemView instanceof CustomRelativeWrapper) { + header = (CustomRelativeWrapper) itemView; + } + } + + @Override + public void onViewRecycled() { + super.onViewRecycled(); + } + + @Override + protected void updateView(Context context, Object object) { + super.updateView(context, object); + } + + @Override + public void onViewAttachedToWindow() { + super.onViewAttachedToWindow(); + if (header != null) { + + } + } + + @Override + public void onViewDetachedFromWindow() { + super.onViewDetachedFromWindow(); + if (header != null) { + + } + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/LinearLayoutWithRecyclerOnScrollListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/LinearLayoutWithRecyclerOnScrollListener.java new file mode 100644 index 00000000..e307ce0a --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/LinearLayoutWithRecyclerOnScrollListener.java @@ -0,0 +1,91 @@ +package com.ml93.captainmiaoUtil.listener; + +/* + * Copyright (C) 2015 Jorge Castillo Pérez + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * modify from https://github.com/JorgeCastilloPrz/Mirage + */ + + +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/** + * @author Jorge Castillo Pérez + * + * modify at 2015/08/23 + */ +public abstract class LinearLayoutWithRecyclerOnScrollListener extends RecyclerOnScrollListener { + public static String TAG = LinearLayoutWithRecyclerOnScrollListener.class.getSimpleName(); + + + // The minimum amount of items to have below your current scroll position before loading more. + private int visibleThreshold = 1; + int firstVisibleItem, visibleItemCount, totalItemCount; + private LinearLayoutManager mLinearLayoutManager; + + public abstract void onLoadMore(int pagination, int pageSize); + + + public LinearLayoutWithRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager, int pagination, int pageSize) { + this.mLinearLayoutManager = linearLayoutManager; + this.pagination = pagination; + this.pageSize = pageSize; + } + + public LinearLayoutWithRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) { + this.mLinearLayoutManager = linearLayoutManager; + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!isLoading()) { + visibleItemCount = recyclerView.getChildCount(); + totalItemCount = mLinearLayoutManager.getItemCount(); + firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition(); + + //totalItemCount > visibleItemCount load more + if (loadMoreEnable && !loading && totalItemCount > visibleItemCount && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) { + // End has been reached + loading = true; + pagination++; + onLoadMore(pagination, pageSize); + } + } + } + + + public boolean checkCanDoRefresh() { + //fixed https://github.com/captain-miao/RecyclerViewUtils/issues/5 + if(mLinearLayoutManager.getItemCount() == 0) return true; + int firstVisiblePosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + if(firstVisiblePosition == 0) { + View firstVisibleView = mLinearLayoutManager.findViewByPosition(firstVisiblePosition); + int top = firstVisibleView.getTop(); + return top >= 0; + } else { + return false; + } + + //it's also work.(but I can't test enough) + //since support library 22.1, suggest using ViewCompat.canScrollVertically() + //but not recyclerView reference + //return !ViewCompat.canScrollVertically(recyclerView, -1); + } + + +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/OnRecyclerItemClickListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/OnRecyclerItemClickListener.java new file mode 100644 index 00000000..42a88222 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/OnRecyclerItemClickListener.java @@ -0,0 +1,18 @@ +package com.ml93.captainmiaoUtil.listener; + +import android.view.View; + +/** + * @author YanLu + * @since 15/11/1 + */ +public interface OnRecyclerItemClickListener { + /** + * Called when a view has been clicked. + * + * @param v The view that was clicked. + * @param position position at + */ + void onClick(View v, int position); + +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/RecyclerOnScrollListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/RecyclerOnScrollListener.java new file mode 100644 index 00000000..cb33afbf --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/RecyclerOnScrollListener.java @@ -0,0 +1,48 @@ +package com.ml93.captainmiaoUtil.listener; + +import android.support.v7.widget.RecyclerView; + +/** + * @author YanLu + * @since 16/4/23 + */ +public abstract class RecyclerOnScrollListener extends RecyclerView.OnScrollListener{ + + protected boolean loading = false; + protected boolean loadMoreEnable = true; + + protected int pageSize = 15; + protected int pagination = 1; + + public abstract boolean checkCanDoRefresh(); + public abstract void onLoadMore(int pagination, int pageSize); + + + public void loadComplete() { + loading = false; + } + + public synchronized boolean isLoading() { + return loading; + } + + public void setLoadMoreEnable(boolean loadMoreEnable) { + this.loadMoreEnable = loadMoreEnable; + } + + public int getPagination() { + return pagination; + } + + public void setPagination(int pagination) { + this.pagination = pagination; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/RefreshRecyclerViewListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/RefreshRecyclerViewListener.java new file mode 100644 index 00000000..664c6f1f --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/RefreshRecyclerViewListener.java @@ -0,0 +1,21 @@ +package com.ml93.captainmiaoUtil.listener; + +/** + * @author YanLu + * @since 15/11/1 + */ +public interface RefreshRecyclerViewListener { + + /** + * Called when pull to refresh. + */ + void onRefresh(); + + /** + * Called when scroll to recyclerView end. + * + * @param pagination page at + * @param pageSize page size + */ + void onLoadMore(final int pagination, final int pageSize); +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/StaggeredGridWithRecyclerOnScrollListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/StaggeredGridWithRecyclerOnScrollListener.java new file mode 100644 index 00000000..18f40837 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/listener/StaggeredGridWithRecyclerOnScrollListener.java @@ -0,0 +1,53 @@ +package com.ml93.captainmiaoUtil.listener; + + +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; + + +/** + * @author YanLu + * @since 16/4/23 + */ +public abstract class StaggeredGridWithRecyclerOnScrollListener extends RecyclerOnScrollListener { + public static String TAG = StaggeredGridWithRecyclerOnScrollListener.class.getSimpleName(); + + // The minimum amount of items to have below your current scroll position before loading more. + int pastVisibleItems, visibleItemCount, totalItemCount; + private StaggeredGridLayoutManager mLayoutManager; + + public abstract void onLoadMore(int pagination, int pageSize); + + public StaggeredGridWithRecyclerOnScrollListener(StaggeredGridLayoutManager layoutManager, int pagination, int pageSize) { + this.mLayoutManager = layoutManager; + this.pagination = pagination; + this.pageSize = pageSize; + } + public StaggeredGridWithRecyclerOnScrollListener(StaggeredGridLayoutManager layoutManager) { + this.mLayoutManager = layoutManager; + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!isLoading()) { + visibleItemCount = mLayoutManager.getChildCount(); + totalItemCount = mLayoutManager.getItemCount(); + int[] firstVisibleItems = null; + firstVisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItems); + if (firstVisibleItems != null && firstVisibleItems.length > 0) { + pastVisibleItems = firstVisibleItems[0]; + } + + if ((visibleItemCount + pastVisibleItems) >= totalItemCount) { + // End has been reached + loading = true; + pagination++; + onLoadMore(pagination, pageSize); + } + } + } + + public abstract boolean checkCanDoRefresh(); + +} diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/AdGoogleDisplaySupport.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/AdGoogleDisplaySupport.java similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/AdGoogleDisplaySupport.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/AdGoogleDisplaySupport.java index 7ed03991..278de05c 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/AdGoogleDisplaySupport.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/AdGoogleDisplaySupport.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui; +package com.ml93.captainmiaoUtil.ui; import android.app.Activity; import android.support.v4.view.ViewCompat; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/AnimationType.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/AnimationType.java similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/AnimationType.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/AnimationType.java index 79f15d5e..bb2dff8b 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/AnimationType.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/AnimationType.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui; +package com.ml93.captainmiaoUtil.ui; import android.view.animation.OvershootInterpolator; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/CustomPtr.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/CustomPtr.java similarity index 86% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/CustomPtr.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/CustomPtr.java index 2e55362b..2212a336 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/CustomPtr.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/CustomPtr.java @@ -1,10 +1,11 @@ -package com.marshalchen.ultimaterecyclerview.ui; +package com.ml93.captainmiaoUtil.ui; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; -import in.srain.cube.views.ptr.PtrFrameLayout; +import com.insraincubeptr.PtrFrameLayout; + /** * Created by cym on 15/3/21. diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/DividerItemDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/DividerItemDecoration.java similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/DividerItemDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/DividerItemDecoration.java index b3bfd694..e3160741 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/DividerItemDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/DividerItemDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui; +package com.ml93.captainmiaoUtil.ui; import android.content.Context; import android.content.res.TypedArray; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/VerticalSwipeRefreshLayout.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/VerticalSwipeRefreshLayout.java similarity index 96% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/VerticalSwipeRefreshLayout.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/VerticalSwipeRefreshLayout.java index 3acc408f..4ef502fc 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/VerticalSwipeRefreshLayout.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/VerticalSwipeRefreshLayout.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui; +package com.ml93.captainmiaoUtil.ui; import android.content.Context; import android.support.v4.widget.SwipeRefreshLayout; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/emptyview/emptyViewOnShownListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/emptyview/emptyViewOnShownListener.java similarity index 51% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/emptyview/emptyViewOnShownListener.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/emptyview/emptyViewOnShownListener.java index 629ffa61..08756ab7 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/emptyview/emptyViewOnShownListener.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/emptyview/emptyViewOnShownListener.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.emptyview; +package com.ml93.captainmiaoUtil.ui.emptyview; import android.view.View; @@ -6,5 +6,9 @@ * Created by zJJ on 2/19/2016. */ public interface emptyViewOnShownListener { + /** + * on bind empty view to the view by the listener + * @param mView the view + */ void onEmptyViewShow(final View mView); } diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/AddFloatingActionButton.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/AddFloatingActionButton.java old mode 100755 new mode 100644 similarity index 97% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/AddFloatingActionButton.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/AddFloatingActionButton.java index e8181f3b..6e3b6112 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/AddFloatingActionButton.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/AddFloatingActionButton.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton; +package com.ml93.captainmiaoUtil.ui.floatingactionbutton; import android.content.Context; import android.content.res.TypedArray; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/FloatingActionButton.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/FloatingActionButton.java old mode 100755 new mode 100644 similarity index 99% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/FloatingActionButton.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/FloatingActionButton.java index f76c16bd..90f62b39 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/FloatingActionButton.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/FloatingActionButton.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton; +package com.ml93.captainmiaoUtil.ui.floatingactionbutton; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/FloatingActionsMenu.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/FloatingActionsMenu.java old mode 100755 new mode 100644 similarity index 99% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/FloatingActionsMenu.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/FloatingActionsMenu.java index 6e50846a..a4d236ca --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/FloatingActionsMenu.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/FloatingActionsMenu.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton; +package com.ml93.captainmiaoUtil.ui.floatingactionbutton; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/JellyBeanFloatingActionButton.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/JellyBeanFloatingActionButton.java similarity index 96% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/JellyBeanFloatingActionButton.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/JellyBeanFloatingActionButton.java index daed34ee..d09382cd 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/floatingactionbutton/JellyBeanFloatingActionButton.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/floatingactionbutton/JellyBeanFloatingActionButton.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.floatingactionbutton; +package com.ml93.captainmiaoUtil.ui.floatingactionbutton; import android.content.Context; import android.content.res.TypedArray; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/HeaderItemDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/HeaderItemDecoration.java similarity index 96% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/HeaderItemDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/HeaderItemDecoration.java index 49c84af7..6f7e7add 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/HeaderItemDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/HeaderItemDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.header; +package com.ml93.captainmiaoUtil.ui.header; import android.graphics.Rect; import android.support.v7.widget.GridLayoutManager; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/HeaderShadowDecoration.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/HeaderShadowDecoration.java similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/HeaderShadowDecoration.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/HeaderShadowDecoration.java index 99d5034f..8bb24186 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/HeaderShadowDecoration.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/HeaderShadowDecoration.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.header; +package com.ml93.captainmiaoUtil.ui.header; import android.graphics.Canvas; import android.graphics.Color; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/RecyclerViewHeader.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/RecyclerViewHeader.java similarity index 98% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/RecyclerViewHeader.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/RecyclerViewHeader.java index 045f1446..ddc567f3 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/header/RecyclerViewHeader.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/header/RecyclerViewHeader.java @@ -1,10 +1,9 @@ -package com.marshalchen.ultimaterecyclerview.ui.header; +package com.ml93.captainmiaoUtil.ui.header; import android.widget.RelativeLayout; import android.annotation.SuppressLint; import android.content.Context; -import android.graphics.Rect; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.v7.widget.GridLayoutManager; @@ -20,7 +19,6 @@ import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.LinearLayout; -import android.widget.RelativeLayout; /** * Created by hesk on 18/3/16. diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/swipe/SwipeableRecyclerViewTouchListener.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/swipe/SwipeableRecyclerViewTouchListener.java old mode 100755 new mode 100644 similarity index 99% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/swipe/SwipeableRecyclerViewTouchListener.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/swipe/SwipeableRecyclerViewTouchListener.java index 35f5deaa..c4717f52 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/swipe/SwipeableRecyclerViewTouchListener.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/swipe/SwipeableRecyclerViewTouchListener.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.marshalchen.ultimaterecyclerview.ui.swipe; +package com.ml93.captainmiaoUtil.ui.swipe; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/swipe/defaultRegularSwipe.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/swipe/defaultRegularSwipe.java similarity index 86% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/swipe/defaultRegularSwipe.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/swipe/defaultRegularSwipe.java index 86cb919b..00376411 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/swipe/defaultRegularSwipe.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/swipe/defaultRegularSwipe.java @@ -1,10 +1,8 @@ -package com.marshalchen.ultimaterecyclerview.ui.swipe; +package com.ml93.captainmiaoUtil.ui.swipe; import android.support.v7.widget.RecyclerView; -import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter; import com.marshalchen.ultimaterecyclerview.quickAdapter.easyRegularAdapter; -import com.marshalchen.ultimaterecyclerview.swipe.SimpleSwipeListener; /** * Created by hesk on 19/2/16. diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/timelineview/LineType.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/timelineview/LineType.java similarity index 78% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/timelineview/LineType.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/timelineview/LineType.java index f3a5bc6c..fa6553cc 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/timelineview/LineType.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/timelineview/LineType.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.timelineview; +package com.ml93.captainmiaoUtil.ui.timelineview; /** * Created by zJJ on 4/27/2016. diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/timelineview/TimelineView.java b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/timelineview/TimelineView.java similarity index 99% rename from UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/timelineview/TimelineView.java rename to UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/timelineview/TimelineView.java index d696b10e..802d6c5b 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/ui/timelineview/TimelineView.java +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/ml93/captainmiaoUtil/ui/timelineview/TimelineView.java @@ -1,4 +1,4 @@ -package com.marshalchen.ultimaterecyclerview.ui.timelineview; +package com.ml93.captainmiaoUtil.ui.timelineview; import android.content.Context; import android.content.res.TypedArray; diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/drawable-xhdpi/ptr_rotate_arrow.png b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/drawable-xhdpi/ptr_rotate_arrow.png new file mode 100644 index 00000000..c1a49d5c Binary files /dev/null and b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/drawable-xhdpi/ptr_rotate_arrow.png differ diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/cube_ptr_classic_default_header.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/cube_ptr_classic_default_header.xml new file mode 100644 index 00000000..0d56638f --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/cube_ptr_classic_default_header.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/cube_ptr_simple_loading.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/cube_ptr_simple_loading.xml new file mode 100644 index 00000000..d13165be --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/cube_ptr_simple_loading.xml @@ -0,0 +1,8 @@ + + + diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/custom_recycler_view_layout.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/custom_recycler_view_layout.xml deleted file mode 100644 index f773588c..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/custom_recycler_view_layout.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/swipeable_ultimate_recycler_view_layout.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/swipeable_ultimate_recycler_view_layout.xml index 1769fe4f..136af0f2 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/swipeable_ultimate_recycler_view_layout.xml +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/swipeable_ultimate_recycler_view_layout.xml @@ -1,49 +1,25 @@ + android:layout_height="match_parent"> - + - - + android:layout_height="match_parent" + android:focusableInTouchMode="true" /> - + - - - - + android:layout_centerInParent="true" /> \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/ultimate_recycler_view_layout.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/ultimate_recycler_view_layout.xml deleted file mode 100644 index d167f1b8..00000000 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/ultimate_recycler_view_layout.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/urv_normal.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/urv_normal.xml new file mode 100644 index 00000000..4effca29 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/urv_normal.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/urv_ptr.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/urv_ptr.xml new file mode 100644 index 00000000..e9c6ede4 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/urv_ptr.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/vertical_recycler_view.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/vertical_recycler_view.xml index 075fa1e9..9dc32886 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/vertical_recycler_view.xml +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/layout/vertical_recycler_view.xml @@ -1,20 +1,4 @@ - - + + + + + + + + + @@ -88,11 +97,43 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/color.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/color.xml index dfb9ffbc..623e8ba3 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/color.xml +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/color.xml @@ -1,4 +1,7 @@ #994d4d4d + #37000000 + #03000000 + 2dp \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/cube_ptr_string.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/cube_ptr_string.xml new file mode 100644 index 00000000..145a04f7 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/cube_ptr_string.xml @@ -0,0 +1,15 @@ + + + + 下拉 + 下拉刷新 + 释放刷新 + 加载中… + 更新完成. + + 上次更新:  +  秒之前 +  分钟之前 +  小时之前 + + \ No newline at end of file diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/ids.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/ids.xml index 48ae178e..0f3525c7 100755 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/ids.xml +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/ids.xml @@ -11,5 +11,12 @@ + + + + + + + diff --git a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/strings.xml b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/strings.xml index 1b6f0a08..2022875d 100644 --- a/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/strings.xml +++ b/UltimateRecyclerView/ultimaterecyclerview/src/main/res/values/strings.xml @@ -1,3 +1,10 @@ UltimateRecyclerView + + The content view in PtrFrameLayout is empty. Do you forget to specify its id in xml layout file? + + Loading… + Load more + No more data… + diff --git a/UltimateRecyclerView/ultimaterecyclerview/version.properties b/UltimateRecyclerView/ultimaterecyclerview/version.properties new file mode 100644 index 00000000..265b4c37 --- /dev/null +++ b/UltimateRecyclerView/ultimaterecyclerview/version.properties @@ -0,0 +1 @@ +#Fri Apr 07 14:54:27 CST 2017 diff --git a/UpcomingChanges.md b/UpcomingChanges.md index 0f4cd0a8..840df4de 100644 --- a/UpcomingChanges.md +++ b/UpcomingChanges.md @@ -1,26 +1,26 @@ -### Upcoming changes in 0.4.2: - -- [ ] change an other sticky header for optimization -- [ ] setSwipeToDismissCallback() throws a null pointer exception if there is no adapter set; -- [ ] trigger to bring the item back when swipe to dismiss -- [x] auto judge loadmore or header in adatper -- [ ] swipe position judge -- [ ] make ``swapAdapter`` more intelligent -- [ ] Customize height and width -- [ ] Traditional header -- [ ] Swipe to dismiss color -- [x] Make adapter more easy to use -- [x] Expandble feature -- [ ] Change toolbar into CollapsingToolbarLayout -- [ ] Swipe with undo action -- [ ] fix related bugs - -### Other changes: - -* More animations -* add swipe to refresh at the bottom -* etc... - - - -If you have some good idea, please tell us.My email is cymcsg # gmail.com.And it is a good idea to put your idea on the issue. +### Upcoming changes in 0.4.2: + +- [ ] change an other sticky header for optimization +- [ ] setSwipeToDismissCallback() throws a null pointer exception if there is no adapter set; +- [ ] trigger to bring the item back when swipe to dismiss +- [x] auto judge loadmore or header in adatper +- [ ] swipe position judge +- [ ] make ``swapAdapter`` more intelligent +- [ ] Customize height and width +- [ ] Traditional header +- [ ] Swipe to dismiss color +- [x] Make adapter more easy to use +- [x] Expandble feature +- [ ] Change toolbar into CollapsingToolbarLayout +- [ ] Swipe with undo action +- [ ] fix related bugs + +### Other changes: + +* More animations +* add swipe to refresh at the bottom +* etc... + + + +If you have some good idea, please tell us.My email is cymcsg # gmail.com.And it is a good idea to put your idea on the issue.