The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .gitignore
├── .idea
    ├── .name
    ├── compiler.xml
    ├── copyright
    │   └── profiles_settings.xml
    ├── encodings.xml
    ├── gradle.xml
    ├── misc.xml
    ├── modules.xml
    ├── runConfigurations.xml
    └── vcs.xml
├── LICENSE.txt
├── README.md
├── app
    ├── .gitignore
    ├── build.gradle
    ├── proguard-rules.pro
    └── src
    │   ├── androidTest
    │       └── java
    │       │   └── com
    │       │       └── gigamole
    │       │           └── sample
    │       │               └── ApplicationTest.java
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── com
    │           │   └── gigamole
    │           │       └── sample
    │           │           ├── adapters
    │           │               ├── HorizontalPagerAdapter.java
    │           │               ├── MainPagerAdapter.java
    │           │               └── VerticalPagerAdapter.java
    │           │           ├── screens
    │           │               ├── HorizontalPagerFragment.java
    │           │               ├── MainActivity.java
    │           │               ├── TwoWayPagerFragment.java
    │           │               └── VerticalPagerFragment.java
    │           │           └── utils
    │           │               ├── NonScrollableViewPager.java
    │           │               ├── SquareFrameLayout.java
    │           │               ├── TintSelectorImageView.java
    │           │               └── Utils.java
    │       └── res
    │           ├── drawable
    │               ├── bg_main.xml
    │               ├── ic_delivery.png
    │               ├── ic_design.png
    │               ├── ic_development.png
    │               ├── ic_ecommerce.png
    │               ├── ic_fintech.png
    │               ├── ic_internet.png
    │               ├── ic_logo.png
    │               ├── ic_qa.png
    │               ├── ic_social.png
    │               ├── ic_strategy.png
    │               ├── ic_wearable.png
    │               └── overlay_top.xml
    │           ├── layout
    │               ├── activity_main.xml
    │               ├── fragment_horizontal.xml
    │               ├── fragment_two_way.xml
    │               ├── fragment_vertical.xml
    │               ├── item.xml
    │               └── two_way_item.xml
    │           ├── mipmap-hdpi
    │               └── ic_launcher.png
    │           ├── mipmap-mdpi
    │               └── ic_launcher.png
    │           ├── mipmap-xhdpi
    │               └── ic_launcher.png
    │           ├── mipmap-xxhdpi
    │               └── ic_launcher.png
    │           ├── mipmap-xxxhdpi
    │               └── ic_launcher.png
    │           └── values
    │               ├── colors.xml
    │               ├── dimens.xml
    │               ├── strings.xml
    │               └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
    └── wrapper
    │   ├── gradle-wrapper.jar
    │   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── infinitecycleviewpager
    ├── .gitignore
    ├── build.gradle
    ├── proguard-rules.pro
    └── src
    │   ├── androidTest
    │       └── java
    │       │   └── com
    │       │       └── gigamole
    │       │           └── infinitecycleviewpager
    │       │               └── ApplicationTest.java
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── com
    │           │   └── gigamole
    │           │       └── infinitecycleviewpager
    │           │           ├── HorizontalInfiniteCycleViewPager.java
    │           │           ├── InfiniteCycleManager.java
    │           │           ├── InfiniteCyclePagerAdapter.java
    │           │           ├── InfiniteCycleScroller.java
    │           │           ├── OnInfiniteCyclePageTransformListener.java
    │           │           ├── VerticalInfiniteCycleViewPager.java
    │           │           ├── VerticalViewPager.java
    │           │           └── ViewPageable.java
    │       └── res
    │           └── values
    │               ├── attrs.xml
    │               └── strings.xml
└── settings.gradle


/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | 


--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | icvp


--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project version="4">
 3 |   <component name="CompilerConfiguration">
 4 |     <resourceExtensions />
 5 |     <wildcardResourcePatterns>
 6 |       <entry name="!?*.java" />
 7 |       <entry name="!?*.form" />
 8 |       <entry name="!?*.class" />
 9 |       <entry name="!?*.groovy" />
10 |       <entry name="!?*.scala" />
11 |       <entry name="!?*.flex" />
12 |       <entry name="!?*.kt" />
13 |       <entry name="!?*.clj" />
14 |       <entry name="!?*.aj" />
15 |     </wildcardResourcePatterns>
16 |     <annotationProcessing>
17 |       <profile default="true" name="Default" enabled="false">
18 |         <processorPath useClasspath="true" />
19 |       </profile>
20 |     </annotationProcessing>
21 |   </component>
22 | </project>


--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 | <component name="CopyrightManager">
2 |   <settings default="" />
3 | </component>


--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <project version="4">
3 |   <component name="Encoding">
4 |     <file url="PROJECT" charset="UTF-8" />
5 |   </component>
6 | </project>


--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project version="4">
 3 |   <component name="GradleSettings">
 4 |     <option name="linkedExternalProjectsSettings">
 5 |       <GradleProjectSettings>
 6 |         <option name="distributionType" value="LOCAL" />
 7 |         <option name="externalProjectPath" value="$PROJECT_DIR
quot; />
 8 |         <option name="gradleHome" value="D:\Programs\Programming\AndroidStudio\AS\gradle\gradle-2.14.1" />
 9 |         <option name="modules">
10 |           <set>
11 |             <option value="$PROJECT_DIR
quot; />
12 |             <option value="$PROJECT_DIR$/app" />
13 |             <option value="$PROJECT_DIR$/infinitecycleviewpager" />
14 |           </set>
15 |         </option>
16 |         <option name="myModules">
17 |           <set>
18 |             <option value="$PROJECT_DIR
quot; />
19 |             <option value="$PROJECT_DIR$/app" />
20 |             <option value="$PROJECT_DIR$/infinitecycleviewpager" />
21 |           </set>
22 |         </option>
23 |       </GradleProjectSettings>
24 |     </option>
25 |   </component>
26 | </project>


--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project version="4">
 3 |   <component name="NullableNotNullManager">
 4 |     <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
 5 |     <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
 6 |     <option name="myNullables">
 7 |       <value>
 8 |         <list size="4">
 9 |           <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
10 |           <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
11 |           <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
12 |           <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
13 |         </list>
14 |       </value>
15 |     </option>
16 |     <option name="myNotNulls">
17 |       <value>
18 |         <list size="4">
19 |           <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
20 |           <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
21 |           <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
22 |           <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
23 |         </list>
24 |       </value>
25 |     </option>
26 |   </component>
27 |   <component name="ProjectLevelVcsManager" settingsEditedManually="false">
28 |     <OptionsSetting value="true" id="Add" />
29 |     <OptionsSetting value="true" id="Remove" />
30 |     <OptionsSetting value="true" id="Checkout" />
31 |     <OptionsSetting value="true" id="Update" />
32 |     <OptionsSetting value="true" id="Status" />
33 |     <OptionsSetting value="true" id="Edit" />
34 |     <ConfirmationsSetting value="0" id="Add" />
35 |     <ConfirmationsSetting value="0" id="Remove" />
36 |   </component>
37 |   <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
38 |     <output url="file://$PROJECT_DIR$/build/classes" />
39 |   </component>
40 |   <component name="ProjectType">
41 |     <option name="id" value="Android" />
42 |   </component>
43 |   <component name="masterDetails">
44 |     <states>
45 |       <state key="ProjectJDKs.UI">
46 |         <settings>
47 |           <last-edited>1.7</last-edited>
48 |           <splitter-proportions>
49 |             <option name="proportions">
50 |               <list>
51 |                 <option value="0.2" />
52 |               </list>
53 |             </option>
54 |           </splitter-proportions>
55 |         </settings>
56 |       </state>
57 |     </states>
58 |   </component>
59 | </project>


--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project version="4">
 3 |   <component name="ProjectModuleManager">
 4 |     <modules>
 5 |       <module fileurl="file://$PROJECT_DIR$/InfiniteCycleViewPager.iml" filepath="$PROJECT_DIR$/InfiniteCycleViewPager.iml" />
 6 |       <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
 7 |       <module fileurl="file://$PROJECT_DIR$/icvp.iml" filepath="$PROJECT_DIR$/icvp.iml" />
 8 |       <module fileurl="file://$PROJECT_DIR$/infinitecycleviewpager/infinitecycleviewpager.iml" filepath="$PROJECT_DIR$/infinitecycleviewpager/infinitecycleviewpager.iml" />
 9 |     </modules>
10 |   </component>
11 | </project>


--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project version="4">
 3 |   <component name="RunConfigurationProducerService">
 4 |     <option name="ignoredProducers">
 5 |       <set>
 6 |         <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
 7 |         <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
 8 |         <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
 9 |       </set>
10 |     </option>
11 |   </component>
12 | </project>


--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <project version="4">
3 |   <component name="VcsDirectoryMappings">
4 |     <mapping directory="$PROJECT_DIR
quot; vcs="Git" />
5 |   </component>
6 | </project>


--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
  1 | Apache License
  2 |                            Version 2.0, January 2004
  3 |                         http://www.apache.org/licenses/
  4 | 
  5 |    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  6 | 
  7 |    1. Definitions.
  8 | 
  9 |       "License" shall mean the terms and conditions for use, reproduction,
 10 |       and distribution as defined by Sections 1 through 9 of this document.
 11 | 
 12 |       "Licensor" shall mean the copyright owner or entity authorized by
 13 |       the copyright owner that is granting the License.
 14 | 
 15 |       "Legal Entity" shall mean the union of the acting entity and all
 16 |       other entities that control, are controlled by, or are under common
 17 |       control with that entity. For the purposes of this definition,
 18 |       "control" means (i) the power, direct or indirect, to cause the
 19 |       direction or management of such entity, whether by contract or
 20 |       otherwise, or (ii) ownership of fifty percent (50%) or more of the
 21 |       outstanding shares, or (iii) beneficial ownership of such entity.
 22 | 
 23 |       "You" (or "Your") shall mean an individual or Legal Entity
 24 |       exercising permissions granted by this License.
 25 | 
 26 |       "Source" form shall mean the preferred form for making modifications,
 27 |       including but not limited to software source code, documentation
 28 |       source, and configuration files.
 29 | 
 30 |       "Object" form shall mean any form resulting from mechanical
 31 |       transformation or translation of a Source form, including but
 32 |       not limited to compiled object code, generated documentation,
 33 |       and conversions to other media types.
 34 | 
 35 |       "Work" shall mean the work of authorship, whether in Source or
 36 |       Object form, made available under the License, as indicated by a
 37 |       copyright notice that is included in or attached to the work
 38 |       (an example is provided in the Appendix below).
 39 | 
 40 |       "Derivative Works" shall mean any work, whether in Source or Object
 41 |       form, that is based on (or derived from) the Work and for which the
 42 |       editorial revisions, annotations, elaborations, or other modifications
 43 |       represent, as a whole, an original work of authorship. For the purposes
 44 |       of this License, Derivative Works shall not include works that remain
 45 |       separable from, or merely link (or bind by name) to the interfaces of,
 46 |       the Work and Derivative Works thereof.
 47 | 
 48 |       "Contribution" shall mean any work of authorship, including
 49 |       the original version of the Work and any modifications or additions
 50 |       to that Work or Derivative Works thereof, that is intentionally
 51 |       submitted to Licensor for inclusion in the Work by the copyright owner
 52 |       or by an individual or Legal Entity authorized to submit on behalf of
 53 |       the copyright owner. For the purposes of this definition, "submitted"
 54 |       means any form of electronic, verbal, or written communication sent
 55 |       to the Licensor or its representatives, including but not limited to
 56 |       communication on electronic mailing lists, source code control systems,
 57 |       and issue tracking systems that are managed by, or on behalf of, the
 58 |       Licensor for the purpose of discussing and improving the Work, but
 59 |       excluding communication that is conspicuously marked or otherwise
 60 |       designated in writing by the copyright owner as "Not a Contribution."
 61 | 
 62 |       "Contributor" shall mean Licensor and any individual or Legal Entity
 63 |       on behalf of whom a Contribution has been received by Licensor and
 64 |       subsequently incorporated within the Work.
 65 | 
 66 |    2. Grant of Copyright License. Subject to the terms and conditions of
 67 |       this License, each Contributor hereby grants to You a perpetual,
 68 |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 69 |       copyright license to reproduce, prepare Derivative Works of,
 70 |       publicly display, publicly perform, sublicense, and distribute the
 71 |       Work and such Derivative Works in Source or Object form.
 72 | 
 73 |    3. Grant of Patent License. Subject to the terms and conditions of
 74 |       this License, each Contributor hereby grants to You a perpetual,
 75 |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 76 |       (except as stated in this section) patent license to make, have made,
 77 |       use, offer to sell, sell, import, and otherwise transfer the Work,
 78 |       where such license applies only to those patent claims licensable
 79 |       by such Contributor that are necessarily infringed by their
 80 |       Contribution(s) alone or by combination of their Contribution(s)
 81 |       with the Work to which such Contribution(s) was submitted. If You
 82 |       institute patent litigation against any entity (including a
 83 |       cross-claim or counterclaim in a lawsuit) alleging that the Work
 84 |       or a Contribution incorporated within the Work constitutes direct
 85 |       or contributory patent infringement, then any patent licenses
 86 |       granted to You under this License for that Work shall terminate
 87 |       as of the date such litigation is filed.
 88 | 
 89 |    4. Redistribution. You may reproduce and distribute copies of the
 90 |       Work or Derivative Works thereof in any medium, with or without
 91 |       modifications, and in Source or Object form, provided that You
 92 |       meet the following conditions:
 93 | 
 94 |       (a) You must give any other recipients of the Work or
 95 |           Derivative Works a copy of this License; and
 96 | 
 97 |       (b) You must cause any modified files to carry prominent notices
 98 |           stating that You changed the files; and
 99 | 
