From 548a9ffd7bf19228d86d823eb14f9835d213c0f6 Mon Sep 17 00:00:00 2001 From: Gil Shapira Date: Sun, 10 Jul 2011 16:52:39 +0300 Subject: [PATCH 1/4] Use a DecelerateInterpolator to have more natural movement on long horizontal scrolls --- .../github/ysamlan/horizontalpager/HorizontalPager.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/com/github/ysamlan/horizontalpager/HorizontalPager.java b/src/com/github/ysamlan/horizontalpager/HorizontalPager.java index 0ccc6cf..8fd55b4 100644 --- a/src/com/github/ysamlan/horizontalpager/HorizontalPager.java +++ b/src/com/github/ysamlan/horizontalpager/HorizontalPager.java @@ -30,6 +30,8 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; import android.widget.Scroller; /** @@ -70,6 +72,7 @@ public final class HorizontalPager extends ViewGroup { private static final int SNAP_VELOCITY_DIP_PER_SECOND = 600; // Argument to getVelocity for units to give pixels per second (1 = pixels per millisecond). private static final int VELOCITY_UNIT_PIXELS_PER_SECOND = 1000; + private static final float INTERPOLATION_FACTOR = 1.75f; private static final int TOUCH_STATE_REST = 0; private static final int TOUCH_STATE_HORIZONTAL_SCROLLING = 1; @@ -124,7 +127,9 @@ public HorizontalPager(final Context context, final AttributeSet attrs) { * Sets up the scroller and touch/fling sensitivity parameters for the pager. */ private void init() { - mScroller = new Scroller(getContext()); + // use a DecelerateInterpolator to have more natural movement on long horizontal scrolls + Interpolator interpolator = new DecelerateInterpolator(INTERPOLATION_FACTOR); + mScroller = new Scroller(getContext(), interpolator); // Calculate the density-dependent snap velocity in pixels DisplayMetrics displayMetrics = new DisplayMetrics(); From 9edd382b70f32ffc722c900d8eac00195af095d0 Mon Sep 17 00:00:00 2001 From: Gil Shapira Date: Sun, 10 Jul 2011 17:31:50 +0300 Subject: [PATCH 2/4] The current screen persists through orientation changes (added code by Accused187) --- .../activity_tabbed_horizontal_pager_demo.xml | 2 +- res/values/ids.xml | 4 ++ .../horizontalpager/HorizontalPager.java | 56 ++++++++++++++++++- .../horizontalpager/HorizontalPagerDemo.java | 1 + .../TabbedHorizontalPagerDemo.java | 9 ++- 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 res/values/ids.xml diff --git a/res/layout/activity_tabbed_horizontal_pager_demo.xml b/res/layout/activity_tabbed_horizontal_pager_demo.xml index ce75f95..637ab71 100644 --- a/res/layout/activity_tabbed_horizontal_pager_demo.xml +++ b/res/layout/activity_tabbed_horizontal_pager_demo.xml @@ -30,7 +30,7 @@ android:text="#3" /> diff --git a/res/values/ids.xml b/res/values/ids.xml new file mode 100644 index 0000000..636398b --- /dev/null +++ b/res/values/ids.xml @@ -0,0 +1,4 @@ + + + + diff --git a/src/com/github/ysamlan/horizontalpager/HorizontalPager.java b/src/com/github/ysamlan/horizontalpager/HorizontalPager.java index 8fd55b4..c00dfa8 100644 --- a/src/com/github/ysamlan/horizontalpager/HorizontalPager.java +++ b/src/com/github/ysamlan/horizontalpager/HorizontalPager.java @@ -21,6 +21,8 @@ package com.github.ysamlan.horizontalpager; import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.Display; @@ -143,6 +145,22 @@ private void init() { mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); } + @Override + protected Parcelable onSaveInstanceState() { + final SavedState state = new SavedState(super.onSaveInstanceState()); + state.mCurrentScreen = mCurrentScreen; + return state; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + SavedState savedState = (SavedState) state; + super.onRestoreInstanceState(savedState.getSuperState()); + if (savedState.mCurrentScreen != -1) { + mCurrentScreen = savedState.mCurrentScreen; + } + } + @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); @@ -167,9 +185,7 @@ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec if (mFirstLayout) { scrollTo(mCurrentScreen * width, 0); mFirstLayout = false; - } - - else if (width != mLastSeenLayoutWidth) { // Width has changed + } else if (width != mLastSeenLayoutWidth) { // Width has changed /* * Recalculate the width and scroll to the right position to be sure we're in the right * place in the event that we had a rotation that didn't result in an activity restart @@ -506,4 +522,38 @@ public static interface OnScreenSwitchListener { */ void onScreenSwitched(int screen); } + + /** + * A parcelable so we can save our current screen and return to it after an activity destroy. + */ + public static class SavedState extends BaseSavedState { + + private int mCurrentScreen = -1; + + public SavedState(Parcelable superState) { + super(superState); + } + + public SavedState(Parcel in) { + super(in); + mCurrentScreen = in.readInt(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(mCurrentScreen); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + } diff --git a/src/com/github/ysamlan/horizontalpager/HorizontalPagerDemo.java b/src/com/github/ysamlan/horizontalpager/HorizontalPagerDemo.java index 82d2406..36e3162 100644 --- a/src/com/github/ysamlan/horizontalpager/HorizontalPagerDemo.java +++ b/src/com/github/ysamlan/horizontalpager/HorizontalPagerDemo.java @@ -20,6 +20,7 @@ public void onCreate(final Bundle savedInstanceState) { // Create the view switcher HorizontalPager realViewSwitcher = new HorizontalPager(getApplicationContext()); + realViewSwitcher.setId(R.id.horizontal_pager); // Add some views to it final int[] backgroundColors = diff --git a/src/com/github/ysamlan/horizontalpager/TabbedHorizontalPagerDemo.java b/src/com/github/ysamlan/horizontalpager/TabbedHorizontalPagerDemo.java index 1b205e4..5c3ae1e 100644 --- a/src/com/github/ysamlan/horizontalpager/TabbedHorizontalPagerDemo.java +++ b/src/com/github/ysamlan/horizontalpager/TabbedHorizontalPagerDemo.java @@ -19,9 +19,7 @@ public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tabbed_horizontal_pager_demo); mPager = (HorizontalPager) findViewById(R.id.horizontal_pager); - mPager.setOnScreenSwitchListener(onScreenSwitchListener); mRadioGroup = (RadioGroup) findViewById(R.id.tabs); - mRadioGroup.setOnCheckedChangeListener(onCheckedChangedListener); // Go to the simple demo if the user clicks on the simple demo button findViewById(R.id.simple_demo_btn).setOnClickListener(new View.OnClickListener() { @@ -32,6 +30,13 @@ public void onClick(final View v) { } }); } + + @Override + protected void onResume() { + super.onResume(); + mPager.setOnScreenSwitchListener(onScreenSwitchListener); + mRadioGroup.setOnCheckedChangeListener(onCheckedChangedListener); + } private final HorizontalPager.OnScreenSwitchListener onScreenSwitchListener = new HorizontalPager.OnScreenSwitchListener() { From 2700a5a70a69f1dc67fd78147e8a058c6c4b6714 Mon Sep 17 00:00:00 2001 From: Gil Shapira Date: Sun, 10 Jul 2011 18:17:33 +0300 Subject: [PATCH 3/4] Added a demo activity for lists. The ListHorizontalPagerDemo activity contains an HorizontalPager with three ListViews. This demonstrates the problem where the HorizontalPager gets locked into vertical scrolling until it's tapped. --- AndroidManifest.xml | 3 + .../activity_list_horizontal_pager_demo.xml | 29 +++++++++ .../activity_tabbed_horizontal_pager_demo.xml | 21 ++++-- .../ListHorizontalPagerDemo.java | 65 +++++++++++++++++++ .../TabbedHorizontalPagerDemo.java | 9 +++ 5 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 res/layout/activity_list_horizontal_pager_demo.xml create mode 100644 src/com/github/ysamlan/horizontalpager/ListHorizontalPagerDemo.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index ca061c6..0701157 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -26,5 +26,8 @@ + \ No newline at end of file diff --git a/res/layout/activity_list_horizontal_pager_demo.xml b/res/layout/activity_list_horizontal_pager_demo.xml new file mode 100644 index 0000000..2f92f4f --- /dev/null +++ b/res/layout/activity_list_horizontal_pager_demo.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/res/layout/activity_tabbed_horizontal_pager_demo.xml b/res/layout/activity_tabbed_horizontal_pager_demo.xml index 637ab71..a0ee63e 100644 --- a/res/layout/activity_tabbed_horizontal_pager_demo.xml +++ b/res/layout/activity_tabbed_horizontal_pager_demo.xml @@ -71,9 +71,20 @@ android:background="#00f" /> -