diff --git a/build.gradle b/build.gradle index afc9df5..c624b32 100755 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,11 @@ buildscript { + ext.kotlin_version = '1.2.21' repositories { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:0.7.+' + classpath 'com.android.tools.build:gradle:2.3.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/gradle.properties b/gradle.properties index 73e0cd0..d2794c0 100755 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,10 @@ VERSION_NAME=19.0.1 VERSION_CODE=2 GROUP=com.github.castorflex.verticalviewpager +androidMinSdkVersion=14 +androidTargetSdkVersion=27 +androidCompileSdkVersion=27 +androidBuildToolsVersion=25.0.3 #storeFile=nice try #keyAlias=nice try diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9b8ffdd..eaba301 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/library/build.gradle b/library/build.gradle index 643308e..fc24908 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'android-library' +apply plugin: 'kotlin-android' repositories { mavenCentral() @@ -6,15 +7,21 @@ repositories { dependencies { compile 'com.android.support:support-v4:19.0.0' + compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" } android { - compileSdkVersion 19 - buildToolsVersion "19.0.0" + def androidCompileSdkVersion = project.androidCompileSdkVersion.toInteger() + def androidTargetSdkVersion = project.androidTargetSdkVersion.toInteger() + def androidMinSdkVersion = project.androidMinSdkVersion.toInteger() + def androidBuildToolsVersion = project.androidBuildToolsVersion.toString() + + compileSdkVersion androidCompileSdkVersion + buildToolsVersion androidBuildToolsVersion defaultConfig { - minSdkVersion 4 - targetSdkVersion 19 + minSdkVersion androidMinSdkVersion + targetSdkVersion androidTargetSdkVersion versionName project.VERSION_NAME versionCode Integer.parseInt(project.VERSION_CODE) } diff --git a/library/src/main/java/fr/castorflex/android/verticalviewpager/VerticalViewPager.java b/library/src/main/java/fr/castorflex/android/verticalviewpager/VerticalViewPager.java index 8fbc9c3..97e2861 100644 --- a/library/src/main/java/fr/castorflex/android/verticalviewpager/VerticalViewPager.java +++ b/library/src/main/java/fr/castorflex/android/verticalviewpager/VerticalViewPager.java @@ -398,15 +398,27 @@ public void setCurrentItem(int item, boolean smoothScroll) { setCurrentItemInternal(item, smoothScroll, false); } + /** + * Set the currently selected page with duration. + * + * @param item Item index to select + * @param duration Scroll duration to reach item index + */ + public void setCurrentItem(int item, int duration) { + mPopulatePending = false; + setCurrentItemInternal(item, true, false, 0, duration); + } + + public int getCurrentItem() { return mCurItem; } void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) { - setCurrentItemInternal(item, smoothScroll, always, 0); + setCurrentItemInternal(item, smoothScroll, always, 0, 0); } - void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) { + void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity, int duration) { if (mAdapter == null || mAdapter.getCount() <= 0) { setScrollingCacheEnabled(false); return; @@ -445,12 +457,12 @@ void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int requestLayout(); } else { populate(item); - scrollToItem(item, smoothScroll, velocity, dispatchSelected); + scrollToItem(item, smoothScroll, velocity, dispatchSelected, duration); } } private void scrollToItem(int item, boolean smoothScroll, int velocity, - boolean dispatchSelected) { + boolean dispatchSelected, int duration) { final ItemInfo curInfo = infoForPosition(item); int destY = 0; if (curInfo != null) { @@ -459,7 +471,7 @@ private void scrollToItem(int item, boolean smoothScroll, int velocity, Math.min(curInfo.offset, mLastOffset))); } if (smoothScroll) { - smoothScrollTo(0, destY, velocity); + smoothScrollTo(0, destY, velocity, duration); if (dispatchSelected && mOnPageChangeListener != null) { mOnPageChangeListener.onPageSelected(item); } @@ -672,7 +684,7 @@ float distanceInfluenceForSnapDuration(float f) { * @param y the number of pixels to scroll by on the Y axis */ void smoothScrollTo(int x, int y) { - smoothScrollTo(x, y, 0); + smoothScrollTo(x, y, 0,0); } /** @@ -682,7 +694,7 @@ void smoothScrollTo(int x, int y) { * @param y the number of pixels to scroll by on the Y axis * @param velocity the velocity associated with a fling, if applicable. (0 otherwise) */ - void smoothScrollTo(int x, int y, int velocity) { + void smoothScrollTo(int x, int y, int velocity, int duration) { if (getChildCount() == 0) { // Nothing to do. setScrollingCacheEnabled(false); @@ -708,18 +720,20 @@ void smoothScrollTo(int x, int y, int velocity) { final float distance = halfHeight + halfHeight * distanceInfluenceForSnapDuration(distanceRatio); - int duration = 0; - velocity = Math.abs(velocity); - if (velocity > 0) { - duration = 4 * Math.round(1000 * Math.abs(distance / velocity)); - } else { - final float pageHeight = height * mAdapter.getPageWidth(mCurItem); - final float pageDelta = (float) Math.abs(dx) / (pageHeight + mPageMargin); - duration = (int) ((pageDelta + 1) * 100); + int scrollDuration = duration; + if (duration <= 0) { + velocity = Math.abs(velocity); + if (velocity > 0) { + duration = 4 * Math.round(1000 * Math.abs(distance / velocity)); + } else { + final float pageHeight = height * mAdapter.getPageWidth(mCurItem); + final float pageDelta = (float) Math.abs(dx) / (pageHeight + mPageMargin); + duration = (int) ((pageDelta + 1) * 100); + } + scrollDuration = Math.min(duration, MAX_SETTLE_DURATION); } - duration = Math.min(duration, MAX_SETTLE_DURATION); - mScroller.startScroll(sx, sy, dx, dy, duration); + mScroller.startScroll(sx, sy, dx, dy, scrollDuration); ViewCompat.postInvalidateOnAnimation(this); } @@ -1495,7 +1509,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { mDecorChildCount = decorCount; if (mFirstLayout) { - scrollToItem(mCurItem, false, 0, false); + scrollToItem(mCurItem, false, 0, false, 0); } mFirstLayout = false; } @@ -1911,7 +1925,7 @@ public boolean onTouchEvent(MotionEvent ev) { final int totalDelta = (int) (y - mInitialMotionY); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); - setCurrentItemInternal(nextPage, true, true, initialVelocity); + setCurrentItemInternal(nextPage, true, true, initialVelocity, 0); mActivePointerId = INVALID_POINTER; endDrag(); @@ -1920,7 +1934,7 @@ public boolean onTouchEvent(MotionEvent ev) { break; case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged) { - scrollToItem(mCurItem, true, 0, false); + scrollToItem(mCurItem, true, 0, false, 0); mActivePointerId = INVALID_POINTER; endDrag(); needsInvalidate = mTopEdge.onRelease() | mBottomEdge.onRelease(); @@ -2210,7 +2224,7 @@ public void endFakeDrag() { final int totalDelta = (int) (mLastMotionY - mInitialMotionY); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); - setCurrentItemInternal(nextPage, true, true, initialVelocity); + setCurrentItemInternal(nextPage, true, true, initialVelocity, 0); endDrag(); mFakeDragging = false; diff --git a/mvn_push.gradle b/mvn_push.gradle index 92fdb4d..2b0b6e2 100644 --- a/mvn_push.gradle +++ b/mvn_push.gradle @@ -91,7 +91,7 @@ afterEvaluate { project -> } task androidJavadocs(type: Javadoc) { - source = android.sourceSets.main.allJava + source = android.sourceSets.main.java } task androidJavadocsJar(type: Jar) { @@ -101,7 +101,7 @@ afterEvaluate { project -> task androidSourcesJar(type: Jar) { classifier = 'sources' - from android.sourceSets.main.allSource + from android.sourceSets.main.java } artifacts { diff --git a/sample/build.gradle b/sample/build.gradle index ef7c773..6e64cf8 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'android' +apply plugin: 'kotlin-android' repositories { mavenCentral() @@ -7,15 +8,22 @@ repositories { dependencies { compile project(':library') compile 'com.android.support:support-v13:19.0.0' + compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" } android { - compileSdkVersion 19 - buildToolsVersion "19.0.0" + + def androidCompileSdkVersion = project.androidCompileSdkVersion.toInteger() + def androidTargetSdkVersion = project.androidTargetSdkVersion.toInteger() + def androidMinSdkVersion = project.androidMinSdkVersion.toInteger() + def androidBuildToolsVersion = project.androidBuildToolsVersion.toString() + + compileSdkVersion androidCompileSdkVersion + buildToolsVersion androidBuildToolsVersion defaultConfig { - minSdkVersion 14 - targetSdkVersion 19 + minSdkVersion androidMinSdkVersion + targetSdkVersion androidTargetSdkVersion versionName project.VERSION_NAME versionCode Integer.parseInt(project.VERSION_CODE) } diff --git a/sample/src/main/java/fr/castorflex/android/verticalviewpager/sample/MainActivity.java b/sample/src/main/java/fr/castorflex/android/verticalviewpager/sample/MainActivity.java deleted file mode 100644 index 648db98..0000000 --- a/sample/src/main/java/fr/castorflex/android/verticalviewpager/sample/MainActivity.java +++ /dev/null @@ -1,144 +0,0 @@ -package fr.castorflex.android.verticalviewpager.sample; - -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.support.v13.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import java.util.Locale; - -import fr.castorflex.android.verticalviewpager.VerticalViewPager; - -public class MainActivity extends Activity { - - private static final float MIN_SCALE = 0.75f; - private static final float MIN_ALPHA = 0.75f; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - VerticalViewPager verticalViewPager = (VerticalViewPager) findViewById(R.id.verticalviewpager); - - verticalViewPager.setAdapter(new DummyAdapter(getFragmentManager())); - verticalViewPager.setPageMargin(getResources().getDimensionPixelSize(R.dimen.pagemargin)); - verticalViewPager.setPageMarginDrawable(new ColorDrawable(getResources().getColor(android.R.color.holo_green_dark))); - - verticalViewPager.setPageTransformer(true, new ViewPager.PageTransformer() { - @Override - public void transformPage(View view, float position) { - int pageWidth = view.getWidth(); - int pageHeight = view.getHeight(); - - if (position < -1) { // [-Infinity,-1) - // This page is way off-screen to the left. - view.setAlpha(0); - - } else if (position <= 1) { // [-1,1] - // Modify the default slide transition to shrink the page as well - float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); - float vertMargin = pageHeight * (1 - scaleFactor) / 2; - float horzMargin = pageWidth * (1 - scaleFactor) / 2; - if (position < 0) { - view.setTranslationY(vertMargin - horzMargin / 2); - } else { - view.setTranslationY(-vertMargin + horzMargin / 2); - } - - // Scale the page down (between MIN_SCALE and 1) - view.setScaleX(scaleFactor); - view.setScaleY(scaleFactor); - - // Fade the page relative to its size. - view.setAlpha(MIN_ALPHA + - (scaleFactor - MIN_SCALE) / - (1 - MIN_SCALE) * (1 - MIN_ALPHA)); - - } else { // (1,+Infinity] - // This page is way off-screen to the right. - view.setAlpha(0); - } - } - }); - } - - public class DummyAdapter extends FragmentPagerAdapter { - - public DummyAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int position) { - // getItem is called to instantiate the fragment for the given page. - // Return a PlaceholderFragment (defined as a static inner class below). - return PlaceholderFragment.newInstance(position + 1); - } - - @Override - public int getCount() { - // Show 3 total pages. - return 3; - } - - @Override - public CharSequence getPageTitle(int position) { - Locale l = Locale.getDefault(); - switch (position) { - case 0: - return "PAGE 1"; - case 1: - return "PAGE 2"; - case 2: - return "PAGE 3"; - } - return null; - } - - } - - /** - * A placeholder fragment containing a simple view. - */ - public static class PlaceholderFragment extends Fragment { - /** - * The fragment argument representing the section number for this - * fragment. - */ - private static final String ARG_SECTION_NUMBER = "section_number"; - - /** - * Returns a new instance of this fragment for the given section - * number. - */ - public static PlaceholderFragment newInstance(int sectionNumber) { - PlaceholderFragment fragment = new PlaceholderFragment(); - Bundle args = new Bundle(); - args.putInt(ARG_SECTION_NUMBER, sectionNumber); - fragment.setArguments(args); - return fragment; - } - - public PlaceholderFragment() { - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_layout, container, false); - TextView textView = (TextView) rootView.findViewById(R.id.textview); - textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); - return rootView; - } - - - } - -} diff --git a/sample/src/main/java/fr/castorflex/android/verticalviewpager/sample/MainActivity.kt b/sample/src/main/java/fr/castorflex/android/verticalviewpager/sample/MainActivity.kt new file mode 100644 index 0000000..6b22da0 --- /dev/null +++ b/sample/src/main/java/fr/castorflex/android/verticalviewpager/sample/MainActivity.kt @@ -0,0 +1,133 @@ +package fr.castorflex.android.verticalviewpager.sample + +import android.app.Activity +import android.app.Fragment +import android.app.FragmentManager +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.os.Handler +import android.support.v13.app.FragmentPagerAdapter +import android.support.v4.view.ViewPager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView + +import java.util.Locale + +import fr.castorflex.android.verticalviewpager.VerticalViewPager + +class MainActivity : Activity() { + + private lateinit var verticalViewPager: VerticalViewPager + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + verticalViewPager = findViewById(R.id.verticalviewpager) as VerticalViewPager + + verticalViewPager.adapter = DummyAdapter(fragmentManager) + verticalViewPager.pageMargin = resources.getDimensionPixelSize(R.dimen.pagemargin) + verticalViewPager.setPageMarginDrawable(ColorDrawable(resources.getColor(android.R.color.holo_green_dark))) + + verticalViewPager.setPageTransformer(true) { view, position -> + val pageWidth = view.width + val pageHeight = view.height + + if (position < -1) { // [-Infinity,-1) + // This page is way off-screen to the left. + view.alpha = 0f + + } else if (position <= 1) { // [-1,1] + // Modify the default slide transition to shrink the page as well + val scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)) + val vertMargin = pageHeight * (1 - scaleFactor) / 2 + val horzMargin = pageWidth * (1 - scaleFactor) / 2 + if (position < 0) { + view.translationY = vertMargin - horzMargin / 2 + } else { + view.translationY = -vertMargin + horzMargin / 2 + } + + // Scale the page down (between MIN_SCALE and 1) + view.scaleX = scaleFactor + view.scaleY = scaleFactor + + // Fade the page relative to its size. + view.alpha = MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA) + + } else { // (1,+Infinity] + // This page is way off-screen to the right. + view.alpha = 0f + } + } + } + + inner class DummyAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) { + + override fun getItem(position: Int): Fragment { + // getItem is called to instantiate the fragment for the given page. + // Return a PlaceholderFragment (defined as a static inner class below). + return PlaceholderFragment.newInstance(position + 1) + } + + override fun getCount(): Int { + // Show 3 total pages. + return 3 + } + + override fun getPageTitle(position: Int): CharSequence? { + Locale.getDefault() + when (position) { + 0 -> return "PAGE 1" + 1 -> return "PAGE 2" + 2 -> return "PAGE 3" + } + return null + } + + } + + /** + * A placeholder fragment containing a simple view. + */ + class PlaceholderFragment : Fragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + val rootView = inflater.inflate(R.layout.fragment_layout, container, false) + val textView = rootView.findViewById(R.id.textview) as TextView + textView.text = Integer.toString(if (arguments != null) arguments.getInt(ARG_SECTION_NUMBER,1) else 1) + return rootView + } + + companion object { + /** + * The fragment argument representing the section number for this + * fragment. + */ + private val ARG_SECTION_NUMBER = "section_number" + + /** + * Returns a new instance of this fragment for the given section + * number. + */ + fun newInstance(sectionNumber: Int): PlaceholderFragment { + val fragment = PlaceholderFragment() + val args = Bundle() + args.putInt(ARG_SECTION_NUMBER, sectionNumber) + fragment.arguments = args + return fragment + } + } + + + } + + companion object { + + private val MIN_SCALE = 0.75f + private val MIN_ALPHA = 0.75f + } + +}