100 |       (c) You must retain, in the Source form of any Derivative Works
101 |           that You distribute, all copyright, patent, trademark, and
102 |           attribution notices from the Source form of the Work,
103 |           excluding those notices that do not pertain to any part of
104 |           the Derivative Works; and
105 | 
106 |       (d) If the Work includes a "NOTICE" text file as part of its
107 |           distribution, then any Derivative Works that You distribute must
108 |           include a readable copy of the attribution notices contained
109 |           within such NOTICE file, excluding those notices that do not
110 |           pertain to any part of the Derivative Works, in at least one
111 |           of the following places: within a NOTICE text file distributed
112 |           as part of the Derivative Works; within the Source form or
113 |           documentation, if provided along with the Derivative Works; or,
114 |           within a display generated by the Derivative Works, if and
115 |           wherever such third-party notices normally appear. The contents
116 |           of the NOTICE file are for informational purposes only and
117 |           do not modify the License. You may add Your own attribution
118 |           notices within Derivative Works that You distribute, alongside
119 |           or as an addendum to the NOTICE text from the Work, provided
120 |           that such additional attribution notices cannot be construed
121 |           as modifying the License.
122 | 
123 |       You may add Your own copyright statement to Your modifications and
124 |       may provide additional or different license terms and conditions
125 |       for use, reproduction, or distribution of Your modifications, or
126 |       for any such Derivative Works as a whole, provided Your use,
127 |       reproduction, and distribution of the Work otherwise complies with
128 |       the conditions stated in this License.
129 | 
130 |    5. Submission of Contributions. Unless You explicitly state otherwise,
131 |       any Contribution intentionally submitted for inclusion in the Work
132 |       by You to the Licensor shall be under the terms and conditions of
133 |       this License, without any additional terms or conditions.
134 |       Notwithstanding the above, nothing herein shall supersede or modify
135 |       the terms of any separate license agreement you may have executed
136 |       with Licensor regarding such Contributions.
137 | 
138 |    6. Trademarks. This License does not grant permission to use the trade
139 |       names, trademarks, service marks, or product names of the Licensor,
140 |       except as required for reasonable and customary use in describing the
141 |       origin of the Work and reproducing the content of the NOTICE file.
142 | 
143 |    7. Disclaimer of Warranty. Unless required by applicable law or
144 |       agreed to in writing, Licensor provides the Work (and each
145 |       Contributor provides its Contributions) on an "AS IS" BASIS,
146 |       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 |       implied, including, without limitation, any warranties or conditions
148 |       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 |       PARTICULAR PURPOSE. You are solely responsible for determining the
150 |       appropriateness of using or redistributing the Work and assume any
151 |       risks associated with Your exercise of permissions under this License.
152 | 
153 |    8. Limitation of Liability. In no event and under no legal theory,
154 |       whether in tort (including negligence), contract, or otherwise,
155 |       unless required by applicable law (such as deliberate and grossly
156 |       negligent acts) or agreed to in writing, shall any Contributor be
157 |       liable to You for damages, including any direct, indirect, special,
158 |       incidental, or consequential damages of any character arising as a
159 |       result of this License or out of the use or inability to use the
160 |       Work (including but not limited to damages for loss of goodwill,
161 |       work stoppage, computer failure or malfunction, or any and all
162 |       other commercial damages or losses), even if such Contributor
163 |       has been advised of the possibility of such damages.
164 | 
165 |    9. Accepting Warranty or Additional Liability. While redistributing
166 |       the Work or Derivative Works thereof, You may choose to offer,
167 |       and charge a fee for, acceptance of support, warranty, indemnity,
168 |       or other liability obligations and/or rights consistent with this
169 |       License. However, in accepting such obligations, You may act only
170 |       on Your own behalf and on Your sole responsibility, not on behalf
171 |       of any other Contributor, and only if You agree to indemnify,
172 |       defend, and hold each Contributor harmless for any liability
173 |       incurred by, or claims asserted against, such Contributor by reason
174 |       of your accepting any such warranty or additional liability.
175 | 
176 |    END OF TERMS AND CONDITIONS
177 | 
178 |    APPENDIX: How to apply the Apache License to your work.
179 | 
180 |       To apply the Apache License to your work, attach the following
181 |       boilerplate notice, with the fields enclosed by brackets "{}"
182 |       replaced with your own identifying information. (Don't include
183 |       the brackets!)  The text should be enclosed in the appropriate
184 |       comment syntax for the file format. We also recommend that a
185 |       file or class name and description of purpose be included on the
186 |       same "printed page" as the copyright notice for easier
187 |       identification within third-party archives.
188 | 
189 |    Copyright {2016} {Basil Miller}
190 | 
191 |    Licensed under the Apache License, Version 2.0 (the "License");
192 |    you may not use this file except in compliance with the License.
193 |    You may obtain a copy of the License at
194 | 
195 |        http://www.apache.org/licenses/LICENSE-2.0
196 | 
197 |    Unless required by applicable law or agreed to in writing, software
198 |    distributed under the License is distributed on an "AS IS" BASIS,
199 |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 |    See the License for the specific language governing permissions and
201 |    limitations under the License.
202 | 
203 | MIT License (MIT)
204 | 
205 |     Copyright (c) 2016 Basil Miller
206 | 
207 |     Permission is hereby granted, free of charge, to any person obtaining a copy
208 |     of this software and associated documentation files (the "Software"), to deal
209 |     in the Software without restriction, including without limitation the rights
210 |     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
211 |     copies of the Software, and to permit persons to whom the Software is
212 |     furnished to do so, subject to the following conditions:
213 | 
214 |     The above copyright notice and this permission notice shall be included in
215 |     all copies or substantial portions of the Software.
216 | 
217 |     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
218 |     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
219 |     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
220 |     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
221 |     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
222 |     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
223 |     THE SOFTWARE.


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | <br/>
  2 | <p align="center">
  3 |   <a href="http://devlight.io">
  4 |       <img src ="https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScLVBKck51Z1Rzb0E" alt="Devlight"/>
  5 |   </a>
  6 | </p>
  7 | <br/>
  8 | 
  9 | InfiniteCycleViewPager
 10 | ======================
 11 | 
 12 | Infinite cycle ViewPager with two-way orientation and interactive effect.
 13 | 
 14 | [![Android Arsenal](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScbldGMXh5VjBjZEE)](http://android-arsenal.com/details/1/4207)
 15 | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 16 | [![Android](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wSccEZaclNGN0R5OWc)](https://github.com/DevLight-Mobile-Agency)
 17 | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 18 | [![Download](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScTkFkZk1UdEN3MHM)](https://bintray.com/gigamole/maven/infinitecycleviewpager/_latestVersion)
 19 | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 20 | [![License](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScU0tmeFpGMHVWNWs)](https://github.com/DevLight-Mobile-Agency/InfiniteCycleViewPager/blob/master/LICENSE.txt)
 21 | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 22 | [![Codacy](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScSHhmckZyeGJDcXc)](https://www.codacy.com/app/gigamole53/InfiniteCycleViewPager?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=DevLight-Mobile-Agency/InfiniteCycleViewPager&amp;utm_campaign=Badge_Grade)
 23 | 
 24 | <br/>
 25 | 
 26 | <p align="center">
 27 |     <img src="https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScS0hwRTZUaG16Znc"/>
 28 |     &nbsp;
 29 |     <img src="https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScNmRmWXAzRmRwNHM"/>
 30 | </p>
 31 | 
 32 | U can check the sample app [here](https://github.com/DevLight-Mobile-Agency/InfiniteCycleViewPager/tree/master/app).
 33 | 
 34 | Warn
 35 | ====
 36 | ```
 37 | This library is not more supported. 
 38 | If you want to add new feature or fix a bug, grab source code and do it. 
 39 | If you think your fix or feature would be useful to other developers, 
 40 | I can add link of your repository to this README file. 
 41 | Thank you for using our libraries.
 42 | ```
 43 | 
 44 | Download
 45 | ========
 46 | 
 47 | You can download a `.aar` from GitHub's [releases page](https://github.com/DevLight-Mobile-Agency/InfiniteCycleViewPager/releases).
 48 | 
 49 | Or use Gradle:
 50 | 
 51 | ```groovy
 52 | compile 'com.github.devlight:infinitecycleviewpager:1.0.2'
 53 | ```
 54 | 
 55 | Or Maven:
 56 | 
 57 | ```groovy
 58 | <dependency>
 59 |   <groupId>com.github.devlight</groupId>
 60 |   <artifactId>infinitecycleviewpager</artifactId>
 61 |   <version>1.0.2</version>
 62 |   <type>pom</type>
 63 | </dependency>
 64 | ```
 65 | 
 66 | Or Ivy:
 67 | 
 68 | ```groovy
 69 | <dependency org='com.github.devlight' name='infinitecycleviewpager' rev='1.0.2'>
 70 |   <artifact name='$AID' ext='pom'></artifact>
 71 | </dependency>
 72 | ```
 73 | 
 74 | Android SDK Version
 75 | ===================
 76 | 
 77 | `InfiniteCycleViewPager` requires a minimum SDK version of 11. 
 78 | 
 79 | Sample
 80 | ======
 81 | 
 82 | <b>Parameters</b>
 83 | 
 84 | For `InfiniteCycleViewPager` you can set such parameters as:
 85 |  
 86 |  - min scale:  
 87 |      allows you to set the minimum scale of left and right bottom pages.
 88 |     
 89 |  - max scale:  
 90 |      allows you to set the maximum scale of center top page.
 91 |     
 92 |  - min scale offset:  
 93 |      allows you to set offset from edge to minimum scaled pages.
 94 |          
 95 |  - center scale offset:  
 96 |     allows you to set offset from center when two pages appears.
 97 | 
 98 |  - model selected icon:  
 99 |      allows you to set selected icon when current model is active.
100 | 
101 |  - medium scaled:  
102 |      allows you to set is scaling would be min -> max or min -> medium -> max.
103 |     
104 |  - scroll duration:  
105 |      allows you to set snap scrolling duration.
106 |      
107 |  - scroll interpolator:  
108 |      allows you to set snap scrolling interpolator.
109 |     
110 |  - page transform listener:  
111 |      allows you to set page transform listener.
112 |      
113 |  - auto scroll:  
114 |      allows you to set auto scroll in positive and negative directions.
115 |     
116 | <b>Tips</b>
117 | 
118 | Two-way widget need a lot of memory.  
119 | Infinite scroll available when item count more then 2.  
120 | You can set vertical or horizontal infinite cycle ViewPager.
121 | 
122 | <b>Init</b>
123 | 
124 | Check out in code init:
125 | 
126 | ```java
127 | //      final VerticalInfiniteCycleViewPager infiniteCycleViewPager =
128 | //                (VerticalInfiniteCycleViewPager) view.findViewById(R.id.vicvp);
129 |         final HorizontalInfiniteCycleViewPager infiniteCycleViewPager =
130 |                 (HorizontalInfiniteCycleViewPager) view.findViewById(R.id.hicvp);
131 |         infiniteCycleViewPager.setAdapter(...);
132 |         infiniteCycleViewPager.setScrollDuration(500);
133 |         infiniteCycleViewPager.setInterpolator(...);
134 |         infiniteCycleViewPager.setMediumScaled(true);
135 |         infiniteCycleViewPager.setMaxPageScale(0.8F);
136 |         infiniteCycleViewPager.setMinPageScale(0.5F);
137 |         infiniteCycleViewPager.setCenterPageScaleOffset(30.0F);
138 |         infiniteCycleViewPager.setMinPageScaleOffset(5.0F);
139 |         infiniteCycleViewPager.setOnInfiniteCyclePageTransformListener(...);
140 | ```
141 | 
142 | If you want to get item position just call this method:  
143 | ```java
144 | infiniteCycleViewPager.getRealItem();
145 | ```
146 |           
147 | To update your ViewPager after some adapter update or else, you can call this method:  
148 | ```java
149 | infiniteCycleViewPager.notifyDataSetChanged();
150 | ```
151 | 
152 | If you want to start auto scroll or stop call this methods:  
153 | ```java
154 | // true - positive
155 | // false - negative
156 | infiniteCycleViewPager.startAutoScroll(...);
157 | infiniteCycleViewPager.stopAutoScroll();
158 | ```
159 | 
160 | Other methods check out in sample.
161 | 
162 | And XML init:
163 | 
164 | ```xml
165 | 
166 | <!--<com.gigamole.infinitecycleviewpager.VerticalInfiniteCycleViewPager-->
167 | <com.gigamole.infinitecycleviewpager.HorizontalInfiniteCycleViewPager
168 |     android:layout_width="match_parent"
169 |     android:layout_height="match_parent"
170 |     app:icvp_interpolator="..."
171 |     app:icvp_center_page_scale_offset="30dp"
172 |     app:icvp_max_page_scale="0.8"
173 |     app:icvp_medium_scaled="true"
174 |     app:icvp_min_page_scale="0.5"
175 |     app:icvp_min_page_scale_offset="5dp"
176 |     app:icvp_scroll_duration="500"/>
177 | ```
178 | 
179 | Getting Help
180 | ============
181 | 
182 | To report a specific problem or feature request, [open a new issue on Github](https://github.com/DevLight-Mobile-Agency/InfiniteCycleViewPager/issues/new).
183 | 
184 | Xamarin
185 | =======
186 | 
187 | Thanks to [Martijn van Dijk](https://github.com/martijn00) for developing Xamarin bindings library for [InfiniteCycleViewPager](https://github.com/martijn00/InfiniteCycleViewPagerXamarin).  
188 | Plugin is available on [Nuget](https://www.nuget.org/packages/Xam.Plugins.Android.InfiniteCycleViewPager/).
189 | 
190 | Credits
191 | =======
192 | 
193 | |[Yehor Kosinov](https://dribbble.com/Kosinov)|[Prakhar Neel Sharma](https://dribbble.com/prakhar)|
194 | |:-------------------------------------------:|:-------------------------------------------------:|
195 | [![](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScVEZRbk5LaFVzUzQ)](https://dribbble.com/shots/2832006-Cinema-App)|[![](https://d13yacurqjgara.cloudfront.net/users/452635/screenshots/2383427/festival.png)](https://dribbble.com/shots/2383427-Personal-Festival-App-Finally-Done)
196 | 
197 | Author
198 | ======
199 | 
200 | Created by [Basil Miller](https://github.com/GIGAMOLE) - [@gigamole](mailto:gigamole53@gmail.com)
201 | 
202 | Company
203 | =======
204 | 
205 | [![Facebook](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScaGhGVFNKU0VxMnc)](https://www.facebook.com/devlightagency)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[![Twitter](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wScZ1ExQWh5cHF5cVE)](https://twitter.com/DevLightIO)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[![LinkedIn](https://drive.google.com/uc?export=download&id=0BxPO_UeS7wSccGZINzEycE1nVFE)](https://www.linkedin.com/company/devlight)
206 | 
207 | [Here](https://github.com/DevLight-Mobile-Agency) you can see open source work developed by Devlight LLC.  
208 | This and another works is an exclusive property of Devlight LLC. 
209 | 
210 | If you want to use this library in applications which will be available on Google Play, please report us about it or author of the library.
211 | 
212 | Whether you're searching for a new partner or trusted team for creating your new great product we are always ready to start work with you. 
213 | 
214 | You can contact us via info@devlight.io or opensource@devlight.io.  
215 | Thanks in advance.
216 | 
217 | Devlight LLC, 2016  
218 | [devlight.io](http://devlight.io) 
219 | 
220 | 


--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | 


--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'com.android.application'
 2 | 
 3 | android {
 4 |     compileSdkVersion 23
 5 |     buildToolsVersion "23.0.3"
 6 | 
 7 |     defaultConfig {
 8 |         applicationId "com.gigamole.sample"
 9 |         minSdkVersion 11
10 |         targetSdkVersion 23
11 |         versionCode 1
12 |         versionName "1.0"
13 |     }
14 |     buildTypes {
15 |         release {
16 |             minifyEnabled false
17 |             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 |         }
19 |     }
20 | }
21 | 
22 | dependencies {
23 |     compile fileTree(dir: 'libs', include: ['*.jar'])
24 |     compile project(':infinitecycleviewpager')
25 |     compile 'com.android.support:appcompat-v7:23.0.1'
26 |     compile 'com.android.support:cardview-v7:23.0.1'
27 |     compile 'com.android.support:support-v4:23.0.1'
28 |     compile 'com.github.stankoutils:app:1.3.10'
29 |     compile 'com.github.devlight.navigationtabstrip:navigationtabstrip:1.0.4'
30 |     compile 'com.github.bumptech.glide:glide:3.7.0'
31 |     compile 'org.jetbrains:annotations-java5:15.0'
32 | }
33 | 


--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in /Users/GIGAMOLE/Library/Android/sdk/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 


--------------------------------------------------------------------------------
/app/src/androidTest/java/com/gigamole/sample/ApplicationTest.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample;
 2 | 
 3 | import android.app.Application;
 4 | import android.test.ApplicationTestCase;
 5 | 
 6 | /**
 7 |  * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 8 |  */
 9 | public class ApplicationTest extends ApplicationTestCase<Application> {
10 |     public ApplicationTest() {
11 |         super(Application.class);
12 |     }
13 | }


--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3 |           package="com.gigamole.sample">
 4 | 
 5 |     <uses-permission android:name="android.permission.INTERNET" />
 6 | 
 7 |     <application
 8 |         android:allowBackup="true"
 9 |         android:icon="@mipmap/ic_launcher"
10 |         android:label="@string/app_name"
11 |         android:supportsRtl="true"
12 |         android:hardwareAccelerated="true"
13 |         android:theme="@style/AppTheme">
14 |         <activity android:name=".screens.MainActivity">
15 |             <intent-filter>
16 |                 <action android:name="android.intent.action.MAIN"/>
17 | 
18 |                 <category android:name="android.intent.category.LAUNCHER"/>
19 |             </intent-filter>
20 |         </activity>
21 |     </application>
22 | 
23 | </manifest>


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/adapters/HorizontalPagerAdapter.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.adapters;
 2 | 
 3 | import android.content.Context;
 4 | import android.support.v4.view.PagerAdapter;
 5 | import android.view.LayoutInflater;
 6 | import android.view.View;
 7 | import android.view.ViewGroup;
 8 | 
 9 | import com.gigamole.infinitecycleviewpager.VerticalInfiniteCycleViewPager;
10 | import com.gigamole.sample.R;
11 | import com.gigamole.sample.utils.Utils;
12 | 
13 | import static com.gigamole.sample.utils.Utils.setupItem;
14 | 
15 | /**
16 |  * Created by GIGAMOLE on 7/27/16.
17 |  */
18 | public class HorizontalPagerAdapter extends PagerAdapter {
19 | 
20 |     private final Utils.LibraryObject[] LIBRARIES = new Utils.LibraryObject[]{
21 |             new Utils.LibraryObject(
22 |                     R.drawable.ic_strategy,
23 |                     "Strategy"
24 |             ),
25 |             new Utils.LibraryObject(
26 |                     R.drawable.ic_design,
27 |                     "Design"
28 |             ),
29 |             new Utils.LibraryObject(
30 |                     R.drawable.ic_development,
31 |                     "Development"
32 |             ),
33 |             new Utils.LibraryObject(
34 |                     R.drawable.ic_qa,
35 |                     "Quality Assurance"
36 |             )
37 |     };
38 | 
39 |     private Context mContext;
40 |     private LayoutInflater mLayoutInflater;
41 | 
42 |     private boolean mIsTwoWay;
43 | 
44 |     public HorizontalPagerAdapter(final Context context, final boolean isTwoWay) {
45 |         mContext = context;
46 |         mLayoutInflater = LayoutInflater.from(context);
47 |         mIsTwoWay = isTwoWay;
48 |     }
49 | 
50 |     @Override
51 |     public int getCount() {
52 |         return mIsTwoWay ? 6 : LIBRARIES.length;
53 |     }
54 | 
55 |     @Override
56 |     public int getItemPosition(final Object object) {
57 |         return POSITION_NONE;
58 |     }
59 | 
60 |     @Override
61 |     public Object instantiateItem(final ViewGroup container, final int position) {
62 |         final View view;
63 |         if (mIsTwoWay) {
64 |             view = mLayoutInflater.inflate(R.layout.two_way_item, container, false);
65 | 
66 |             final VerticalInfiniteCycleViewPager verticalInfiniteCycleViewPager =
67 |                     (VerticalInfiniteCycleViewPager) view.findViewById(R.id.vicvp);
68 |             verticalInfiniteCycleViewPager.setAdapter(
69 |                     new VerticalPagerAdapter(mContext)
70 |             );
71 |             verticalInfiniteCycleViewPager.setCurrentItem(position);
72 |         } else {
73 |             view = mLayoutInflater.inflate(R.layout.item, container, false);
74 |             setupItem(view, LIBRARIES[position]);
75 |         }
76 | 
77 |         container.addView(view);
78 |         return view;
79 |     }
80 | 
81 |     @Override
82 |     public boolean isViewFromObject(final View view, final Object object) {
83 |         return view.equals(object);
84 |     }
85 | 
86 |     @Override
87 |     public void destroyItem(final ViewGroup container, final int position, final Object object) {
88 |         container.removeView((View) object);
89 |     }
90 | }
91 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/adapters/MainPagerAdapter.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.adapters;
 2 | 
 3 | import android.support.v4.app.Fragment;
 4 | import android.support.v4.app.FragmentManager;
 5 | import android.support.v4.app.FragmentStatePagerAdapter;
 6 | 
 7 | import com.gigamole.sample.screens.HorizontalPagerFragment;
 8 | import com.gigamole.sample.screens.TwoWayPagerFragment;
 9 | 
10 | /**
11 |  * Created by GIGAMOLE on 8/18/16.
12 |  */
13 | public class MainPagerAdapter extends FragmentStatePagerAdapter {
14 | 
15 |     private final static int COUNT = 3;
16 | 
17 |     private final static int HORIZONTAL = 0;
18 |     private final static int TWO_WAY = 1;
19 | 
20 |     public MainPagerAdapter(final FragmentManager fm) {
21 |         super(fm);
22 |     }
23 | 
24 |     @Override
25 |     public Fragment getItem(final int position) {
26 |         switch (position) {
27 |             case TWO_WAY:
28 |                 return new TwoWayPagerFragment();
29 |             case HORIZONTAL:
30 |             default:
31 |                 return new HorizontalPagerFragment();
32 |         }
33 |     }
34 | 
35 |     @Override
36 |     public int getCount() {
37 |         return COUNT;
38 |     }
39 | }
40 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/adapters/VerticalPagerAdapter.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.adapters;
 2 | 
 3 | import android.content.Context;
 4 | import android.support.v4.view.PagerAdapter;
 5 | import android.view.LayoutInflater;
 6 | import android.view.View;
 7 | import android.view.ViewGroup;
 8 | 
 9 | import com.gigamole.sample.R;
10 | import com.gigamole.sample.utils.Utils;
11 | 
12 | import static com.gigamole.sample.utils.Utils.setupItem;
13 | 
14 | /**
15 |  * Created by GIGAMOLE on 7/27/16.
16 |  */
17 | public class VerticalPagerAdapter extends PagerAdapter {
18 | 
19 |     private final Utils.LibraryObject[] TWO_WAY_LIBRARIES = new Utils.LibraryObject[]{
20 |             new Utils.LibraryObject(
21 |                     R.drawable.ic_fintech,
22 |                     "Fintech"
23 |             ),
24 |             new Utils.LibraryObject(
25 |                     R.drawable.ic_delivery,
26 |                     "Delivery"
27 |             ),
28 |             new Utils.LibraryObject(
29 |                     R.drawable.ic_social,
30 |                     "Social network"
31 |             ),
32 |             new Utils.LibraryObject(
33 |                     R.drawable.ic_ecommerce,
34 |                     "E-commerce"
35 |             ),
36 |             new Utils.LibraryObject(
37 |                     R.drawable.ic_wearable,
38 |                     "Wearable"
39 |             ),
40 |             new Utils.LibraryObject(
41 |                     R.drawable.ic_internet,
42 |                     "Internet of things"
43 |             )
44 |     };
45 | 
46 |     private LayoutInflater mLayoutInflater;
47 | 
48 |     public VerticalPagerAdapter(final Context context) {
49 |         mLayoutInflater = LayoutInflater.from(context);
50 |     }
51 | 
52 | 
53 |     @Override
54 |     public int getCount() {
55 |         return TWO_WAY_LIBRARIES.length;
56 |     }
57 | 
58 |     @Override
59 |     public int getItemPosition(final Object object) {
60 |         return POSITION_NONE;
61 |     }
62 | 
63 |     @Override
64 |     public Object instantiateItem(final ViewGroup container, final int position) {
65 |         final View view = mLayoutInflater.inflate(R.layout.item, container, false);
66 | 
67 |         setupItem(view, TWO_WAY_LIBRARIES[position]);
68 | 
69 |         container.addView(view);
70 |         return view;
71 |     }
72 | 
73 |     @Override
74 |     public boolean isViewFromObject(final View view, final Object object) {
75 |         return view.equals(object);
76 |     }
77 | 
78 |     @Override
79 |     public void destroyItem(final ViewGroup container, final int position, final Object object) {
80 |         container.removeView((View) object);
81 |     }
82 | }
83 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/screens/HorizontalPagerFragment.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.screens;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.annotation.Nullable;
 5 | import android.support.v4.app.Fragment;
 6 | import android.view.LayoutInflater;
 7 | import android.view.View;
 8 | import android.view.ViewGroup;
 9 | 
10 | import com.gigamole.infinitecycleviewpager.HorizontalInfiniteCycleViewPager;
11 | import com.gigamole.sample.R;
12 | import com.gigamole.sample.adapters.HorizontalPagerAdapter;
13 | 
14 | /**
15 |  * Created by GIGAMOLE on 8/18/16.
16 |  */
17 | public class HorizontalPagerFragment extends Fragment {
18 | 
19 |     @Nullable
20 |     @Override
21 |     public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
22 |         return inflater.inflate(R.layout.fragment_horizontal, container, false);
23 |     }
24 | 
25 |     @Override
26 |     public void onViewCreated(final View view, @Nullable final Bundle savedInstanceState) {
27 |         super.onViewCreated(view, savedInstanceState);
28 | 
29 |         final HorizontalInfiniteCycleViewPager horizontalInfiniteCycleViewPager =
30 |                 (HorizontalInfiniteCycleViewPager) view.findViewById(R.id.hicvp);
31 |         horizontalInfiniteCycleViewPager.setAdapter(new HorizontalPagerAdapter(getContext(), false));
32 | 
33 | //        horizontalInfiniteCycleViewPager.setScrollDuration(400);
34 | //        horizontalInfiniteCycleViewPager.setPageDuration(1000);
35 | //        horizontalInfiniteCycleViewPager.setInterpolator(
36 | //                AnimationUtils.loadInterpolator(getContext(), android.R.anim.overshoot_interpolator)
37 | //        );
38 | //        horizontalInfiniteCycleViewPager.setMediumScaled(false);
39 | //        horizontalInfiniteCycleViewPager.setMaxPageScale(0.8F);
40 | //        horizontalInfiniteCycleViewPager.setMinPageScale(0.5F);
41 | //        horizontalInfiniteCycleViewPager.setCenterPageScaleOffset(30.0F);
42 | //        horizontalInfiniteCycleViewPager.setMinPageScaleOffset(5.0F);
43 | //        horizontalInfiniteCycleViewPager.setOnInfiniteCyclePageTransformListener();
44 | 
45 | //        horizontalInfiniteCycleViewPager.setCurrentItem(
46 | //                horizontalInfiniteCycleViewPager.getRealItem() + 1
47 | //        );
48 |     }
49 | }
50 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/screens/MainActivity.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.screens;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.v4.view.ViewPager;
 5 | import android.support.v7.app.AppCompatActivity;
 6 | 
 7 | import com.gigamole.navigationtabstrip.NavigationTabStrip;
 8 | import com.gigamole.sample.R;
 9 | import com.gigamole.sample.adapters.MainPagerAdapter;
10 | 
11 | public class MainActivity extends AppCompatActivity {
12 | 
13 |     @Override
14 |     protected void onCreate(Bundle savedInstanceState) {
15 |         super.onCreate(savedInstanceState);
16 |         setContentView(R.layout.activity_main);
17 | 
18 |         final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_main);
19 |         viewPager.setAdapter(new MainPagerAdapter(getSupportFragmentManager()));
20 |         viewPager.setOffscreenPageLimit(2);
21 | 
22 |         final NavigationTabStrip navigationTabStrip = (NavigationTabStrip) findViewById(R.id.nts);
23 |         navigationTabStrip.setTitles("HOW WE WORK", "WE WORK WITH");
24 |         navigationTabStrip.setViewPager(viewPager);
25 |     }
26 | }
27 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/screens/TwoWayPagerFragment.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.screens;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.annotation.Nullable;
 5 | import android.support.v4.app.Fragment;
 6 | import android.view.LayoutInflater;
 7 | import android.view.View;
 8 | import android.view.ViewGroup;
 9 | 
10 | import com.gigamole.infinitecycleviewpager.HorizontalInfiniteCycleViewPager;
11 | import com.gigamole.sample.R;
12 | import com.gigamole.sample.adapters.HorizontalPagerAdapter;
13 | 
14 | /**
15 |  * Created by GIGAMOLE on 8/18/16.
16 |  */
17 | public class TwoWayPagerFragment extends Fragment {
18 | 
19 |     @Nullable
20 |     @Override
21 |     public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
22 |         return inflater.inflate(R.layout.fragment_two_way, container, false);
23 |     }
24 | 
25 |     @Override
26 |     public void onViewCreated(final View view, @Nullable final Bundle savedInstanceState) {
27 |         super.onViewCreated(view, savedInstanceState);
28 | 
29 |         final HorizontalInfiniteCycleViewPager horizontalInfiniteCycleViewPager =
30 |                 (HorizontalInfiniteCycleViewPager) view.findViewById(R.id.hicvp);
31 |         horizontalInfiniteCycleViewPager.setAdapter(new HorizontalPagerAdapter(getContext(), true));
32 | //
33 | //        horizontalInfiniteCycleViewPager.setScrollDuration(500);
34 | //        horizontalInfiniteCycleViewPager.setPageDuration(1000);
35 | //        horizontalInfiniteCycleViewPager.setInterpolator(null);
36 | //        horizontalInfiniteCycleViewPager.setMediumScaled(true);
37 | //        horizontalInfiniteCycleViewPager.setMaxPageScale(1.0F);
38 | //        horizontalInfiniteCycleViewPager.setMinPageScale(0.7F);
39 | //        horizontalInfiniteCycleViewPager.setCenterPageScaleOffset(0.0F);
40 | //        horizontalInfiniteCycleViewPager.setMinPageScaleOffset(0.0F);
41 |     }
42 | }
43 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/screens/VerticalPagerFragment.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.screens;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.annotation.Nullable;
 5 | import android.support.v4.app.Fragment;
 6 | import android.view.LayoutInflater;
 7 | import android.view.View;
 8 | import android.view.ViewGroup;
 9 | 
10 | import com.gigamole.infinitecycleviewpager.VerticalInfiniteCycleViewPager;
11 | import com.gigamole.sample.R;
12 | import com.gigamole.sample.adapters.VerticalPagerAdapter;
13 | 
14 | /**
15 |  * Created by GIGAMOLE on 8/18/16.
16 |  */
17 | public class VerticalPagerFragment extends Fragment {
18 | 
19 |     @Nullable
20 |     @Override
21 |     public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
22 |         return inflater.inflate(R.layout.fragment_vertical, container, false);
23 |     }
24 | 
25 |     @Override
26 |     public void onViewCreated(final View view, @Nullable final Bundle savedInstanceState) {
27 |         super.onViewCreated(view, savedInstanceState);
28 | 
29 |         final VerticalInfiniteCycleViewPager verticalInfiniteCycleViewPager =
30 |                 (VerticalInfiniteCycleViewPager) view.findViewById(R.id.vicvp);
31 |         verticalInfiniteCycleViewPager.setAdapter(new VerticalPagerAdapter(getContext()));
32 | 
33 |         verticalInfiniteCycleViewPager.setScrollDuration(1000);
34 |         verticalInfiniteCycleViewPager.startAutoScroll(true);
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/utils/NonScrollableViewPager.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.utils;
 2 | 
 3 | import android.content.Context;
 4 | import android.support.v4.view.ViewPager;
 5 | import android.util.AttributeSet;
 6 | import android.view.MotionEvent;
 7 | 
 8 | public class NonScrollableViewPager extends ViewPager {
 9 | 
10 |     public NonScrollableViewPager(Context context) {
11 |         super(context);
12 |     }
13 | 
14 |     public NonScrollableViewPager(Context context, AttributeSet attrs) {
15 |         super(context, attrs);
16 |     }
17 | 
18 |     @Override
19 |     public boolean onTouchEvent(MotionEvent ev) {
20 |         return false;
21 |     }
22 | 
23 |     @Override
24 |     public boolean onInterceptTouchEvent(MotionEvent ev) {
25 |         return false;
26 |     }
27 | }


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/utils/SquareFrameLayout.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.utils;
 2 | 
 3 | import android.content.Context;
 4 | import android.util.AttributeSet;
 5 | import android.widget.FrameLayout;
 6 | 
 7 | /**
 8 |  * Created by GIGAMOLE on 8/18/16.
 9 |  */
10 | public class SquareFrameLayout extends FrameLayout {
11 | 
12 |     public SquareFrameLayout(final Context context) {
13 |         super(context);
14 |     }
15 | 
16 |     public SquareFrameLayout(final Context context, final AttributeSet attrs) {
17 |         super(context, attrs);
18 |     }
19 | 
20 |     public SquareFrameLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) {
21 |         super(context, attrs, defStyleAttr);
22 |     }
23 | 
24 |     @Override
25 |     protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
26 |         final int width = MeasureSpec.getSize(widthMeasureSpec);
27 |         final int height = MeasureSpec.getSize(heightMeasureSpec);
28 | 
29 |         if (width < height) {
30 |             setMeasuredDimension(width, width);
31 |             super.onMeasure(widthMeasureSpec, widthMeasureSpec);
32 |         } else {
33 |             setMeasuredDimension(height, height);
34 |             super.onMeasure(heightMeasureSpec, heightMeasureSpec);
35 |         }
36 |     }
37 | }
38 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/utils/TintSelectorImageView.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.utils;
 2 | 
 3 | import android.content.Context;
 4 | import android.graphics.Color;
 5 | import android.graphics.PorterDuff;
 6 | import android.util.AttributeSet;
 7 | import android.view.MotionEvent;
 8 | import android.widget.ImageView;
 9 | 
10 | /**
11 |  * Created by GIGAMOLE on 8/22/16.
12 |  */
13 | public class TintSelectorImageView extends ImageView {
14 | 
15 |     private final static int TINT_SELECTOR_COLOR = Color.parseColor("#506DD3CE");
16 | 
17 |     public TintSelectorImageView(final Context context) {
18 |         super(context);
19 |         setClickable(true);
20 |     }
21 | 
22 |     public TintSelectorImageView(final Context context, final AttributeSet attrs) {
23 |         super(context, attrs);
24 |         setClickable(true);
25 |     }
26 | 
27 |     public TintSelectorImageView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
28 |         super(context, attrs, defStyleAttr);
29 |         setClickable(true);
30 |     }
31 | 
32 |     @Override
33 |     public boolean onTouchEvent(final MotionEvent event) {
34 |         switch (event.getAction()) {
35 |             case MotionEvent.ACTION_DOWN:
36 |             case MotionEvent.ACTION_MOVE:
37 |                 setColorFilter(TINT_SELECTOR_COLOR, PorterDuff.Mode.SRC_OVER);
38 |                 postInvalidate();
39 |                 break;
40 |             case MotionEvent.ACTION_UP:
41 |             case MotionEvent.ACTION_CANCEL:
42 |             case MotionEvent.ACTION_OUTSIDE:
43 |             default:
44 |                 clearColorFilter();
45 |                 postInvalidate();
46 |                 break;
47 |         }
48 | 
49 |         return super.onTouchEvent(event);
50 |     }
51 | 
52 | }
53 | 


--------------------------------------------------------------------------------
/app/src/main/java/com/gigamole/sample/utils/Utils.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.sample.utils;
 2 | 
 3 | import android.view.View;
 4 | import android.widget.ImageView;
 5 | import android.widget.TextView;
 6 | 
 7 | import com.gigamole.sample.R;
 8 | 
 9 | /**
10 |  * Created by GIGAMOLE on 8/18/16.
11 |  */
12 | public class Utils {
13 | 
14 |     public static void setupItem(final View view, final LibraryObject libraryObject) {
15 |         final TextView txt = (TextView) view.findViewById(R.id.txt_item);
16 |         txt.setText(libraryObject.getTitle());
17 | 
18 |         final ImageView img = (ImageView) view.findViewById(R.id.img_item);
19 |         img.setImageResource(libraryObject.getRes());
20 |     }
21 | 
22 |     public static class LibraryObject {
23 | 
24 |         private String mTitle;
25 |         private int mRes;
26 | 
27 |         public LibraryObject(final int res, final String title) {
28 |             mRes = res;
29 |             mTitle = title;
30 |         }
31 | 
32 |         public String getTitle() {
33 |             return mTitle;
34 |         }
35 | 
36 |         public void setTitle(final String title) {
37 |             mTitle = title;
38 |         }
39 | 
40 |         public int getRes() {
41 |             return mRes;
42 |         }
43 | 
44 |         public void setRes(final int res) {
45 |             mRes = res;
46 |         }
47 |     }
48 | }
49 | 


--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_main.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <shape xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     android:dither="true"
 4 |     android:shape="rectangle">
 5 | 
 6 |     <gradient android:angle="270"
 7 |               android:startColor="#00000000"
 8 |               android:type="linear"
 9 |               android:endColor="#37000000"/>
10 | 
11 | </shape>


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delivery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_delivery.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_design.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_design.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_development.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_development.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_ecommerce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_ecommerce.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fintech.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_fintech.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_internet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_internet.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_logo.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_qa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_qa.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_social.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_social.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_strategy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_strategy.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wearable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/drawable/ic_wearable.png


--------------------------------------------------------------------------------
/app/src/main/res/drawable/overlay_top.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <shape xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     android:dither="true"
 4 |     android:shape="rectangle">
 5 | 
 6 |     <gradient android:angle="90"
 7 |               android:startColor="#00ffffff"
 8 |               android:type="linear"
 9 |               android:useLevel="false"
10 |               android:endColor="#ffffffff"/>
11 | 
12 | </shape>


--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <LinearLayout
 3 |     xmlns:android="http://schemas.android.com/apk/res/android"
 4 |     xmlns:app="http://schemas.android.com/apk/res-auto"
 5 |     xmlns:tools="http://schemas.android.com/tools"
 6 |     android:layout_width="match_parent"
 7 |     android:layout_height="match_parent"
 8 |     android:background="#fff"
 9 |     android:clipChildren="false"
10 |     android:clipToPadding="false"
11 |     android:gravity="center"
12 |     android:orientation="vertical"
13 |     tools:context=".screens.MainActivity">
14 | 
15 |     <ImageView
16 |         android:layout_width="wrap_content"
17 |         android:layout_height="56dp"
18 |         android:layout_marginTop="10dp"
19 |         android:adjustViewBounds="true"
20 |         android:padding="8dp"
21 |         android:src="@drawable/ic_logo"/>
22 | 
23 |     <com.gigamole.navigationtabstrip.NavigationTabStrip
24 |         android:id="@+id/nts"
25 |         android:layout_width="match_parent"
26 |         android:layout_height="40dp"
27 |         android:layout_marginEnd="25dp"
28 |         android:layout_marginLeft="25dp"
29 |         android:layout_marginRight="25dp"
30 |         android:layout_marginStart="25dp"
31 |         android:layout_marginTop="10dp"
32 |         app:nts_active_color="@android:color/black"
33 |         app:nts_color="#ffa70b"
34 |         app:nts_gravity="bottom"
35 |         app:nts_inactive_color="@android:color/darker_gray"
36 |         app:nts_size="13sp"
37 |         app:nts_type="line"
38 |         app:nts_weight="3dp"/>
39 | 
40 |     <FrameLayout
41 |         android:layout_width="match_parent"
42 |         android:layout_height="match_parent"
43 |         android:background="@drawable/bg_main">
44 | 
45 |         <com.gigamole.sample.utils.NonScrollableViewPager
46 |             android:id="@+id/vp_main"
47 |             android:layout_width="match_parent"
48 |             android:layout_height="match_parent"/>
49 | 
50 |         <View
51 |             android:layout_width="match_parent"
52 |             android:layout_height="20dp"
53 |             android:background="@drawable/overlay_top"
54 |             android:cacheColorHint="#00000000"/>
55 | 
56 |     </FrameLayout>
57 | 
58 | </LinearLayout>
59 | 


--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_horizontal.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |              android:layout_width="match_parent"
 4 |              android:layout_height="match_parent"
 5 |              xmlns:app="http://schemas.android.com/apk/res-auto">
 6 | 
 7 |     <com.gigamole.infinitecycleviewpager.HorizontalInfiniteCycleViewPager
 8 |         android:id="@+id/hicvp"
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="match_parent"
11 |         app:icvp_interpolator="@android:anim/accelerate_decelerate_interpolator"
12 |         app:icvp_scroll_duration="250"
13 |         app:icvp_center_page_scale_offset="30dp"
14 |         app:icvp_min_page_scale_offset="5dp"
15 |         app:icvp_max_page_scale="0.8"
16 |         app:icvp_min_page_scale="0.55"
17 |         app:icvp_medium_scaled="false"/>
18 | 
19 | </FrameLayout>


--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_two_way.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |              xmlns:app="http://schemas.android.com/apk/res-auto"
 4 |              android:layout_width="match_parent"
 5 |              android:layout_height="match_parent"
 6 |              android:clipChildren="false">
 7 | 
 8 |     <com.gigamole.sample.utils.SquareFrameLayout
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="wrap_content"
11 |         android:layout_gravity="center"
12 |         android:clipChildren="false">
13 | 
14 |         <com.gigamole.infinitecycleviewpager.HorizontalInfiniteCycleViewPager
15 |             android:id="@+id/hicvp"
16 |             android:layout_width="match_parent"
17 |             android:layout_height="match_parent"
18 |             app:icvp_interpolator="@android:anim/accelerate_decelerate_interpolator"
19 |             app:icvp_scroll_duration="250"
20 |             app:icvp_center_page_scale_offset="0dp"
21 |             app:icvp_max_page_scale="1.0"
22 |             app:icvp_medium_scaled="true"
23 |             app:icvp_min_page_scale="0.7"
24 |             app:icvp_min_page_scale_offset="0dp"/>
25 | 
26 |     </com.gigamole.sample.utils.SquareFrameLayout>
27 | 
28 | </FrameLayout>


--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_vertical.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |              xmlns:app="http://schemas.android.com/apk/res-auto"
 4 |              android:layout_width="match_parent"
 5 |              android:layout_height="match_parent"
 6 |              android:clipChildren="false">
 7 | 
 8 |     <com.gigamole.sample.utils.SquareFrameLayout
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="wrap_content"
11 |         android:layout_gravity="center"
12 |         android:clipChildren="false">
13 | 
14 |         <com.gigamole.infinitecycleviewpager.VerticalInfiniteCycleViewPager
15 |             android:id="@+id/vicvp"
16 |             android:layout_width="match_parent"
17 |             android:layout_height="match_parent"
18 |             app:icvp_interpolator="@android:anim/overshoot_interpolator"
19 |             app:icvp_center_page_scale_offset="0dp"
20 |             app:icvp_max_page_scale="0.9"
21 |             app:icvp_medium_scaled="true"
22 |             app:icvp_min_page_scale="0.7"
23 |             app:icvp_min_page_scale_offset="-20dp"
24 |             app:icvp_scroll_duration="600"/>
25 | 
26 |     </com.gigamole.sample.utils.SquareFrameLayout>
27 | 
28 | </FrameLayout>


--------------------------------------------------------------------------------
/app/src/main/res/layout/item.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |              xmlns:app="http://schemas.android.com/apk/res-auto"
 4 |              xmlns:tools="http://schemas.android.com/tools"
 5 |              android:layout_width="match_parent"
 6 |              android:layout_height="match_parent">
 7 | 
 8 |     <android.support.v7.widget.CardView
 9 |         android:layout_width="match_parent"
10 |         android:layout_height="match_parent"
11 |         android:layout_gravity="center"
12 |         app:cardCornerRadius="10dp"
13 |         app:cardElevation="20dp"
14 |         app:cardPreventCornerOverlap="false"
15 |         app:cardUseCompatPadding="true">
16 | 
17 |             <LinearLayout
18 |                 android:layout_width="wrap_content"
19 |                 android:layout_height="wrap_content"
20 |                 android:layout_gravity="center"
21 |                 android:gravity="center"
22 |                 android:orientation="vertical">
23 | 
24 |                 <ImageView
25 |                     android:id="@+id/img_item"
26 |                     android:layout_width="wrap_content"
27 |                     android:layout_height="wrap_content"
28 |                     tools:src="@drawable/ic_delivery"/>
29 | 
30 |                 <TextView
31 |                     android:id="@+id/txt_item"
32 |                     android:layout_width="wrap_content"
33 |                     android:layout_height="wrap_content"
34 |                     android:layout_marginTop="26dp"
35 |                     android:textColor="#005fb0"
36 |                     android:textSize="36sp"
37 |                     android:typeface="sans"
38 |                     tools:text="Delivery"/>
39 | 
40 |             </LinearLayout>
41 | 
42 |     </android.support.v7.widget.CardView>
43 | 
44 | </FrameLayout>


--------------------------------------------------------------------------------
/app/src/main/res/layout/two_way_item.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <com.gigamole.sample.utils.SquareFrameLayout
 3 |     xmlns:android="http://schemas.android.com/apk/res/android"
 4 |     xmlns:app="http://schemas.android.com/apk/res-auto"
 5 |     android:layout_width="match_parent"
 6 |     android:layout_height="match_parent"
 7 |     android:layout_gravity="center"
 8 |     android:clipChildren="false">
 9 | 
10 |     <com.gigamole.infinitecycleviewpager.VerticalInfiniteCycleViewPager
11 |         android:id="@+id/vicvp"
12 |         android:layout_width="match_parent"
13 |         android:layout_height="match_parent"
14 |         app:icvp_center_page_scale_offset="0dp"
15 |         app:icvp_max_page_scale="0.8"
16 |         app:icvp_medium_scaled="true"
17 |         app:icvp_min_page_scale="0.6"
18 |         app:icvp_min_page_scale_offset="0dp"
19 |         app:icvp_interpolator="@android:anim/accelerate_decelerate_interpolator"
20 |         app:icvp_scroll_duration="250"/>
21 | 
22 | </com.gigamole.sample.utils.SquareFrameLayout>


--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/mipmap-hdpi/ic_launcher.png


--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/mipmap-mdpi/ic_launcher.png


--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/mipmap-xhdpi/ic_launcher.png


--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="utf-8"?>
2 | <resources>
3 | </resources>
4 | 


--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 | <resources>
2 | </resources>
3 | 


--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | <resources>
2 |     <string name="app_name">InfinityCycleViewPager</string>
3 | </resources>
4 | 


--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 | <resources>
2 | 
3 |     <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"/>
4 | 
5 | </resources>
6 | 


--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
 2 | 
 3 | buildscript {
 4 |     repositories {
 5 |         jcenter()
 6 |     }
 7 |     dependencies {
 8 |         classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
 9 |         classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.1"
10 |         classpath 'com.android.tools.build:gradle:2.1.3'
11 |     }
12 | }
13 | 
14 | allprojects {
15 |     repositories {
16 |         jcenter()
17 |     }
18 | }
19 | 


--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
 1 | # Project-wide Gradle settings.
 2 | 
 3 | # IDE (e.g. Android Studio) users:
 4 | # Gradle settings configured through the IDE *will override*
 5 | # any settings specified in this file.
 6 | 
 7 | # For more details on how to configure your build environment visit
 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
 9 | 
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 | 
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true


--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devlight/InfiniteCycleViewPager/1038d36cec95c06c3b9b71223c319af7994b9d24/gradle/wrapper/gradle-wrapper.jar


--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Aug 21 09:41:12 EEST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 | 


--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env bash
  2 | 
  3 | ##############################################################################
  4 | ##
  5 | ##  Gradle start up script for UN*X
  6 | ##
  7 | ##############################################################################
  8 | 
  9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 10 | DEFAULT_JVM_OPTS=""
 11 | 
 12 | APP_NAME="Gradle"
 13 | APP_BASE_NAME=`basename "$0"`
 14 | 
 15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
 16 | MAX_FD="maximum"
 17 | 
 18 | warn ( ) {
 19 |     echo "$*"
 20 | }
 21 | 
 22 | die ( ) {
 23 |     echo
 24 |     echo "$*"
 25 |     echo
 26 |     exit 1
 27 | }
 28 | 
 29 | # OS specific support (must be 'true' or 'false').
 30 | cygwin=false
 31 | msys=false
 32 | darwin=false
 33 | case "`uname`" in
 34 |   CYGWIN* )
 35 |     cygwin=true
 36 |     ;;
 37 |   Darwin* )
 38 |     darwin=true
 39 |     ;;
 40 |   MINGW* )
 41 |     msys=true
 42 |     ;;
 43 | esac
 44 | 
 45 | # Attempt to set APP_HOME
 46 | # Resolve links: $0 may be a link
 47 | PRG="$0"
 48 | # Need this for relative symlinks.
 49 | while [ -h "$PRG" ] ; do
 50 |     ls=`ls -ld "$PRG"`
 51 |     link=`expr "$ls" : '.*-> \(.*\)
#39;`
 52 |     if expr "$link" : '/.*' > /dev/null; then
 53 |         PRG="$link"
 54 |     else
 55 |         PRG=`dirname "$PRG"`"/$link"
 56 |     fi
 57 | done
 58 | SAVED="`pwd`"
 59 | cd "`dirname \"$PRG\"`/" >/dev/null
 60 | APP_HOME="`pwd -P`"
 61 | cd "$SAVED" >/dev/null
 62 | 
 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 64 | 
 65 | # Determine the Java command to use to start the JVM.
 66 | if [ -n "$JAVA_HOME" ] ; then
 67 |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 68 |         # IBM's JDK on AIX uses strange locations for the executables
 69 |         JAVACMD="$JAVA_HOME/jre/sh/java"
 70 |     else
 71 |         JAVACMD="$JAVA_HOME/bin/java"
 72 |     fi
 73 |     if [ ! -x "$JAVACMD" ] ; then
 74 |         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
 75 | 
 76 | Please set the JAVA_HOME variable in your environment to match the
 77 | location of your Java installation."
 78 |     fi
 79 | else
 80 |     JAVACMD="java"
 81 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 82 | 
 83 | Please set the JAVA_HOME variable in your environment to match the
 84 | location of your Java installation."
 85 | fi
 86 | 
 87 | # Increase the maximum file descriptors if we can.
 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
 89 |     MAX_FD_LIMIT=`ulimit -H -n`
 90 |     if [ $? -eq 0 ] ; then
 91 |         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
 92 |             MAX_FD="$MAX_FD_LIMIT"
 93 |         fi
 94 |         ulimit -n $MAX_FD
 95 |         if [ $? -ne 0 ] ; then
 96 |             warn "Could not set maximum file descriptor limit: $MAX_FD"
 97 |         fi
 98 |     else
 99 |         warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 |     fi
101 | fi
102 | 
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 |     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 | 
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 |     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 |     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 |     JAVACMD=`cygpath --unix "$JAVACMD"`
113 | 
114 |     # We build the pattern for arguments to be converted via cygpath
115 |     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 |     SEP=""
117 |     for dir in $ROOTDIRSRAW ; do
118 |         ROOTDIRS="$ROOTDIRS$SEP$dir"
119 |         SEP="|"
120 |     done
121 |     OURCYGPATTERN="(^($ROOTDIRS))"
122 |     # Add a user-defined pattern to the cygpath arguments
123 |     if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 |         OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 |     fi
126 |     # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 |     i=0
128 |     for arg in "$@" ; do
129 |         CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 |         CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
131 | 
132 |         if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
133 |             eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 |         else
135 |             eval `echo args$i`="\"$arg\""
136 |         fi
137 |         i=$((i+1))
138 |     done
139 |     case $i in
140 |         (0) set -- ;;
141 |         (1) set -- "$args0" ;;
142 |         (2) set -- "$args0" "$args1" ;;
143 |         (3) set -- "$args0" "$args1" "$args2" ;;
144 |         (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 |         (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 |         (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 |         (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 |         (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 |         (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 |     esac
151 | fi
152 | 
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 |     JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 | 
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 | 


--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
 1 | @if "%DEBUG%" == "" @echo off
 2 | @rem ##########################################################################
 3 | @rem
 4 | @rem  Gradle startup script for Windows
 5 | @rem
 6 | @rem ##########################################################################
 7 | 
 8 | @rem Set local scope for the variables with windows NT shell
 9 | if "%OS%"=="Windows_NT" setlocal
10 | 
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 | 
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 | 
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 | 
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 | 
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 | 
32 | goto fail
33 | 
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 | 
38 | if exist "%JAVA_EXE%" goto init
39 | 
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 | 
46 | goto fail
47 | 
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 | 
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 | 
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 | 
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 | 
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 | 
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 | 
69 | :execute
70 | @rem Setup the command line
71 | 
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 | 
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 | 
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 | 
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 | 
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 | 
90 | :omega
91 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/build.gradle:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (C) 2015 Basil Miller
  3 |  *
  4 |  * Licensed under the Apache License, Version 2.0 (the "License");
  5 |  * you may not use this file except in compliance with the License.
  6 |  * You may obtain a copy of the License at
  7 |  *
  8 |  *      http://www.apache.org/licenses/LICENSE-2.0
  9 |  *
 10 |  * Unless required by applicable law or agreed to in writing, software
 11 |  * distributed under the License is distributed on an "AS IS" BASIS,
 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 |  * See the License for the specific language governing permissions and
 14 |  * limitations under the License.
 15 |  */
 16 | 
 17 | apply plugin: 'com.android.library'
 18 | apply plugin: "com.jfrog.bintray"
 19 | apply plugin: 'com.github.dcendents.android-maven'
 20 | apply plugin: 'maven'
 21 | 
 22 | version = "1.0.2"
 23 | 
 24 | android {
 25 |     compileSdkVersion 23
 26 |     buildToolsVersion "23.0.3"
 27 | 
 28 |     defaultConfig {
 29 |         minSdkVersion 11
 30 |         targetSdkVersion 23
 31 |         versionCode 1
 32 |         versionName "1.0.2"
 33 |     }
 34 |     buildTypes {
 35 |         release {
 36 |             minifyEnabled false
 37 |             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 38 |         }
 39 |     }
 40 | }
 41 | 
 42 | dependencies {
 43 |     compile fileTree(dir: 'libs', include: ['*.jar'])
 44 |     //noinspection GradleDependency
 45 |     compile 'com.android.support:appcompat-v7:23.0.1'
 46 | }
 47 | 
 48 | def siteUrl = 'https://github.com/DevLight-Mobile-Agency/InfiniteCycleViewPager'
 49 | def gitUrl = 'https://github.com/DevLight-Mobile-Agency/InfiniteCycleViewPager.git'
 50 | group = "com.github.devlight"
 51 | 
 52 | install {
 53 |     repositories.mavenInstaller {
 54 |         // This generates POM.xml with proper parameters
 55 |         pom {
 56 |             //noinspection GroovyAssignabilityCheck
 57 |             project {
 58 |                 packaging 'aar'
 59 | 
 60 |                 // Add your description here
 61 |                 //noinspection GroovyAssignabilityCheck
 62 |                 name 'InfiniteCycleViewPager'
 63 |                 description = 'Infinite cycle ViewPager with two-way orientation and interactive effect.'
 64 |                 url siteUrl
 65 | 
 66 |                 // Set your license
 67 |                 licenses {
 68 |                     license {
 69 |                         //noinspection GroovyAssignabilityCheck
 70 |                         name 'The Apache Software License, Version 2.0'
 71 |                         url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
 72 |                     }
 73 |                 }
 74 |                 developers {
 75 |                     developer {
 76 |                         id 'gigamole'
 77 |                         //noinspection GroovyAssignabilityCheck
 78 |                         name 'Basil Miller'
 79 |                         email 'gigamole53@gmail.com'
 80 |                     }
 81 |                 }
 82 |                 scm {
 83 |                     connection gitUrl
 84 |                     developerConnection gitUrl
 85 |                     url siteUrl
 86 |                 }
 87 |             }
 88 |         }
 89 |     }
 90 | }
 91 | 
 92 | task sourcesJar(type: Jar) {
 93 |     //noinspection GroovyAssignabilityCheck
 94 |     from android.sourceSets.main.java.srcDirs
 95 |     classifier = 'sources'
 96 | }
 97 | 
 98 | task javadoc(type: Javadoc) {
 99 |     source = android.sourceSets.main.java.srcDirs
100 |     //noinspection GroovyAssignabilityCheck
101 |     classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
102 | }
103 | 
104 | afterEvaluate {
105 |     javadoc.classpath += files(android.libraryVariants.collect { variant ->
106 |         variant.javaCompile.classpath.files
107 |     })
108 | }
109 | 
110 | task javadocJar(type: Jar, dependsOn: javadoc) {
111 |     classifier = 'javadoc'
112 |     //noinspection GrUnresolvedAccess
113 |     from javadoc.destinationDir
114 | }
115 | artifacts {
116 |     archives javadocJar
117 |     archives sourcesJar
118 | }
119 | 
120 | Properties properties = new Properties()
121 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
122 | 
123 | bintray {
124 |     user = properties.getProperty("bintray.user")
125 |     key = properties.getProperty("bintray.apikey")
126 | 
127 |     configurations = ['archives']
128 |     pkg {
129 |         repo = "maven"
130 |         // it is the name that appears in bintray when logged
131 |         name = "infinitecycleviewpager"
132 |         websiteUrl = siteUrl
133 |         vcsUrl = gitUrl
134 |         licenses = ["Apache-2.0"]
135 |         publish = true
136 |         //noinspection GroovyAssignabilityCheck
137 |         version {
138 |             gpg {
139 |                 sign = true //Determines whether to GPG sign the files. The default is false
140 |                 passphrase = properties.getProperty("bintray.gpg.password")
141 |                 //Optional. The passphrase for GPG signing'
142 |             }
143 | //            mavenCentralSync {
144 | //                sync = true //Optional (true by default). Determines whether to sync the version to Maven Central.
145 | //                user = properties.getProperty("bintray.oss.user") //OSS user token
146 | //                password = properties.getProperty("bintray.oss.password") //OSS user password
147 | //                close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually.
148 | //            }
149 |         }
150 |     }
151 | }


--------------------------------------------------------------------------------
/infinitecycleviewpager/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in /Users/GIGAMOLE/Library/Android/sdk/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/androidTest/java/com/gigamole/infinitecycleviewpager/ApplicationTest.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.infinitecycleviewpager;
 2 | 
 3 | import android.app.Application;
 4 | import android.test.ApplicationTestCase;
 5 | 
 6 | /**
 7 |  * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 8 |  */
 9 | public class ApplicationTest extends ApplicationTestCase<Application> {
10 |     public ApplicationTest() {
11 |         super(Application.class);
12 |     }
13 | }


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 |           package="com.gigamole.infinitecycleviewpager"/>
3 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/HorizontalInfiniteCycleViewPager.java:
--------------------------------------------------------------------------------
  1 | package com.gigamole.infinitecycleviewpager;
  2 | 
  3 | import android.content.Context;
  4 | import android.support.v4.view.PagerAdapter;
  5 | import android.support.v4.view.ViewPager;
  6 | import android.util.AttributeSet;
  7 | import android.view.MotionEvent;
  8 | import android.view.View;
  9 | import android.view.ViewGroup;
 10 | import android.view.animation.Interpolator;
 11 | 
 12 | /**
 13 |  * Created by GIGAMOLE on 7/27/16.
 14 |  */
 15 | public class HorizontalInfiniteCycleViewPager extends ViewPager implements ViewPageable {
 16 | 
 17 |     private InfiniteCycleManager mInfiniteCycleManager;
 18 | 
 19 |     public HorizontalInfiniteCycleViewPager(final Context context) {
 20 |         super(context);
 21 |         init(context, null);
 22 |     }
 23 | 
 24 |     public HorizontalInfiniteCycleViewPager(final Context context, final AttributeSet attrs) {
 25 |         super(context, attrs);
 26 |         init(context, attrs);
 27 |     }
 28 | 
 29 |     private void init(final Context context, final AttributeSet attributeSet) {
 30 |         mInfiniteCycleManager = new InfiniteCycleManager(context, this, attributeSet);
 31 |     }
 32 | 
 33 |     public float getMinPageScaleOffset() {
 34 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getMinPageScaleOffset();
 35 |     }
 36 | 
 37 |     public void setMinPageScaleOffset(final float minPageScaleOffset) {
 38 |         if (mInfiniteCycleManager != null)
 39 |             mInfiniteCycleManager.setMinPageScaleOffset(minPageScaleOffset);
 40 |     }
 41 | 
 42 |     public float getCenterPageScaleOffset() {
 43 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getCenterPageScaleOffset();
 44 |     }
 45 | 
 46 |     public void setCenterPageScaleOffset(final float centerPageScaleOffset) {
 47 |         if (mInfiniteCycleManager != null)
 48 |             mInfiniteCycleManager.setCenterPageScaleOffset(centerPageScaleOffset);
 49 |     }
 50 | 
 51 |     public float getMinPageScale() {
 52 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getMinPageScale();
 53 |     }
 54 | 
 55 |     public void setMinPageScale(final float minPageScale) {
 56 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setMinPageScale(minPageScale);
 57 |     }
 58 | 
 59 |     public float getMaxPageScale() {
 60 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getMaxPageScale();
 61 |     }
 62 | 
 63 |     public void setMaxPageScale(final float maxPageScale) {
 64 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setMaxPageScale(maxPageScale);
 65 |     }
 66 | 
 67 |     public boolean isMediumScaled() {
 68 |         return mInfiniteCycleManager != null && mInfiniteCycleManager.isMediumScaled();
 69 |     }
 70 | 
 71 |     public void setMediumScaled(final boolean mediumScaled) {
 72 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setMediumScaled(mediumScaled);
 73 |     }
 74 | 
 75 |     public int getScrollDuration() {
 76 |         return mInfiniteCycleManager == null ? 0 : mInfiniteCycleManager.getScrollDuration();
 77 |     }
 78 | 
 79 |     public void setScrollDuration(final int scrollDuration) {
 80 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setScrollDuration(scrollDuration);
 81 |     }
 82 | 
 83 |     public int getPageDuration() {
 84 |         return mInfiniteCycleManager == null ? 0 : mInfiniteCycleManager.getPageDuration();
 85 |     }
 86 | 
 87 |     public void setPageDuration(final int pageDuration) {
 88 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setPageDuration(pageDuration);
 89 |     }
 90 | 
 91 |     public Interpolator getInterpolator() {
 92 |         return mInfiniteCycleManager == null ? null : mInfiniteCycleManager.getInterpolator();
 93 |     }
 94 | 
 95 |     public void setInterpolator(final Interpolator interpolator) {
 96 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setInterpolator(interpolator);
 97 |     }
 98 | 
 99 |     public boolean isVertical() {
100 |         return mInfiniteCycleManager != null && mInfiniteCycleManager.isVertical();
101 |     }
102 | 
103 |     public OnInfiniteCyclePageTransformListener getOnInfiniteCyclePageTransformListener() {
104 |         return mInfiniteCycleManager == null ?
105 |                 null : mInfiniteCycleManager.getOnInfiniteCyclePageTransformListener();
106 |     }
107 | 
108 |     public void setOnInfiniteCyclePageTransformListener(
109 |             final OnInfiniteCyclePageTransformListener onInfiniteCyclePageTransformListener
110 |     ) {
111 |         if (mInfiniteCycleManager != null)
112 |             mInfiniteCycleManager.setOnInfiniteCyclePageTransformListener(onInfiniteCyclePageTransformListener);
113 |     }
114 | 
115 |     @Override
116 |     public void setPageTransformer(final boolean reverseDrawingOrder, final PageTransformer transformer) {
117 |         super.setPageTransformer(
118 |                 false, mInfiniteCycleManager == null ?
119 |                         transformer : mInfiniteCycleManager.getInfinityCyclePageTransformer()
120 |         );
121 |     }
122 | 
123 |     @Override
124 |     protected void setChildrenDrawingOrderEnabled(final boolean enabled) {
125 |         super.setChildrenDrawingOrderEnabled(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
126 |     }
127 | 
128 |     @Override
129 |     public void setClipChildren(final boolean clipChildren) {
130 |         super.setClipChildren(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
131 |     }
132 | 
133 |     @Override
134 |     public void setDrawingCacheEnabled(final boolean enabled) {
135 |         super.setDrawingCacheEnabled(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
136 |     }
137 | 
138 |     @Override
139 |     protected void setChildrenDrawingCacheEnabled(final boolean enabled) {
140 |         super.setChildrenDrawingCacheEnabled(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
141 |     }
142 | 
143 |     @Override
144 |     public void setWillNotCacheDrawing(final boolean willNotCacheDrawing) {
145 |         super.setWillNotCacheDrawing(InfiniteCycleManager.DEFAULT_ENABLE_FLAG);
146 |     }
147 | 
148 |     @Override
149 |     public void setPageMargin(final int marginPixels) {
150 |         super.setPageMargin(InfiniteCycleManager.DEFAULT_PAGE_MARGIN);
151 |     }
152 | 
153 |     @Override
154 |     public void setOffscreenPageLimit(final int limit) {
155 |         super.setOffscreenPageLimit(InfiniteCycleManager.DEFAULT_OFFSCREEN_PAGE_LIMIT);
156 |     }
157 | 
158 |     @Override
159 |     public void setOverScrollMode(final int overScrollMode) {
160 |         super.setOverScrollMode(OVER_SCROLL_NEVER);
161 |     }
162 | 
163 |     @Override
164 |     protected boolean addViewInLayout(final View child, final int index, final ViewGroup.LayoutParams params) {
165 |         return super.addViewInLayout(child, 0, params);
166 |     }
167 | 
168 |     @Override
169 |     public void addView(final View child, final int index, final ViewGroup.LayoutParams params) {
170 |         super.addView(child, 0, params);
171 |     }
172 | 
173 |     @Override
174 |     public void setAdapter(final PagerAdapter adapter) {
175 |         if (mInfiniteCycleManager == null) super.setAdapter(adapter);
176 |         else {
177 |             super.setAdapter(mInfiniteCycleManager.setAdapter(adapter));
178 |             mInfiniteCycleManager.resetPager();
179 |         }
180 |     }
181 | 
182 |     @Override
183 |     public PagerAdapter getAdapter() {
184 |         if (mInfiniteCycleManager == null) return super.getAdapter();
185 |         return mInfiniteCycleManager.getInfiniteCyclePagerAdapter() == null ? super.getAdapter() :
186 |                 mInfiniteCycleManager.getInfiniteCyclePagerAdapter().getPagerAdapter();
187 |     }
188 | 
189 |     @Override
190 |     public boolean onTouchEvent(final MotionEvent ev) {
191 |         try {
192 |             return mInfiniteCycleManager == null ? super.onTouchEvent(ev) :
193 |                     mInfiniteCycleManager.onTouchEvent(ev) && super.onTouchEvent(ev);
194 |         } catch (IllegalArgumentException e) {
195 |             return true;
196 |         }
197 |     }
198 | 
199 |     @Override
200 |     public boolean onInterceptTouchEvent(final MotionEvent ev) {
201 |         try {
202 |             return mInfiniteCycleManager == null ? super.onInterceptTouchEvent(ev) :
203 |                     mInfiniteCycleManager.onInterceptTouchEvent(ev) && super.onInterceptTouchEvent(ev);
204 |         } catch (IllegalArgumentException e) {
205 |             return true;
206 |         }
207 |     }
208 | 
209 |     @Override
210 |     public void onWindowFocusChanged(final boolean hasWindowFocus) {
211 |         if (mInfiniteCycleManager != null)
212 |             mInfiniteCycleManager.onWindowFocusChanged(hasWindowFocus);
213 |         super.onWindowFocusChanged(hasWindowFocus);
214 |     }
215 | 
216 |     @Override
217 |     protected void onDetachedFromWindow() {
218 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.stopAutoScroll();
219 |         super.onDetachedFromWindow();
220 |     }
221 | 
222 |     @Override
223 |     public void setCurrentItem(final int item) {
224 |         setCurrentItem(item, true);
225 |     }
226 | 
227 |     @Override
228 |     public void setCurrentItem(final int item, final boolean smoothScroll) {
229 |         if (mInfiniteCycleManager != null)
230 |             super.setCurrentItem(mInfiniteCycleManager.setCurrentItem(item), true);
231 |     }
232 | 
233 |     public int getRealItem() {
234 |         return mInfiniteCycleManager == null ?
235 |                 getCurrentItem() : mInfiniteCycleManager.getRealItem();
236 |     }
237 | 
238 |     public int getState() {
239 |         return mInfiniteCycleManager == null ?
240 |                 ViewPager.SCROLL_STATE_IDLE : mInfiniteCycleManager.getState();
241 |     }
242 | 
243 |     public void notifyDataSetChanged() {
244 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.notifyDataSetChanged();
245 |     }
246 | 
247 |     public void invalidateTransformer() {
248 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.invalidateTransformer();
249 |     }
250 | 
251 |     public void postInvalidateTransformer() {
252 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.postInvalidateTransformer();
253 |     }
254 | 
255 |     public void startAutoScroll(final boolean isAutoScrollPositive) {
256 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.startAutoScroll(isAutoScrollPositive);
257 |     }
258 | 
259 |     public void stopAutoScroll() {
260 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.stopAutoScroll();
261 |     }
262 | }
263 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/InfiniteCycleManager.java:
--------------------------------------------------------------------------------
  1 | package com.gigamole.infinitecycleviewpager;
  2 | 
  3 | import android.content.Context;
  4 | import android.content.res.Resources;
  5 | import android.content.res.TypedArray;
  6 | import android.graphics.Rect;
  7 | import android.os.Build;
  8 | import android.os.Handler;
  9 | import android.support.v4.view.PagerAdapter;
 10 | import android.support.v4.view.ViewCompat;
 11 | import android.support.v4.view.ViewPager;
 12 | import android.util.AttributeSet;
 13 | import android.view.MotionEvent;
 14 | import android.view.View;
 15 | import android.view.animation.AnimationUtils;
 16 | import android.view.animation.Interpolator;
 17 | 
 18 | import java.lang.reflect.Field;
 19 | 
 20 | import static android.support.v4.view.ViewPager.GONE;
 21 | import static android.support.v4.view.ViewPager.OnPageChangeListener;
 22 | import static android.support.v4.view.ViewPager.PageTransformer;
 23 | import static android.support.v4.view.ViewPager.VISIBLE;
 24 | import static android.view.View.OVER_SCROLL_NEVER;
 25 | import static com.gigamole.infinitecycleviewpager.InfiniteCyclePagerAdapter.OnNotifyDataSetChangedListener;
 26 | 
 27 | /**
 28 |  * Created by GIGAMOLE on 7/27/16.
 29 |  */
 30 | @SuppressWarnings("unused")
 31 | class InfiniteCycleManager implements OnNotifyDataSetChangedListener {
 32 | 
 33 |     // InfiniteCycleManager constants
 34 |     private final static int MIN_CYCLE_COUNT = 3;
 35 |     private final static int MIN_POINTER_COUNT = 1;
 36 | 
 37 |     // Default ViewPager constants and flags
 38 |     protected final static int DEFAULT_OFFSCREEN_PAGE_LIMIT = 2;
 39 |     protected final static int DEFAULT_PAGE_MARGIN = 0;
 40 |     protected final static boolean DEFAULT_DISABLE_FLAG = false;
 41 |     protected final static boolean DEFAULT_ENABLE_FLAG = true;
 42 | 
 43 |     // Default attributes constants
 44 |     private final static float DEFAULT_MIN_SCALE = 0.55F;
 45 |     private final static float DEFAULT_MAX_SCALE = 0.8F;
 46 |     private final static int DEFAULT_MIN_PAGE_SCALE_OFFSET = 30;
 47 |     private final static int DEFAULT_CENTER_PAGE_SCALE_OFFSET = 50;
 48 |     private final static boolean DEFAULT_IS_MEDIUM_SCALED = true;
 49 |     private final static int DEFAULT_SCROLL_DURATION = 500;
 50 | 
 51 |     private Context mContext;
 52 | 
 53 |     // Infinite ViewPager and adapter
 54 |     private ViewPageable mViewPageable;
 55 |     private View mCastViewPageable;
 56 |     private InfiniteCyclePagerAdapter mInfiniteCyclePagerAdapter;
 57 | 
 58 |     // Inner and outer state of scrolling
 59 |     private PageScrolledState mInnerPageScrolledState = PageScrolledState.IDLE;
 60 |     private PageScrolledState mOuterPageScrolledState = PageScrolledState.IDLE;
 61 | 
 62 |     // Page scrolled info positions
 63 |     private float mPageScrolledPositionOffset;
 64 |     private float mPageScrolledPosition;
 65 | 
 66 |     // When item count equals to 3 we need stack count for know is item on position -2 or 2 is placed
 67 |     private int mStackCount;
 68 |     // Item count of original adapter
 69 |     private int mItemCount;
 70 | 
 71 |     // Flag to know is left page need bring to front for correct scrolling present
 72 |     private boolean mIsLeftPageBringToFront;
 73 |     // Flag to know is right page need bring to front for correct scrolling present
 74 |     private boolean mIsRightPageBringToFront;
 75 |     // Detect if was minus one position of transform page for correct handle of page bring to front
 76 |     private boolean mWasMinusOne;
 77 |     // Detect if was plus one position of transform page for correct handle of page bring to front
 78 |     private boolean mWasPlusOne;
 79 | 
 80 |     // Hit rect of view bounds to detect inside touch
 81 |     private final Rect mHitRect = new Rect();
 82 | 
 83 |     // Flag for invalidate transformer side scroll when use setCurrentItem() method
 84 |     private boolean mIsInitialItem;
 85 |     // Flag for setCurrentItem to zero of half the virtual count when set adapter
 86 |     private boolean mIsAdapterInitialPosition;
 87 |     // Flag for data set changed callback to invalidateTransformer()
 88 |     private boolean mIsDataSetChanged;
 89 |     // Detect is ViewPager state
 90 |     private int mState;
 91 | 
 92 |     // Custom transform listener
 93 |     private OnInfiniteCyclePageTransformListener mOnInfiniteCyclePageTransformListener;
 94 | 
 95 |     // Page scale offset at minimum scale(left and right bottom pages)
 96 |     private float mMinPageScaleOffset;
 97 |     // Page scale offset at maximum scale(center top page)
 98 |     private float mCenterPageScaleOffset;
 99 | 
100 |     // Minimum page scale(left and right pages)
101 |     private float mMinPageScale;
102 |     // Maximum page scale(center page)
103 |     private float mMaxPageScale;
104 |     // Center scale by when scroll position is on half
105 |     private float mCenterScaleBy;
106 | 
107 |     // Use medium scale or just from max to min
108 |     private boolean mIsMediumScaled = false;
109 |     // Detect is vertical orientation
110 |     private boolean mIsVertical;
111 | 
112 |     // Scroll duration of snapping
113 |     private int mScrollDuration;
114 |     // Duration for which a page will be shown before moving on to next one when {@link mIsAutoScroll} is TRUE
115 |     private int mPageDuration;
116 |     // Interpolator of snapping
117 |     private Interpolator mInterpolator;
118 | 
119 |     // Auto scroll values
120 |     private boolean mIsAutoScroll;
121 |     private boolean mIsAutoScrollPositive;
122 |     // Auto scroll handlers
123 |     private final Handler mAutoScrollHandler = new Handler();
124 |     private final Runnable mAutoScrollRunnable = new Runnable() {
125 |         @Override
126 |         public void run() {
127 |             if (!mIsAutoScroll) return;
128 |             mViewPageable.setCurrentItem(getRealItem() + (mIsAutoScrollPositive ? 1 : -1));
129 |             mAutoScrollHandler.postDelayed(this, mPageDuration);
130 |         }
131 |     };
132 | 
133 |     public InfiniteCycleManager(
134 |             final Context context,
135 |             final ViewPageable viewPageable,
136 |             final AttributeSet attributeSet
137 |     ) {
138 |         mContext = context;
139 |         mIsVertical = viewPageable instanceof VerticalViewPager;
140 | 
141 |         mViewPageable = viewPageable;
142 |         mCastViewPageable = (View) viewPageable;
143 | 
144 |         // Set default InfiniteViewPager
145 |         mViewPageable.setPageTransformer(false, getInfinityCyclePageTransformer());
146 |         mViewPageable.addOnPageChangeListener(mInfinityCyclePageChangeListener);
147 |         mViewPageable.setClipChildren(DEFAULT_DISABLE_FLAG);
148 |         mViewPageable.setDrawingCacheEnabled(DEFAULT_DISABLE_FLAG);
149 |         mViewPageable.setWillNotCacheDrawing(DEFAULT_ENABLE_FLAG);
150 |         mViewPageable.setPageMargin(DEFAULT_PAGE_MARGIN);
151 |         mViewPageable.setOffscreenPageLimit(DEFAULT_OFFSCREEN_PAGE_LIMIT);
152 |         mViewPageable.setOverScrollMode(OVER_SCROLL_NEVER);
153 | 
154 |         // Reset scroller and process attribute set
155 |         resetScroller();
156 |         processAttributeSet(attributeSet);
157 |     }
158 | 
159 |     public void processAttributeSet(final AttributeSet attributeSet) {
160 |         if (attributeSet == null) return;
161 |         final TypedArray typedArray = mContext.obtainStyledAttributes(
162 |                 attributeSet, mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager :
163 |                         R.styleable.HorizontalInfiniteCycleViewPager
164 |         );
165 |         try {
166 |             setMinPageScaleOffset(
167 |                     typedArray.getDimension(
168 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_min_page_scale_offset :
169 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_min_page_scale_offset,
170 |                             DEFAULT_MIN_PAGE_SCALE_OFFSET
171 |                     )
172 |             );
173 |             setCenterPageScaleOffset(
174 |                     typedArray.getDimension(
175 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_center_page_scale_offset :
176 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_center_page_scale_offset,
177 |                             DEFAULT_CENTER_PAGE_SCALE_OFFSET
178 |                     )
179 |             );
180 |             setMinPageScale(
181 |                     typedArray.getFloat(
182 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_min_page_scale :
183 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_min_page_scale,
184 |                             DEFAULT_MIN_SCALE
185 |                     )
186 |             );
187 |             setMaxPageScale(
188 |                     typedArray.getFloat(
189 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_max_page_scale :
190 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_max_page_scale,
191 |                             DEFAULT_MAX_SCALE
192 |                     )
193 |             );
194 |             setMediumScaled(
195 |                     typedArray.getBoolean(
196 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_medium_scaled :
197 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_medium_scaled,
198 |                             DEFAULT_IS_MEDIUM_SCALED
199 |                     )
200 |             );
201 |             setScrollDuration(
202 |                     typedArray.getInteger(
203 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_scroll_duration :
204 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_scroll_duration,
205 |                             DEFAULT_SCROLL_DURATION
206 |                     )
207 |             );
208 |             setPageDuration(
209 |                     typedArray.getInteger(
210 |                             mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_page_duration :
211 |                                     R.styleable.HorizontalInfiniteCycleViewPager_icvp_page_duration,
212 |                             DEFAULT_SCROLL_DURATION
213 |                     )
214 |             );
215 | 
216 |             // Retrieve interpolator
217 |             Interpolator interpolator = null;
218 |             try {
219 |                 final int interpolatorId = typedArray.getResourceId(
220 |                         mIsVertical ? R.styleable.VerticalInfiniteCycleViewPager_icvp_interpolator :
221 |                                 R.styleable.HorizontalInfiniteCycleViewPager_icvp_interpolator, 0
222 |                 );
223 |                 interpolator = interpolatorId == 0 ? null :
224 |                         AnimationUtils.loadInterpolator(mContext, interpolatorId);
225 |             } catch (Resources.NotFoundException exception) {
226 |                 interpolator = null;
227 |                 exception.printStackTrace();
228 |             } finally {
229 |                 setInterpolator(interpolator);
230 |             }
231 |         } finally {
232 |             typedArray.recycle();
233 |         }
234 |     }
235 | 
236 |     public float getMinPageScaleOffset() {
237 |         return mMinPageScaleOffset;
238 |     }
239 | 
240 |     public void setMinPageScaleOffset(final float minPageScaleOffset) {
241 |         mMinPageScaleOffset = minPageScaleOffset;
242 |     }
243 | 
244 |     public float getCenterPageScaleOffset() {
245 |         return mCenterPageScaleOffset;
246 |     }
247 | 
248 |     public void setCenterPageScaleOffset(final float centerPageScaleOffset) {
249 |         mCenterPageScaleOffset = centerPageScaleOffset;
250 |     }
251 | 
252 |     public float getMinPageScale() {
253 |         return mMinPageScale;
254 |     }
255 | 
256 |     public void setMinPageScale(final float minPageScale) {
257 |         mMinPageScale = minPageScale;
258 |         resetScaleBy();
259 |     }
260 | 
261 |     public float getMaxPageScale() {
262 |         return mMaxPageScale;
263 |     }
264 | 
265 |     public void setMaxPageScale(final float maxPageScale) {
266 |         mMaxPageScale = maxPageScale;
267 |         resetScaleBy();
268 |     }
269 | 
270 |     public boolean isMediumScaled() {
271 |         return mIsMediumScaled;
272 |     }
273 | 
274 |     public void setMediumScaled(final boolean mediumScaled) {
275 |         mIsMediumScaled = mediumScaled;
276 |     }
277 | 
278 |     public int getScrollDuration() {
279 |         return mScrollDuration;
280 |     }
281 | 
282 |     public void setScrollDuration(final int scrollDuration) {
283 |         mScrollDuration = scrollDuration;
284 |         resetScroller();
285 |     }
286 | 
287 |     public int getPageDuration() {
288 |         return mPageDuration;
289 |     }
290 | 
291 |     public void setPageDuration(final int pageDuration) {
292 |         mPageDuration = pageDuration;
293 |         resetScroller();
294 |     }
295 | 
296 |     public Interpolator getInterpolator() {
297 |         return mInterpolator;
298 |     }
299 | 
300 |     public void setInterpolator(final Interpolator interpolator) {
301 |         mInterpolator = interpolator == null ? new SpringInterpolator() : interpolator;
302 |         resetScroller();
303 |     }
304 | 
305 |     public boolean isVertical() {
306 |         return mIsVertical;
307 |     }
308 | 
309 |     public int getState() {
310 |         return mState;
311 |     }
312 | 
313 |     public OnInfiniteCyclePageTransformListener getOnInfiniteCyclePageTransformListener() {
314 |         return mOnInfiniteCyclePageTransformListener;
315 |     }
316 | 
317 |     public void setOnInfiniteCyclePageTransformListener(
318 |             final OnInfiniteCyclePageTransformListener onInfiniteCyclePageTransformListener
319 |     ) {
320 |         mOnInfiniteCyclePageTransformListener = onInfiniteCyclePageTransformListener;
321 |     }
322 | 
323 |     public InfiniteCyclePageTransformer getInfinityCyclePageTransformer() {
324 |         return new InfiniteCyclePageTransformer();
325 |     }
326 | 
327 |     public InfiniteCyclePagerAdapter getInfiniteCyclePagerAdapter() {
328 |         return mInfiniteCyclePagerAdapter;
329 |     }
330 | 
331 |     public PagerAdapter setAdapter(final PagerAdapter adapter) {
332 |         // If adapter count bigger then 2 need to set InfiniteCyclePagerAdapter
333 |         if (adapter != null && adapter.getCount() >= MIN_CYCLE_COUNT) {
334 |             mItemCount = adapter.getCount();
335 |             mInfiniteCyclePagerAdapter = new InfiniteCyclePagerAdapter(adapter);
336 |             mInfiniteCyclePagerAdapter.setOnNotifyDataSetChangedListener(this);
337 |             return mInfiniteCyclePagerAdapter;
338 |         } else {
339 |             if (mInfiniteCyclePagerAdapter != null) {
340 |                 mInfiniteCyclePagerAdapter.setOnNotifyDataSetChangedListener(null);
341 |                 mInfiniteCyclePagerAdapter = null;
342 |             }
343 |             return adapter;
344 |         }
345 |     }
346 | 
347 |     // We are disable multitouch on ViewPager and settling scroll, also we disable outside drag
348 |     public boolean onTouchEvent(final MotionEvent event) {
349 |         if (mViewPageable.getAdapter() == null || mViewPageable.getAdapter().getCount() == 0)
350 |             return false;
351 |         if (mIsAutoScroll || mIsInitialItem || mViewPageable.isFakeDragging()) return false;
352 |         if (event.getPointerCount() > MIN_POINTER_COUNT || !mViewPageable.hasWindowFocus())
353 |             event.setAction(MotionEvent.ACTION_UP);
354 |         checkHitRect(event);
355 |         return true;
356 |     }
357 | 
358 |     public boolean onInterceptTouchEvent(MotionEvent event) {
359 |         return onTouchEvent(event);
360 |     }
361 | 
362 |     // When not has window focus clamp to nearest position
363 |     public void onWindowFocusChanged(final boolean hasWindowFocus) {
364 |         if (hasWindowFocus) invalidateTransformer();
365 |     }
366 | 
367 |     // Set current item where you put original adapter position and this method calculate nearest
368 |     // position to scroll from center if at first initial position or nearest position of old position
369 |     public int setCurrentItem(final int item) {
370 |         mIsInitialItem = true;
371 | 
372 |         if (mViewPageable.getAdapter() == null ||
373 |                 mViewPageable.getAdapter().getCount() < MIN_CYCLE_COUNT) return item;
374 | 
375 |         final int count = mViewPageable.getAdapter().getCount();
376 |         if (mIsAdapterInitialPosition) {
377 |             mIsAdapterInitialPosition = false;
378 |             return ((mInfiniteCyclePagerAdapter.getCount() / 2) / count) * count;
379 |         } else return mViewPageable.getCurrentItem() + Math.min(count, item) - getRealItem();
380 |     }
381 | 
382 |     // Need to get current position of original adapter. We cant override getCurrentItem() method,
383 |     // because ViewPager must have original item count relative to virtual adapter count
384 |     public int getRealItem() {
385 |         if (mViewPageable.getAdapter() == null ||
386 |                 mViewPageable.getAdapter().getCount() < MIN_CYCLE_COUNT)
387 |             return mViewPageable.getCurrentItem();
388 |         return mInfiniteCyclePagerAdapter.getVirtualPosition(mViewPageable.getCurrentItem());
389 |     }
390 | 
391 |     // Now you can call notify data on ViewPager nor adapter to invalidate all of positions
392 |     public void notifyDataSetChanged() {
393 |         if (mInfiniteCyclePagerAdapter == null) {
394 |             mViewPageable.getAdapter().notifyDataSetChanged();
395 |             mIsDataSetChanged = true;
396 |         } else mInfiniteCyclePagerAdapter.notifyDataSetChanged();
397 |         postInvalidateTransformer();
398 |     }
399 | 
400 |     // If you need to update transformer call this method, which is trigger fake scroll
401 |     public void invalidateTransformer() {
402 |         if (mViewPageable.getAdapter() == null || mViewPageable.getAdapter().getCount() == 0 ||
403 |                 mViewPageable.getChildCount() == 0) return;
404 |         if (mViewPageable.beginFakeDrag()) {
405 |             mViewPageable.fakeDragBy(0.0F);
406 |             mViewPageable.endFakeDrag();
407 |         }
408 |     }
409 | 
410 |     public void postInvalidateTransformer() {
411 |         mViewPageable.post(new Runnable() {
412 |             @Override
413 |             public void run() {
414 |                 invalidateTransformer();
415 |                 mIsDataSetChanged = false;
416 |             }
417 |         });
418 |     }
419 | 
420 |     // Enable hardware layer when transform pages
421 |     private void enableHardwareLayer(final View v) {
422 |         final int layerType = Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT ?
423 |                 View.LAYER_TYPE_NONE : View.LAYER_TYPE_HARDWARE;
424 |         if (v.getLayerType() != layerType) v.setLayerType(layerType, null);
425 |     }
426 | 
427 |     // Disable hardware layer when idle
428 |     private void disableHardwareLayers() {
429 |         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) return;
430 |         for (int i = 0; i < mViewPageable.getChildCount(); i++) {
431 |             final View child = mViewPageable.getChildAt(i);
432 |             if (child.getLayerType() != View.LAYER_TYPE_NONE)
433 |                 child.setLayerType(View.LAYER_TYPE_NONE, null);
434 |         }
435 |     }
436 | 
437 |     // Detect is we are idle in pageScrolled() callback, not in scrollStateChanged()
438 |     private boolean isSmallPositionOffset(float positionOffset) {
439 |         return Math.abs(positionOffset) < 0.0001F;
440 |     }
441 | 
442 |     // Check view bounds touch
443 |     private void checkHitRect(final MotionEvent event) {
444 |         if (event.getAction() == MotionEvent.ACTION_DOWN) {
445 |             mHitRect.set(
446 |                     mCastViewPageable.getLeft(), mCastViewPageable.getTop(),
447 |                     mCastViewPageable.getRight(), mCastViewPageable.getBottom()
448 |             );
449 |         } else if (event.getAction() == MotionEvent.ACTION_MOVE && !mHitRect.contains(
450 |                 mCastViewPageable.getLeft() + (int) event.getX(),
451 |                 mCastViewPageable.getTop() + (int) event.getY()
452 |         )) event.setAction(MotionEvent.ACTION_UP);
453 |     }
454 | 
455 |     // Reset scroller to own
456 |     private void resetScroller() {
457 |         if (mViewPageable == null) return;
458 |         try {
459 |             final Field scroller = mIsVertical ? VerticalViewPager.class.getDeclaredField("mScroller") :
460 |                     ViewPager.class.getDeclaredField("mScroller");
461 |             scroller.setAccessible(true);
462 |             final InfiniteCycleScroller infiniteCycleScroller =
463 |                     new InfiniteCycleScroller(mContext, mInterpolator);
464 |             infiniteCycleScroller.setDuration(mScrollDuration);
465 |             scroller.set(mViewPageable, infiniteCycleScroller);
466 |         } catch (Exception e) {
467 |             e.printStackTrace();
468 |         }
469 |     }
470 | 
471 |     // Reset pager when reset adapter
472 |     public void resetPager() {
473 |         mIsAdapterInitialPosition = true;
474 |         mViewPageable.setCurrentItem(0);
475 |         postInvalidateTransformer();
476 |     }
477 | 
478 |     // Recalculate scale by variable
479 |     private void resetScaleBy() {
480 |         mCenterScaleBy = (mMaxPageScale - mMinPageScale) * 0.5F;
481 |     }
482 | 
483 |     // Start auto scroll
484 |     public void startAutoScroll(final boolean isAutoScrollPositive) {
485 |         if (mIsAutoScroll && isAutoScrollPositive == mIsAutoScrollPositive) return;
486 |         mIsAutoScroll = true;
487 |         mIsAutoScrollPositive = isAutoScrollPositive;
488 | 
489 |         mAutoScrollHandler.removeCallbacks(mAutoScrollRunnable);
490 |         mAutoScrollHandler.post(mAutoScrollRunnable);
491 |     }
492 | 
493 |     // Stop auto scroll
494 |     public void stopAutoScroll() {
495 |         if (!mIsAutoScroll) return;
496 |         mIsAutoScroll = false;
497 |         mAutoScrollHandler.removeCallbacks(mAutoScrollRunnable);
498 |     }
499 | 
500 |     @Override
501 |     public void onChanged() {
502 |         mIsDataSetChanged = true;
503 |     }
504 | 
505 |     // The main presenter feature of this library is this InfiniteCyclePageTransformer.
506 |     // The logic is based to cycle items like carousel mode. There we don't have direct method
507 |     // to set z-index, so we need to handle only one method bringToFront().
508 |     protected class InfiniteCyclePageTransformer implements PageTransformer {
509 | 
510 |         @Override
511 |         public void transformPage(final View page, final float position) {
512 |             if (mOnInfiniteCyclePageTransformListener != null)
513 |                 mOnInfiniteCyclePageTransformListener.onPreTransform(page, position);
514 | 
515 |             // Handle page layer and bounds visibility
516 |             enableHardwareLayer(page);
517 |             if (mItemCount == MIN_CYCLE_COUNT) {
518 |                 if (position > 2.0F || position < -2.0F ||
519 |                         (mStackCount != 0 && position > 1.0F) ||
520 |                         (mStackCount != 0 && position < -1.0F)) {
521 |                     page.setVisibility(GONE);
522 |                     return;
523 |                 } else page.setVisibility(VISIBLE);
524 |             }
525 | 
526 |             final float pageSize = mIsVertical ? page.getMeasuredHeight() : page.getMeasuredWidth();
527 | 
528 |             // Page offsets relative to scale
529 |             final float pageMinScaleOffset = pageSize * mMinPageScale;
530 |             final float pageSubScaleByOffset = pageSize * mCenterScaleBy;
531 | 
532 |             // Page offsets from bounds
533 |             final float pageMinScaleEdgeOffset = (pageSize - pageMinScaleOffset) * 0.5F;
534 |             final float pageMaxScaleEdgeOffset = (pageSize - (pageSize * mMaxPageScale)) * 0.5F;
535 |             final float pageSubScaleEdgeOffset =
536 |                     (pageSize - (pageSize * (mMinPageScale + mCenterScaleBy))) * 0.5F;
537 | 
538 |             final float scale;
539 |             final float translation;
540 | 
541 |             // Detect when the count <= 3 and another page of side stack not placed
542 |             if (mItemCount < MIN_CYCLE_COUNT + 1 && mStackCount == 0 &&
543 |                     position > -2.0F && position < -1.0F) {
544 |                 final float fraction = -1.0F - position;
545 | 
546 |                 scale = mMinPageScale;
547 |                 translation = (pageSize - pageMinScaleEdgeOffset + mMinPageScaleOffset) +
548 |                         (pageSize * 2.0F - pageMinScaleOffset - mMinPageScaleOffset * 2.0F) * fraction;
549 | 
550 |                 mStackCount++;
551 |             }
552 |             // Detect when the count > 3 and pages at the center of bottom
553 |             else if (mItemCount > MIN_CYCLE_COUNT && position >= -2.0F && position < -1.0F) {
554 |                 final float fraction = 1.0F + (position + 1.0F);
555 | 
556 |                 scale = mMinPageScale;
557 |                 translation = (pageSize * 2.0F) - ((pageSize +
558 |                         pageMinScaleEdgeOffset - mMinPageScaleOffset) * fraction);
559 | 
560 |             }
561 |             // Transform from minimum scale to medium scale or max
562 |             else if (position >= -1.0F && position <= -0.5F) {
563 |                 final float positiveFraction = 1.0F + (position + 0.5F) * 2.0F;
564 |                 final float negativeFraction = 1.0F - positiveFraction;
565 | 
566 |                 if (mIsMediumScaled) {
567 |                     final float startOffset = pageSize - pageSubScaleByOffset -
568 |                             pageMaxScaleEdgeOffset + mMinPageScaleOffset;
569 | 
570 |                     scale = (mMinPageScale + mCenterScaleBy) - (mCenterScaleBy * negativeFraction);
571 |                     translation = startOffset - ((startOffset - pageSubScaleEdgeOffset +
572 |                             mCenterPageScaleOffset) * positiveFraction);
573 |                 } else {
574 |                     final float startOffset =
575 |                             pageSize - pageMinScaleEdgeOffset + mMinPageScaleOffset;
576 | 
577 |                     scale = (mMaxPageScale) - ((mMaxPageScale - mMinPageScale) * negativeFraction);
578 |                     translation = (startOffset) - ((startOffset - pageMaxScaleEdgeOffset +
579 |                             mCenterPageScaleOffset) * positiveFraction);
580 |                 }
581 |             }
582 |             // Transform from center or max to max
583 |             else if (position >= -0.5F && position <= 0.0F) {
584 |                 final float fraction = -position * 2.0F;
585 | 
586 |                 scale = mMaxPageScale - (mIsMediumScaled ? mCenterScaleBy * fraction : 0.0F);
587 |                 translation = ((mIsMediumScaled ? pageSubScaleEdgeOffset : pageMaxScaleEdgeOffset) -
588 |                         mCenterPageScaleOffset) * fraction;
589 |             }
590 |             // Transform from max to center or max
591 |             else if (position >= 0.0F && position <= 0.5F) {
592 |                 final float negativeFraction = position * 2.0F;
593 |                 final float positiveFraction = 1.0F - negativeFraction;
594 | 
595 |                 scale = !mIsMediumScaled ? mMaxPageScale :
596 |                         (mMinPageScale + mCenterScaleBy) + (mCenterScaleBy * positiveFraction);
597 |                 translation = (-(mIsMediumScaled ? pageSubScaleEdgeOffset : pageMaxScaleEdgeOffset) +
598 |                         mCenterPageScaleOffset) * negativeFraction;
599 |             }
600 |             // Transform from center or max to min
601 |             else if (position >= 0.5F && position <= 1.0F) {
602 |                 final float negativeFraction = (position - 0.5F) * 2.0F;
603 |                 final float positiveFraction = 1.0F - negativeFraction;
604 | 
605 |                 if (mIsMediumScaled) {
606 |                     scale = mMinPageScale + (mCenterScaleBy * positiveFraction);
607 |                     translation = (-pageSubScaleEdgeOffset + mCenterPageScaleOffset) + ((-pageSize +
608 |                             pageSubScaleByOffset + pageMaxScaleEdgeOffset + pageSubScaleEdgeOffset
609 |                             - mMinPageScaleOffset - mCenterPageScaleOffset) * negativeFraction);
610 |                 } else {
611 |                     scale = mMinPageScale + ((mMaxPageScale - mMinPageScale) * positiveFraction);
612 |                     translation = (-pageMaxScaleEdgeOffset + mCenterPageScaleOffset) +
613 |                             ((-pageSize + pageMaxScaleEdgeOffset + pageMinScaleEdgeOffset -
614 |                                     mMinPageScaleOffset - mCenterPageScaleOffset) * negativeFraction);
615 |                 }
616 |             }
617 |             // Detect when the count > 3 and pages at the center of bottom
618 |             else if (mItemCount > MIN_CYCLE_COUNT && position > 1.0F && position <= 2.0F) {
619 |                 final float negativeFraction = 1.0F + (position - 1.0F);
620 |                 final float positiveFraction = 1.0F - negativeFraction;
621 | 
622 |                 scale = mMinPageScale;
623 |                 translation = -(pageSize - pageMinScaleEdgeOffset + mMinPageScaleOffset) +
624 |                         ((pageSize + pageMinScaleEdgeOffset - mMinPageScaleOffset) * positiveFraction);
625 |             }
626 |             // Detect when the count <= 3 and another page of side stack not placed
627 |             else if (mItemCount < MIN_CYCLE_COUNT + 1 && mStackCount == 0 &&
628 |                     position > 1.0F && position < 2.0F) {
629 |                 final float fraction = 1.0F - position;
630 | 
631 |                 scale = mMinPageScale;
632 |                 translation = -(pageSize - pageMinScaleEdgeOffset + mMinPageScaleOffset) +
633 |                         ((pageSize * 2.0F - pageMinScaleOffset - mMinPageScaleOffset * 2.0F) * fraction);
634 | 
635 |                 mStackCount++;
636 |             } else {
637 |                 // Reset values
638 |                 scale = mMinPageScale;
639 |                 translation = 0.0F;
640 |             }
641 | 
642 |             // Scale page
643 |             ViewCompat.setScaleX(page, scale);
644 |             ViewCompat.setScaleY(page, scale);
645 | 
646 |             // Translate page
647 |             if (mIsVertical) ViewCompat.setTranslationY(page, translation);
648 |             else ViewCompat.setTranslationX(page, translation);
649 | 
650 |             boolean needBringToFront = false;
651 |             if (mItemCount == MIN_CYCLE_COUNT - 1) mIsLeftPageBringToFront = true;
652 | 
653 |             // Switch to handle what direction we move to know how need bring to front out pages
654 |             switch (mOuterPageScrolledState) {
655 |                 case GOING_LEFT:
656 |                     // Reset left page is bring
657 |                     mIsLeftPageBringToFront = false;
658 |                     // Now we handle where we scroll in outer and inner left direction
659 |                     if (mInnerPageScrolledState == PageScrolledState.GOING_LEFT) {
660 |                         // This is another flag which detect if right was not bring to front
661 |                         // and set positive flag
662 |                         if (position > -0.5F && position <= 0.0F) {
663 |                             if (!mIsRightPageBringToFront) {
664 |                                 mIsRightPageBringToFront = true;
665 |                                 needBringToFront = true;
666 |                             }
667 |                         }
668 |                         // Position of center page and we need bring to front immediately
669 |                         else if (position >= 0.0F && position < 0.5F) needBringToFront = true;
670 |                             // If right was not bring we need to set it up and detect if there no bounds
671 |                         else if (position > 0.5F && position < 1.0F && !mIsRightPageBringToFront &&
672 |                                 mViewPageable.getChildCount() > MIN_CYCLE_COUNT)
673 |                             needBringToFront = true;
674 |                     } else {
675 |                         // We move to the right and detect if position if under half of path
676 |                         if (mPageScrolledPositionOffset < 0.5F &&
677 |                                 position > -0.5F && position <= 0.0F) needBringToFront = true;
678 |                     }
679 |                     break;
680 |                 case GOING_RIGHT:
681 |                     // Reset right page is bring
682 |                     mIsRightPageBringToFront = false;
683 |                     // Now we handle where we scroll in outer and inner right direction
684 |                     if (mInnerPageScrolledState == PageScrolledState.GOING_RIGHT) {
685 |                         // This is another flag which detect if left was not bring to front
686 |                         // and set positive flag
687 |                         if (position >= 0.0F && position < 0.5F) {
688 |                             if (!mIsLeftPageBringToFront) {
689 |                                 mIsLeftPageBringToFront = true;
690 |                                 needBringToFront = true;
691 |                             }
692 |                         }
693 |                         // Position of center page and we need bring to front immediately
694 |                         else if (position > -0.5F && position <= 0.0F) needBringToFront = true;
695 |                             // If left was not bring we need to set it up and detect if there no bounds
696 |                         else if (position > -1.0F && position < -0.5F && !mIsLeftPageBringToFront &&
697 |                                 mViewPageable.getChildCount() > MIN_CYCLE_COUNT)
698 |                             needBringToFront = true;
699 |                     } else {
700 |                         // We move to the left and detect if position if over half of path
701 |                         if (mPageScrolledPositionOffset > 0.5F &&
702 |                                 position >= 0.0F && position < 0.5F) needBringToFront = true;
703 |                     }
704 |                     break;
705 |                 default:
706 |                     // If is data set changed we need to hard reset page bring flags
707 |                     if (mIsDataSetChanged) {
708 |                         mIsLeftPageBringToFront = false;
709 |                         mIsRightPageBringToFront = false;
710 |                     }
711 |                     // There is one of the general logic which is calculate
712 |                     // what page must be arrived first from idle state
713 |                     else {
714 |                         // Detect different situations of is there a page was bring or
715 |                         // we just need to bring it again to override drawing order
716 | 
717 |                         if (!mWasPlusOne && position == 1.0F) mWasPlusOne = true;
718 |                         else if (mWasPlusOne && position == -1.0F) mIsLeftPageBringToFront = true;
719 |                         else if ((!mWasPlusOne && position == -1.0F) ||
720 |                                 (mWasPlusOne && mIsLeftPageBringToFront && position == -2.0F))
721 |                             mIsLeftPageBringToFront = false;
722 | 
723 |                         if (!mWasMinusOne && position == -1.0F) mWasMinusOne = true;
724 |                         else if (mWasMinusOne && position == 1.0F) mIsRightPageBringToFront = true;
725 |                         else if ((!mWasMinusOne && position == 1.0F) ||
726 |                                 (mWasMinusOne && mIsRightPageBringToFront && position == 2.0F))
727 |                             mIsRightPageBringToFront = false;
728 |                     }
729 | 
730 |                     // Always bring to front is center position
731 |                     if (position == 0.0F) needBringToFront = true;
732 |                     break;
733 |             }
734 | 
735 |             // Bring to front if needed
736 |             if (needBringToFront) {
737 |                 page.bringToFront();
738 |                 mCastViewPageable.invalidate();
739 |             }
740 | 
741 |             if (mOnInfiniteCyclePageTransformListener != null)
742 |                 mOnInfiniteCyclePageTransformListener.onPostTransform(page, position);
743 |         }
744 |     }
745 | 
746 |     // OnPageChangeListener which is retrieve info about scroll direction and scroll state
747 |     protected final OnPageChangeListener mInfinityCyclePageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
748 |         @Override
749 |         public void onPageScrolled(
750 |                 final int position, final float positionOffset, final int positionOffsetPixels
751 |         ) {
752 |             // Reset stack count on each scroll offset
753 |             mStackCount = 0;
754 | 
755 |             // We need to rewrite states when is dragging and when setCurrentItem() from idle
756 |             if (mState != ViewPager.SCROLL_STATE_SETTLING || mIsInitialItem) {
757 |                 // Detect first state from idle
758 |                 if (mOuterPageScrolledState == PageScrolledState.IDLE && positionOffset > 0) {
759 |                     mPageScrolledPosition = mViewPageable.getCurrentItem();
760 |                     mOuterPageScrolledState = position == mPageScrolledPosition ?
761 |                             PageScrolledState.GOING_LEFT : PageScrolledState.GOING_RIGHT;
762 |                 }
763 | 
764 |                 // Rewrite scrolled state when switch to another edge
765 |                 final boolean goingRight = position == mPageScrolledPosition;
766 |                 if (mOuterPageScrolledState == PageScrolledState.GOING_LEFT && !goingRight)
767 |                     mOuterPageScrolledState = PageScrolledState.GOING_RIGHT;
768 |                 else if (mOuterPageScrolledState == PageScrolledState.GOING_RIGHT && goingRight)
769 |                     mOuterPageScrolledState = PageScrolledState.GOING_LEFT;
770 |             }
771 | 
772 |             // Rewrite inner dynamic scrolled state
773 |             if (mPageScrolledPositionOffset <= positionOffset)
774 |                 mInnerPageScrolledState = PageScrolledState.GOING_LEFT;
775 |             else mInnerPageScrolledState = PageScrolledState.GOING_RIGHT;
776 |             mPageScrolledPositionOffset = positionOffset;
777 | 
778 |             // Detect if is idle in pageScrolled() callback to transform pages last time
779 |             if ((isSmallPositionOffset(positionOffset) ? 0 : positionOffset) == 0) {
780 |                 // Reset states and flags on idle
781 |                 disableHardwareLayers();
782 | 
783 |                 mInnerPageScrolledState = PageScrolledState.IDLE;
784 |                 mOuterPageScrolledState = PageScrolledState.IDLE;
785 | 
786 |                 mWasMinusOne = false;
787 |                 mWasPlusOne = false;
788 |                 mIsLeftPageBringToFront = false;
789 |                 mIsRightPageBringToFront = false;
790 | 
791 |                 mIsInitialItem = false;
792 |             }
793 |         }
794 | 
795 |         @Override
796 |         public void onPageScrollStateChanged(final int state) {
797 |             mState = state;
798 |         }
799 |     };
800 | 
801 |     // Page scrolled state
802 |     private enum PageScrolledState {
803 |         IDLE, GOING_LEFT, GOING_RIGHT
804 |     }
805 | 
806 |     // Default spring interpolator
807 |     private final class SpringInterpolator implements Interpolator {
808 | 
809 |         private final static float FACTOR = 0.5F;
810 | 
811 |         @Override
812 |         public float getInterpolation(final float input) {
813 |             return (float) (Math.pow(2.0F, -10.0F * input) *
814 |                     Math.sin((input - FACTOR / 4.0F) * (2.0F * Math.PI) / FACTOR) + 1.0F);
815 |         }
816 |     }
817 | }
818 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/InfiniteCyclePagerAdapter.java:
--------------------------------------------------------------------------------
  1 | package com.gigamole.infinitecycleviewpager;
  2 | 
  3 | import android.database.DataSetObserver;
  4 | import android.os.Parcelable;
  5 | import android.support.v4.view.PagerAdapter;
  6 | import android.view.View;
  7 | import android.view.ViewGroup;
  8 | 
  9 | /**
 10 |  * Created by GIGAMOLE on 7/27/16.
 11 |  */
 12 | 
 13 | // PagerAdapter that wrap original ViewPager adapter with infinite scroll feature.
 14 | // There is VIRTUAL_ITEM_COUNT which equals to 10_000_000.
 15 | // At start, ViewPager set position to half of virtual and find nearest zero position.
 16 | class InfiniteCyclePagerAdapter extends PagerAdapter {
 17 | 
 18 |     private final static int VIRTUAL_ITEM_COUNT = 10_000_000;
 19 | 
 20 |     private final PagerAdapter mPagerAdapter;
 21 |     private OnNotifyDataSetChangedListener mOnNotifyDataSetChangedListener;
 22 | 
 23 |     public InfiniteCyclePagerAdapter(final PagerAdapter pagerAdapter) {
 24 |         mPagerAdapter = pagerAdapter;
 25 |     }
 26 | 
 27 |     public PagerAdapter getPagerAdapter() {
 28 |         return mPagerAdapter;
 29 |     }
 30 | 
 31 |     public void setOnNotifyDataSetChangedListener(final OnNotifyDataSetChangedListener onNotifyDataSetChangedListener) {
 32 |         mOnNotifyDataSetChangedListener = onNotifyDataSetChangedListener;
 33 |     }
 34 | 
 35 |     @Override
 36 |     public void destroyItem(ViewGroup container, int position, Object object) {
 37 |         mPagerAdapter.destroyItem(container, getVirtualPosition(position), object);
 38 |     }
 39 | 
 40 |     @Override
 41 |     public void finishUpdate(ViewGroup container) {
 42 |         mPagerAdapter.finishUpdate(container);
 43 |     }
 44 | 
 45 |     @Override
 46 |     public int getCount() {
 47 |         if (mPagerAdapter.getCount() == 0) return 0;
 48 |         return VIRTUAL_ITEM_COUNT;
 49 |     }
 50 | 
 51 |     @Override
 52 |     public CharSequence getPageTitle(int position) {
 53 |         return mPagerAdapter.getPageTitle(getVirtualPosition(position));
 54 |     }
 55 | 
 56 |     @Override
 57 |     public float getPageWidth(int position) {
 58 |         return mPagerAdapter.getPageWidth(getVirtualPosition(position));
 59 |     }
 60 | 
 61 |     @Override
 62 |     public boolean isViewFromObject(View view, Object o) {
 63 |         return mPagerAdapter.isViewFromObject(view, o);
 64 |     }
 65 | 
 66 |     @Override
 67 |     public Object instantiateItem(ViewGroup container, int position) {
 68 |         return mPagerAdapter.instantiateItem(container, getVirtualPosition(position));
 69 |     }
 70 | 
 71 |     @Override
 72 |     public Parcelable saveState() {
 73 |         return mPagerAdapter.saveState();
 74 |     }
 75 | 
 76 |     @Override
 77 |     public void restoreState(Parcelable state, ClassLoader loader) {
 78 |         mPagerAdapter.restoreState(state, loader);
 79 |     }
 80 | 
 81 |     @Override
 82 |     public void startUpdate(ViewGroup container) {
 83 |         mPagerAdapter.startUpdate(container);
 84 |     }
 85 | 
 86 |     @Override
 87 |     public void unregisterDataSetObserver(DataSetObserver observer) {
 88 |         mPagerAdapter.unregisterDataSetObserver(observer);
 89 |     }
 90 | 
 91 |     @Override
 92 |     public void registerDataSetObserver(DataSetObserver observer) {
 93 |         mPagerAdapter.registerDataSetObserver(observer);
 94 |     }
 95 | 
 96 |     @Override
 97 |     public void notifyDataSetChanged() {
 98 |         mPagerAdapter.notifyDataSetChanged();
 99 |         // Callback for invalidating transformer position
100 |         if (mOnNotifyDataSetChangedListener != null) mOnNotifyDataSetChangedListener.onChanged();
101 |     }
102 | 
103 |     @Override
104 |     public void setPrimaryItem(ViewGroup container, int position, Object object) {
105 |         mPagerAdapter.setPrimaryItem(container, position, object);
106 |     }
107 | 
108 |     @Override
109 |     public int getItemPosition(Object object) {
110 |         return mPagerAdapter.getItemPosition(object);
111 |     }
112 | 
113 |     // Main feature of this adapter which return virtual position
114 |     // relative to virtual count and original count
115 |     protected int getVirtualPosition(final int realPosition) {
116 |         return realPosition % mPagerAdapter.getCount();
117 |     }
118 | 
119 |     protected interface OnNotifyDataSetChangedListener {
120 |         void onChanged();
121 |     }
122 | }


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/InfiniteCycleScroller.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.infinitecycleviewpager;
 2 | 
 3 | import android.content.Context;
 4 | import android.view.animation.Interpolator;
 5 | import android.widget.Scroller;
 6 | 
 7 | /**
 8 |  * Created by GIGAMOLE on 8/4/16.
 9 |  */
10 | 
11 | // Custom scroller for setting own snap duration and interpolator
12 | class InfiniteCycleScroller extends Scroller {
13 | 
14 |     private int mDuration;
15 | 
16 |     public InfiniteCycleScroller(final Context context) {
17 |         super(context);
18 |     }
19 | 
20 |     public InfiniteCycleScroller(final Context context, final Interpolator interpolator) {
21 |         super(context, interpolator);
22 |     }
23 | 
24 |     public InfiniteCycleScroller(final Context context, final Interpolator interpolator, final boolean flywheel) {
25 |         super(context, interpolator, flywheel);
26 |     }
27 | 
28 |     public void setDuration(final int duration) {
29 |         mDuration = duration;
30 |     }
31 | 
32 |     @Override
33 |     public void startScroll(int startX, int startY, int dx, int dy, int duration) {
34 |         super.startScroll(startX, startY, dx, dy, mDuration);
35 |     }
36 | 
37 |     @Override
38 |     public void startScroll(int startX, int startY, int dx, int dy) {
39 |         super.startScroll(startX, startY, dx, dy, mDuration);
40 |     }
41 | }
42 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/OnInfiniteCyclePageTransformListener.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.infinitecycleviewpager;
 2 | 
 3 | import android.view.View;
 4 | 
 5 | /**
 6 |  * Created by GIGAMOLE on 7/27/16.
 7 |  */
 8 | public interface OnInfiniteCyclePageTransformListener {
 9 |     void onPreTransform(final View page, final float position);
10 | 
11 |     void onPostTransform(final View page, final float position);
12 | }


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/VerticalInfiniteCycleViewPager.java:
--------------------------------------------------------------------------------
  1 | package com.gigamole.infinitecycleviewpager;
  2 | 
  3 | import android.content.Context;
  4 | import android.support.v4.view.PagerAdapter;
  5 | import android.support.v4.view.ViewPager;
  6 | import android.util.AttributeSet;
  7 | import android.view.MotionEvent;
  8 | import android.view.View;
  9 | import android.view.ViewGroup;
 10 | import android.view.animation.Interpolator;
 11 | 
 12 | /**
 13 |  * Created by GIGAMOLE on 7/27/16.
 14 |  */
 15 | public class VerticalInfiniteCycleViewPager extends VerticalViewPager implements ViewPageable {
 16 | 
 17 |     private InfiniteCycleManager mInfiniteCycleManager;
 18 | 
 19 |     public VerticalInfiniteCycleViewPager(final Context context) {
 20 |         super(context);
 21 |         init(context, null);
 22 |     }
 23 | 
 24 |     public VerticalInfiniteCycleViewPager(final Context context, final AttributeSet attrs) {
 25 |         super(context, attrs);
 26 |         init(context, attrs);
 27 |     }
 28 | 
 29 |     private void init(final Context context, final AttributeSet attributeSet) {
 30 |         mInfiniteCycleManager = new InfiniteCycleManager(context, this, attributeSet);
 31 |     }
 32 | 
 33 |     public float getMinPageScaleOffset() {
 34 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getMinPageScaleOffset();
 35 |     }
 36 | 
 37 |     public void setMinPageScaleOffset(final float minPageScaleOffset) {
 38 |         if (mInfiniteCycleManager != null)
 39 |             mInfiniteCycleManager.setMinPageScaleOffset(minPageScaleOffset);
 40 |     }
 41 | 
 42 |     public float getCenterPageScaleOffset() {
 43 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getCenterPageScaleOffset();
 44 |     }
 45 | 
 46 |     public void setCenterPageScaleOffset(final float centerPageScaleOffset) {
 47 |         if (mInfiniteCycleManager != null)
 48 |             mInfiniteCycleManager.setCenterPageScaleOffset(centerPageScaleOffset);
 49 |     }
 50 | 
 51 |     public float getMinPageScale() {
 52 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getMinPageScale();
 53 |     }
 54 | 
 55 |     public void setMinPageScale(final float minPageScale) {
 56 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setMinPageScale(minPageScale);
 57 |     }
 58 | 
 59 |     public float getMaxPageScale() {
 60 |         return mInfiniteCycleManager == null ? 0.0F : mInfiniteCycleManager.getMaxPageScale();
 61 |     }
 62 | 
 63 |     public void setMaxPageScale(final float maxPageScale) {
 64 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setMaxPageScale(maxPageScale);
 65 |     }
 66 | 
 67 |     public boolean isMediumScaled() {
 68 |         return mInfiniteCycleManager != null && mInfiniteCycleManager.isMediumScaled();
 69 |     }
 70 | 
 71 |     public void setMediumScaled(final boolean mediumScaled) {
 72 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setMediumScaled(mediumScaled);
 73 |     }
 74 | 
 75 |     public int getScrollDuration() {
 76 |         return mInfiniteCycleManager == null ? 0 : mInfiniteCycleManager.getScrollDuration();
 77 |     }
 78 | 
 79 |     public void setScrollDuration(final int scrollDuration) {
 80 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setScrollDuration(scrollDuration);
 81 |     }
 82 | 
 83 |     public int getPageDuration() {
 84 |         return mInfiniteCycleManager == null ? 0 : mInfiniteCycleManager.getPageDuration();
 85 |     }
 86 | 
 87 |     public void setPageDuration(final int pageDuration) {
 88 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setPageDuration(pageDuration);
 89 |     }
 90 | 
 91 |     public Interpolator getInterpolator() {
 92 |         return mInfiniteCycleManager == null ? null : mInfiniteCycleManager.getInterpolator();
 93 |     }
 94 | 
 95 |     public void setInterpolator(final Interpolator interpolator) {
 96 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.setInterpolator(interpolator);
 97 |     }
 98 | 
 99 |     public boolean isVertical() {
100 |         return mInfiniteCycleManager != null && mInfiniteCycleManager.isVertical();
101 |     }
102 | 
103 |     public OnInfiniteCyclePageTransformListener getOnInfiniteCyclePageTransformListener() {
104 |         return mInfiniteCycleManager == null ?
105 |                 null : mInfiniteCycleManager.getOnInfiniteCyclePageTransformListener();
106 |     }
107 | 
108 |     public void setOnInfiniteCyclePageTransformListener(
109 |             final OnInfiniteCyclePageTransformListener onInfiniteCyclePageTransformListener
110 |     ) {
111 |         if (mInfiniteCycleManager != null)
112 |             mInfiniteCycleManager.setOnInfiniteCyclePageTransformListener(onInfiniteCyclePageTransformListener);
113 |     }
114 | 
115 |     @Override
116 |     public void setPageTransformer(final boolean reverseDrawingOrder, final ViewPager.PageTransformer transformer) {
117 |         super.setPageTransformer(
118 |                 false, mInfiniteCycleManager == null ?
119 |                         transformer : mInfiniteCycleManager.getInfinityCyclePageTransformer()
120 |         );
121 |     }
122 | 
123 |     @Override
124 |     protected void setChildrenDrawingOrderEnabled(final boolean enabled) {
125 |         super.setChildrenDrawingOrderEnabled(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
126 |     }
127 | 
128 |     @Override
129 |     public void setClipChildren(final boolean clipChildren) {
130 |         super.setClipChildren(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
131 |     }
132 | 
133 |     @Override
134 |     public void setDrawingCacheEnabled(final boolean enabled) {
135 |         super.setDrawingCacheEnabled(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
136 |     }
137 | 
138 |     @Override
139 |     protected void setChildrenDrawingCacheEnabled(final boolean enabled) {
140 |         super.setChildrenDrawingCacheEnabled(InfiniteCycleManager.DEFAULT_DISABLE_FLAG);
141 |     }
142 | 
143 |     @Override
144 |     public void setWillNotCacheDrawing(final boolean willNotCacheDrawing) {
145 |         super.setWillNotCacheDrawing(InfiniteCycleManager.DEFAULT_ENABLE_FLAG);
146 |     }
147 | 
148 |     @Override
149 |     public void setPageMargin(final int marginPixels) {
150 |         super.setPageMargin(InfiniteCycleManager.DEFAULT_PAGE_MARGIN);
151 |     }
152 | 
153 |     @Override
154 |     public void setOffscreenPageLimit(final int limit) {
155 |         super.setOffscreenPageLimit(InfiniteCycleManager.DEFAULT_OFFSCREEN_PAGE_LIMIT);
156 |     }
157 | 
158 |     @Override
159 |     public void setOverScrollMode(final int overScrollMode) {
160 |         super.setOverScrollMode(OVER_SCROLL_NEVER);
161 |     }
162 | 
163 |     @Override
164 |     protected boolean addViewInLayout(final View child, final int index, final ViewGroup.LayoutParams params) {
165 |         return super.addViewInLayout(child, 0, params);
166 |     }
167 | 
168 |     @Override
169 |     public void addView(final View child, final int index, final ViewGroup.LayoutParams params) {
170 |         super.addView(child, 0, params);
171 |     }
172 | 
173 |     @Override
174 |     public void setAdapter(final PagerAdapter adapter) {
175 |         if (mInfiniteCycleManager == null) super.setAdapter(adapter);
176 |         else {
177 |             super.setAdapter(mInfiniteCycleManager.setAdapter(adapter));
178 |             mInfiniteCycleManager.resetPager();
179 |         }
180 |     }
181 | 
182 |     @Override
183 |     public PagerAdapter getAdapter() {
184 |         if (mInfiniteCycleManager == null) return super.getAdapter();
185 |         return mInfiniteCycleManager.getInfiniteCyclePagerAdapter() == null ? super.getAdapter() :
186 |                 mInfiniteCycleManager.getInfiniteCyclePagerAdapter().getPagerAdapter();
187 |     }
188 | 
189 |     @Override
190 |     public boolean onTouchEvent(final MotionEvent ev) {
191 |         try {
192 |             return mInfiniteCycleManager == null ? super.onTouchEvent(ev) :
193 |                     mInfiniteCycleManager.onTouchEvent(ev) && super.onTouchEvent(ev);
194 |         } catch (IllegalArgumentException e) {
195 |             return true;
196 |         }
197 |     }
198 | 
199 |     @Override
200 |     public boolean onInterceptTouchEvent(final MotionEvent ev) {
201 |         try {
202 |             return mInfiniteCycleManager == null ? super.onInterceptTouchEvent(ev) :
203 |                     mInfiniteCycleManager.onInterceptTouchEvent(ev) && super.onInterceptTouchEvent(ev);
204 |         } catch (IllegalArgumentException e) {
205 |             return true;
206 |         }
207 |     }
208 | 
209 |     @Override
210 |     public void onWindowFocusChanged(final boolean hasWindowFocus) {
211 |         if (mInfiniteCycleManager != null)
212 |             mInfiniteCycleManager.onWindowFocusChanged(hasWindowFocus);
213 |         super.onWindowFocusChanged(hasWindowFocus);
214 |     }
215 | 
216 |     @Override
217 |     protected void onDetachedFromWindow() {
218 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.stopAutoScroll();
219 |         super.onDetachedFromWindow();
220 |     }
221 | 
222 |     @Override
223 |     public void setCurrentItem(final int item) {
224 |         setCurrentItem(item, true);
225 |     }
226 | 
227 |     @Override
228 |     public void setCurrentItem(final int item, final boolean smoothScroll) {
229 |         if (mInfiniteCycleManager != null)
230 |             super.setCurrentItem(mInfiniteCycleManager.setCurrentItem(item), true);
231 |     }
232 | 
233 |     public int getRealItem() {
234 |         return mInfiniteCycleManager == null ?
235 |                 getCurrentItem() : mInfiniteCycleManager.getRealItem();
236 |     }
237 | 
238 |     public int getState() {
239 |         return mInfiniteCycleManager == null ?
240 |                 ViewPager.SCROLL_STATE_IDLE : mInfiniteCycleManager.getState();
241 |     }
242 | 
243 |     public void notifyDataSetChanged() {
244 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.notifyDataSetChanged();
245 |     }
246 | 
247 |     public void invalidateTransformer() {
248 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.invalidateTransformer();
249 |     }
250 | 
251 |     public void postInvalidateTransformer() {
252 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.postInvalidateTransformer();
253 |     }
254 | 
255 |     public void startAutoScroll(final boolean isAutoScrollPositive) {
256 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.startAutoScroll(isAutoScrollPositive);
257 |     }
258 | 
259 |     public void stopAutoScroll() {
260 |         if (mInfiniteCycleManager != null) mInfiniteCycleManager.stopAutoScroll();
261 |     }
262 | }
263 | 


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/java/com/gigamole/infinitecycleviewpager/ViewPageable.java:
--------------------------------------------------------------------------------
 1 | package com.gigamole.infinitecycleviewpager;
 2 | 
 3 | import android.support.v4.view.PagerAdapter;
 4 | import android.view.View;
 5 | 
 6 | import static android.support.v4.view.ViewPager.OnPageChangeListener;
 7 | import static android.support.v4.view.ViewPager.PageTransformer;
 8 | 
 9 | /**
10 |  * Created by GIGAMOLE on 7/27/16.
11 |  */
12 | 
13 | // Interface that duplicate methods of ViewPager for implements it in Horizontal and Vertical
14 | // InfiniteCycleViewPager for casting them to ViewPageable in InfiniteCycleManager
15 | interface ViewPageable {
16 | 
17 |     boolean hasWindowFocus();
18 |     int getCurrentItem();
19 |     int getChildCount();
20 |     View getChildAt(final int index);
21 |     PagerAdapter getAdapter();
22 | 
23 |     boolean post(final Runnable runnable);
24 | 
25 |     void addOnPageChangeListener(final OnPageChangeListener onPageChangeListener);
26 |     void setClipChildren(final boolean clipChildren);
27 |     void setDrawingCacheEnabled(final boolean drawingCacheEnabled);
28 |     void setWillNotCacheDrawing(final boolean willNotCacheDrawing);
29 |     void setOverScrollMode(final int overScrollMode);
30 |     void setCurrentItem(final int item);
31 |     void setPageTransformer(final boolean reverseDrawingOrder, final PageTransformer transformer);
32 |     void setPageMargin(final int pageMargin);
33 |     void setOffscreenPageLimit(final int offscreenPageLimit);
34 | 
35 |     boolean isFakeDragging();
36 |     boolean beginFakeDrag();
37 |     void fakeDragBy(final float dragBy);
38 |     void endFakeDrag();
39 | 
40 | }


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <resources>
 3 | 
 4 |     <attr name="icvp_min_page_scale_offset" format="dimension"/>
 5 |     <attr name="icvp_center_page_scale_offset" format="dimension"/>
 6 |     <attr name="icvp_min_page_scale" format="float"/>
 7 |     <attr name="icvp_max_page_scale" format="float"/>
 8 |     <attr name="icvp_medium_scaled" format="boolean"/>
 9 |     <attr name="icvp_scroll_duration" format="integer"/>
10 |     <attr name="icvp_page_duration" format="integer"/>
11 |     <attr name="icvp_interpolator" format="reference"/>
12 | 
13 |     <declare-styleable name="HorizontalInfiniteCycleViewPager">
14 |         <attr name="icvp_min_page_scale_offset"/>
15 |         <attr name="icvp_center_page_scale_offset"/>
16 |         <attr name="icvp_min_page_scale"/>
17 |         <attr name="icvp_max_page_scale"/>
18 |         <attr name="icvp_medium_scaled"/>
19 |         <attr name="icvp_scroll_duration"/>
20 |         <attr name="icvp_page_duration"/>
21 |         <attr name="icvp_interpolator"/>
22 |     </declare-styleable>
23 | 
24 |     <declare-styleable name="VerticalInfiniteCycleViewPager">
25 |         <attr name="icvp_min_page_scale_offset"/>
26 |         <attr name="icvp_center_page_scale_offset"/>
27 |         <attr name="icvp_min_page_scale"/>
28 |         <attr name="icvp_max_page_scale"/>
29 |         <attr name="icvp_medium_scaled"/>
30 |         <attr name="icvp_scroll_duration"/>
31 |         <attr name="icvp_page_duration"/>
32 |         <attr name="icvp_interpolator"/>
33 |     </declare-styleable>
34 | 
35 | </resources>


--------------------------------------------------------------------------------
/infinitecycleviewpager/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | <resources>
2 |     <string name="app_name">InfinityCycleViewPager</string>
3 | </resources>
4 | 


--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':infinitecycleviewpager'
2 | 


--------------------------------------------------------------------------------