├── app ├── .gitignore ├── apk │ └── sample-app-v1.0.0.apk ├── src │ ├── main │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── styles.xml │ │ │ │ └── colors.xml │ │ │ ├── layout │ │ │ │ ├── item_page.xml │ │ │ │ ├── fragment_page.xml │ │ │ │ ├── activity_show_hide_fragment.xml │ │ │ │ ├── activity_indicator_example.xml │ │ │ │ ├── activity_simple_example.xml │ │ │ │ ├── activity_fragment_pager_example.xml │ │ │ │ └── activity_fragment_state_pager_example.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── kenilt │ │ │ │ └── loopingviewpager │ │ │ │ └── example │ │ │ │ ├── model │ │ │ │ ├── PageModel.kt │ │ │ │ └── DataGenerator.kt │ │ │ │ ├── fragmentPager │ │ │ │ ├── ExampleFragmentPagerAdapter.kt │ │ │ │ ├── PageFragment.kt │ │ │ │ └── FragmentPagerExampleActivity.kt │ │ │ │ ├── BaseExampleActivity.kt │ │ │ │ ├── fragmentStatePager │ │ │ │ ├── ExampleFragmentStatePagerAdapter.kt │ │ │ │ └── FragmentStatePagerExampleActivity.kt │ │ │ │ ├── showHideFragmentExample │ │ │ │ ├── ShowHideFragmentActivity.kt │ │ │ │ └── SimpleExampleFragment.kt │ │ │ │ ├── simpleExample │ │ │ │ ├── ExamplePagerAdapter.kt │ │ │ │ └── SimpleExampleActivity.kt │ │ │ │ ├── indicatorExample │ │ │ │ └── IndicatorExampleActivity.kt │ │ │ │ └── MainActivity.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── kenilt │ │ │ └── loopingviewpager │ │ │ └── example │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── kenilt │ │ └── loopingviewpager │ │ └── example │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── loopingviewpager ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── kenilt │ │ │ └── loopingviewpager │ │ │ ├── scroller │ │ │ ├── ScrollerObserver.kt │ │ │ ├── ScrollerCycle.kt │ │ │ └── AutoScroller.kt │ │ │ ├── util │ │ │ └── LoopingUtil.kt │ │ │ └── widget │ │ │ ├── InternalFragmentStatePagerAdapter.kt │ │ │ ├── InternalFragmentPagerAdapter.kt │ │ │ ├── InternalLoopingAdapter.kt │ │ │ ├── InternalOnPageChangeListener.kt │ │ │ └── LoopingViewPager.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── kenilt │ │ │ └── loopingviewpager │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── kenilt │ │ └── loopingviewpager │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── screenshot ├── simple-screenshot.gif └── indicators-screenshot.gif ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── LICENSE ├── .gitignore ├── gradle.properties ├── tools └── script-git-version.gradle ├── gradlew.bat ├── gradlew └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /loopingviewpager/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /loopingviewpager/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='LoopingViewPager' 2 | include ':app' 3 | include ':loopingviewpager' 4 | -------------------------------------------------------------------------------- /app/apk/sample-app-v1.0.0.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/apk/sample-app-v1.0.0.apk -------------------------------------------------------------------------------- /loopingviewpager/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /screenshot/simple-screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/screenshot/simple-screenshot.gif -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /screenshot/indicators-screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/screenshot/indicators-screenshot.gif -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenilt/LoopingViewPager/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /loopingviewpager/src/main/java/com/kenilt/loopingviewpager/scroller/ScrollerObserver.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.scroller 2 | 3 | /** 4 | * Created by thangnguyen on 4/17/20. 5 | */ 6 | interface ScrollerObserver { 7 | fun changeAutoScroll(isAutoScroll: Boolean) 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/kenilt/loopingviewpager/example/model/PageModel.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example.model 2 | 3 | import java.io.Serializable 4 | 5 | /** 6 | * Created by thangnguyen on 3/11/20. 7 | */ 8 | data class PageModel(var text: String, var color: Int) : Serializable 9 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/test/java/com/kenilt/loopingviewpager/example/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /loopingviewpager/src/test/java/com/kenilt/loopingviewpager/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | LoopingViewPager 3 | Simple example 4 | Fragment pager example 5 | Fragment state pager example 6 | Show hide fragment example 7 | Tab layout + Some indicators 8 | 9 | 10 | Hello blank fragment 11 | 12 | -------------------------------------------------------------------------------- /loopingviewpager/src/main/java/com/kenilt/loopingviewpager/scroller/ScrollerCycle.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.scroller 2 | 3 | /** 4 | * Created by thangnguyen on 4/17/20. 5 | */ 6 | class ScrollerCycle { 7 | 8 | private val observers: MutableList = ArrayList() 9 | 10 | fun addObserver(observer: ScrollerObserver) { 11 | observers.add(observer) 12 | } 13 | 14 | fun removeObserver(observer: ScrollerObserver) { 15 | observers.remove(observer) 16 | } 17 | 18 | fun onChangeAutoScroll(isAutoScroll: Boolean) { 19 | observers.forEach { it.changeAutoScroll(isAutoScroll) } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/kenilt/loopingviewpager/example/fragmentPager/ExampleFragmentPagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example.fragmentPager 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.fragment.app.FragmentPagerAdapter 6 | import com.kenilt.loopingviewpager.example.model.PageModel 7 | 8 | /** 9 | * Created by thangnguyen on 3/13/20. 10 | */ 11 | class ExampleFragmentPagerAdapter(fragmentManager: FragmentManager, private var dataList: List) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { 12 | 13 | override fun getItem(position: Int): Fragment { 14 | return PageFragment.newInstance(dataList[position]) 15 | } 16 | 17 | override fun getCount(): Int { 18 | return dataList.size 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /loopingviewpager/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /loopingviewpager/src/androidTest/java/com/kenilt/loopingviewpager/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.kenilt.loopingviewpager.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/kenilt/loopingviewpager/example/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.kenilt.loopingviewpager.example", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/kenilt/loopingviewpager/example/BaseExampleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import androidx.appcompat.app.AppCompatActivity 6 | 7 | /** 8 | * Created by thangnguyen on 3/13/20. 9 | */ 10 | abstract class BaseExampleActivity : AppCompatActivity() { 11 | 12 | override fun onCreate(savedInstanceState: Bundle?) { 13 | super.onCreate(savedInstanceState) 14 | setTitle(getTitleId()) 15 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 16 | } 17 | 18 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 19 | return when (item.itemId) { 20 | android.R.id.home -> { 21 | finish() 22 | true 23 | } 24 | else -> super.onOptionsItemSelected(item) 25 | } 26 | } 27 | 28 | abstract fun getTitleId(): Int 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/kenilt/loopingviewpager/example/fragmentStatePager/ExampleFragmentStatePagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example.fragmentStatePager 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.fragment.app.FragmentStatePagerAdapter 6 | import com.kenilt.loopingviewpager.example.fragmentPager.PageFragment 7 | import com.kenilt.loopingviewpager.example.model.PageModel 8 | 9 | /** 10 | * Created by thangnguyen on 3/13/20. 11 | */ 12 | class ExampleFragmentStatePagerAdapter(fragmentManager: FragmentManager, private var dataList: List): FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { 13 | 14 | override fun getItem(position: Int): Fragment { 15 | return PageFragment.newInstance(dataList[position]) 16 | } 17 | 18 | override fun getCount(): Int { 19 | return dataList.size 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/kenilt/loopingviewpager/example/model/DataGenerator.kt: -------------------------------------------------------------------------------- 1 | package com.kenilt.loopingviewpager.example.model 2 | 3 | import com.kenilt.loopingviewpager.example.R 4 | 5 | /** 6 | * Created by thangnguyen on 3/11/20. 7 | */ 8 | object DataGenerator { 9 | private val colors = listOf( 10 | R.color.light_slate_gray, 11 | R.color.pink, 12 | R.color.silver, 13 | R.color.thistle, 14 | R.color.medium_aquamarine, 15 | R.color.azure, 16 | R.color.moccasin, 17 | R.color.snow 18 | ) 19 | 20 | fun generateList(length: Int = 4, prefix: String = "Page"): List { 21 | val dataList = ArrayList() 22 | repeat(length) { 23 | dataList.add( 24 | PageModel( 25 | "$prefix ${it + 1}", 26 | colors[it % colors.size] 27 | ) 28 | ) 29 | } 30 | return dataList 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Thang Nguyen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_show_hide_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 |