diff --git a/library/libs/android-support-v4.jar b/library/libs/android-support-v4.jar index b9a4279..428bdbc 100644 Binary files a/library/libs/android-support-v4.jar and b/library/libs/android-support-v4.jar differ diff --git a/library/src/com/directionalviewpager/DirectionalViewPager.java b/library/src/android/support/v4/view/DirectionalViewPager.java similarity index 80% rename from library/src/com/directionalviewpager/DirectionalViewPager.java rename to library/src/android/support/v4/view/DirectionalViewPager.java index 17e023d..557aad9 100644 --- a/library/src/com/directionalviewpager/DirectionalViewPager.java +++ b/library/src/android/support/v4/view/DirectionalViewPager.java @@ -15,21 +15,16 @@ * limitations under the License. */ -package com.directionalviewpager; +package android.support.v4.view; import java.util.ArrayList; + import android.content.Context; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.support.v4.os.ParcelableCompat; import android.support.v4.os.ParcelableCompatCreatorCallbacks; -import android.support.v4.view.MotionEventCompat; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.VelocityTrackerCompat; -import android.support.v4.view.VerticalViewPagerCompat; -import android.support.v4.view.ViewConfigurationCompat; -import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; @@ -41,13 +36,14 @@ /** * Layout manager that allows the user to flip horizontally or vertically - * through pages of data. You supply an implementation of a - * {@link PagerAdapter} to generate the pages that the view shows. - * - *

Note this class is currently under early design and - * development. The API will likely change in later updates of - * the compatibility library, requiring changes to the source code - * of apps when they are compiled against the newer version.

+ * through pages of data. You supply an implementation of a {@link PagerAdapter} + * to generate the pages that the view shows. + *

+ * Note this class is currently under early design and development. The API will + * likely change in later updates of the compatibility library, requiring + * changes to the source code of apps when they are compiled against the newer + * version. + *

*/ public class DirectionalViewPager extends ViewPager { private static final String TAG = "DirectionalViewPager"; @@ -59,21 +55,14 @@ public class DirectionalViewPager extends ViewPager { public static final int HORIZONTAL = 0; public static final int VERTICAL = 1; - static class ItemInfo { - Object object; - int position; - boolean scrolling; - } - private final ArrayList mItems = new ArrayList(); private PagerAdapter mAdapter; - private int mCurItem; // Index of currently displayed page. + private int mCurItem; // Index of currently displayed page. private int mRestoredCurItem = -1; private Parcelable mRestoredAdapterState = null; private ClassLoader mRestoredClassLoader = null; private Scroller mScroller; - private VerticalViewPagerCompat.DataSetObserver mObserver; private int mChildWidthMeasureSpec; private int mChildHeightMeasureSpec; @@ -100,8 +89,8 @@ static class ItemInfo { */ private int mActivePointerId = INVALID_POINTER; /** - * Sentinel value for no current active pointer. - * Used by {@link #mActivePointerId}. + * Sentinel value for no current active pointer. Used by + * {@link #mActivePointerId}. */ private static final int INVALID_POINTER = -1; @@ -112,6 +101,8 @@ static class ItemInfo { private int mMinimumVelocity; private int mMaximumVelocity; + DataSetObserver mObserver; + private OnPageChangeListener mOnPageChangeListener; private int mScrollState = SCROLL_STATE_IDLE; @@ -125,14 +116,17 @@ public DirectionalViewPager(Context context, AttributeSet attrs) { super(context, attrs); initViewPager(); - //We default to horizontal, only change if a value is explicitly specified + // We default to horizontal, only change if a value is explicitly + // specified int orientation = attrs.getAttributeIntValue(XML_NS, "orientation", -1); if (orientation != -1) { setOrientation(orientation); } } + @Override void initViewPager() { + super.initViewPager(); setWillNotDraw(false); mScroller = new Scroller(getContext()); final ViewConfiguration configuration = ViewConfiguration.get(getContext()); @@ -152,8 +146,10 @@ private void setScrollState(int newState) { } } + @Override public void setAdapter(PagerAdapter adapter) { if (mAdapter != null) { + VerticalViewPagerCompat.setDataSetObserver(mAdapter, null); } @@ -177,15 +173,18 @@ public void setAdapter(PagerAdapter adapter) { } } + @Override public PagerAdapter getAdapter() { return mAdapter; } + @Override public void setCurrentItem(int item) { mPopulatePending = false; setCurrentItemInternal(item, true, false); } + @Override void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) { if (mAdapter == null || mAdapter.getCount() <= 0) { setScrollingCacheEnabled(false); @@ -200,11 +199,11 @@ void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) { } else if (item >= mAdapter.getCount()) { item = mAdapter.getCount() - 1; } - if (item > (mCurItem+1) || item < (mCurItem-1)) { - // We are doing a jump by more than one page. To avoid + if (item > (mCurItem + 1) || item < (mCurItem - 1)) { + // We are doing a jump by more than one page. To avoid // glitches, we want to keep all current pages in the view // until the scroll ends. - for (int i=0; i 0; int newCurrItem = -1; @@ -325,21 +330,23 @@ void dataSetChanged() { } } + @Override void populate() { if (mAdapter == null) { return; } - // Bail now if we are waiting to populate. This is to hold off + // Bail now if we are waiting to populate. This is to hold off // on creating views from the time the user releases their finger to // fling to a new position until we have finished the scroll to // that position, avoiding glitches from happening at that point. if (mPopulatePending) { - if (DEBUG) Log.i(TAG, "populate is pending, skipping for now..."); + if (DEBUG) + Log.i(TAG, "populate is pending, skipping for now..."); return; } - // Also, don't populate until we are attached to a window. This is to + // Also, don't populate until we are attached to a window. This is to // avoid trying to populate before we have restored our view hierarchy // state and conflicting with what is restored. if (getWindowToken() == null) { @@ -350,29 +357,32 @@ void populate() { final int startPos = mCurItem > 0 ? mCurItem - 1 : mCurItem; final int count = mAdapter.getCount(); - final int endPos = mCurItem < (count-1) ? mCurItem+1 : count-1; + final int endPos = mCurItem < (count - 1) ? mCurItem + 1 : count - 1; - if (DEBUG) Log.v(TAG, "populating: startPos=" + startPos + " endPos=" + endPos); + if (DEBUG) + Log.v(TAG, "populating: startPos=" + startPos + " endPos=" + endPos); // Add and remove pages in the existing list. int lastPos = -1; - for (int i=0; i endPos) && !ii.scrolling) { - if (DEBUG) Log.i(TAG, "removing: " + ii.position + " @ " + i); + if (DEBUG) + Log.i(TAG, "removing: " + ii.position + " @ " + i); mItems.remove(i); i--; mAdapter.destroyItem(this, ii.position, ii.object); } else if (lastPos < endPos && ii.position > startPos) { // The next item is outside of our range, but we have a gap // between it and the last item where we want to have a page - // shown. Fill in the gap. + // shown. Fill in the gap. lastPos++; if (lastPos < startPos) { lastPos = startPos; } while (lastPos <= endPos && lastPos < ii.position) { - if (DEBUG) Log.i(TAG, "inserting: " + lastPos + " @ " + i); + if (DEBUG) + Log.i(TAG, "inserting: " + lastPos + " @ " + i); addNewItem(lastPos, i); lastPos++; i++; @@ -382,12 +392,13 @@ void populate() { } // Add any new pages we need at the end. - lastPos = mItems.size() > 0 ? mItems.get(mItems.size()-1).position : -1; + lastPos = mItems.size() > 0 ? mItems.get(mItems.size() - 1).position : -1; if (lastPos < endPos) { lastPos++; lastPos = lastPos > startPos ? lastPos : startPos; while (lastPos <= endPos) { - if (DEBUG) Log.i(TAG, "appending: " + lastPos); + if (DEBUG) + Log.i(TAG, "appending: " + lastPos); addNewItem(lastPos, -1); lastPos++; } @@ -395,7 +406,7 @@ void populate() { if (DEBUG) { Log.i(TAG, "Current page list:"); - for (int i=0; i CREATOR - = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks() { + public static final Parcelable.Creator CREATOR = ParcelableCompat + .newCreator(new ParcelableCompatCreatorCallbacks() { @Override public SavedState createFromParcel(Parcel in, ClassLoader loader) { return new SavedState(in, loader); } + @Override public SavedState[] newArray(int size) { return new SavedState[size]; @@ -449,35 +461,6 @@ public SavedState[] newArray(int size) { } } - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.position = mCurItem; - ss.adapterState = mAdapter.saveState(); - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - if (!(state instanceof SavedState)) { - super.onRestoreInstanceState(state); - return; - } - - SavedState ss = (SavedState)state; - super.onRestoreInstanceState(ss.getSuperState()); - - if (mAdapter != null) { - mAdapter.restoreState(ss.adapterState, ss.loader); - setCurrentItemInternal(ss.position, false, true); - } else { - mRestoredCurItem = ss.position; - mRestoredAdapterState = ss.adapterState; - mRestoredClassLoader = ss.loader; - } - } - public int getOrientation() { return mOrientation; } @@ -489,17 +472,18 @@ public void setOrientation(int orientation) { break; default: - throw new IllegalArgumentException("Only HORIZONTAL and VERTICAL are valid orientations."); + throw new IllegalArgumentException( + "Only HORIZONTAL and VERTICAL are valid orientations."); } if (orientation == mOrientation) { return; } - //Complete any scroll we are currently in the middle of + // Complete any scroll we are currently in the middle of completeScroll(); - //Reset values + // Reset values mInitialMotion = 0; mLastMotionX = 0; mLastMotionY = 0; @@ -507,7 +491,7 @@ public void setOrientation(int orientation) { mVelocityTracker.clear(); } - //Adjust scroll for new orientation + // Adjust scroll for new orientation mOrientation = orientation; if (mOrientation == HORIZONTAL) { scrollTo(mCurItem * getWidth(), 0); @@ -535,8 +519,9 @@ public void addView(View child, int index, ViewGroup.LayoutParams params) { } } - ItemInfo infoForChild(View child) { - for (int i=0; i Build.VERSION_CODES.DONUT) { - // If we don't have a valid id, the touch down wasn't on content. + if (activePointerId == INVALID_POINTER + && Build.VERSION.SDK_INT > Build.VERSION_CODES.DONUT) { + // If we don't have a valid id, the touch down wasn't on + // content. break; } @@ -774,11 +769,12 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { secondaryDiff = xDiff; } - - if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); + if (DEBUG) + Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (primaryDiff > mTouchSlop && primaryDiff > secondaryDiff) { - if (DEBUG) Log.v(TAG, "Starting drag!"); + if (DEBUG) + Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); if (mOrientation == HORIZONTAL) { @@ -790,10 +786,11 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { } else { if (secondaryDiff > mTouchSlop) { // The finger has moved enough in the vertical - // direction to be counted as a drag... abort + // direction to be counted as a drag... abort // any attempt to drag horizontally, to work correctly // with children that have scrolling containers. - if (DEBUG) Log.v(TAG, "Starting unable to drag!"); + if (DEBUG) + Log.v(TAG, "Starting unable to drag!"); mIsUnableToDrag = true; } } @@ -802,8 +799,8 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { case MotionEvent.ACTION_DOWN: { /* - * Remember location of down touch. - * ACTION_DOWN always refers to pointer index 0. + * Remember location of down touch. ACTION_DOWN always refers to + * pointer index 0. */ if (mOrientation == HORIZONTAL) { mLastMotionX = mInitialMotion = ev.getX(); @@ -825,9 +822,10 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { mIsUnableToDrag = false; } - if (DEBUG) Log.v(TAG, "Down at " + mLastMotionX + "," + mLastMotionY - + " mIsBeingDragged=" + mIsBeingDragged - + "mIsUnableToDrag=" + mIsUnableToDrag); + if (DEBUG) + Log.v(TAG, "Down at " + mLastMotionX + "," + mLastMotionY + + " mIsBeingDragged=" + mIsBeingDragged + + "mIsUnableToDrag=" + mIsUnableToDrag); break; } @@ -837,9 +835,9 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { } /* - * The only time we want to intercept motion events is if we are in the - * drag mode. - */ + * The only time we want to intercept motion events is if we are in the + * drag mode. + */ return mIsBeingDragged; } @@ -847,7 +845,8 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) { - // Don't handle edge touches immediately -- they may actually belong to one of our + // Don't handle edge touches immediately -- they may actually belong + // to one of our // descendants. return false; } @@ -883,7 +882,8 @@ public boolean onTouchEvent(MotionEvent ev) { } case MotionEvent.ACTION_MOVE: if (!mIsBeingDragged) { - final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); + final int pointerIndex = MotionEventCompat.findPointerIndex(ev, + mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); final float xDiff = Math.abs(x - mLastMotionX); @@ -899,10 +899,11 @@ public boolean onTouchEvent(MotionEvent ev) { secondaryDiff = xDiff; } - - if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); + if (DEBUG) + Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (primaryDiff > mTouchSlop && primaryDiff > secondaryDiff) { - if (DEBUG) Log.v(TAG, "Starting drag!"); + if (DEBUG) + Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; if (mOrientation == HORIZONTAL) { mLastMotionX = x; @@ -968,12 +969,12 @@ public boolean onTouchEvent(MotionEvent ev) { int sizeOverThree; if (mOrientation == HORIZONTAL) { - initialVelocity = (int)VelocityTrackerCompat.getXVelocity( + initialVelocity = (int) VelocityTrackerCompat.getXVelocity( velocityTracker, mActivePointerId); lastMotion = mLastMotionX; sizeOverThree = getWidth() / 3; } else { - initialVelocity = (int)VelocityTrackerCompat.getYVelocity( + initialVelocity = (int) VelocityTrackerCompat.getYVelocity( velocityTracker, mActivePointerId); lastMotion = mLastMotionY; sizeOverThree = getHeight() / 3; @@ -981,11 +982,11 @@ public boolean onTouchEvent(MotionEvent ev) { mPopulatePending = true; if ((Math.abs(initialVelocity) > mMinimumVelocity) - || Math.abs(mInitialMotion-lastMotion) >= sizeOverThree) { + || Math.abs(mInitialMotion - lastMotion) >= sizeOverThree) { if (lastMotion > mInitialMotion) { - setCurrentItemInternal(mCurItem-1, true, true); + setCurrentItemInternal(mCurItem - 1, true, true); } else { - setCurrentItemInternal(mCurItem+1, true, true); + setCurrentItemInternal(mCurItem + 1, true, true); } } else { setCurrentItemInternal(mCurItem, true, true); @@ -1069,9 +1070,10 @@ private void setScrollingCacheEnabled(boolean enabled) { } } - private class DataSetObserver implements VerticalViewPagerCompat.DataSetObserver { + private class DataSetObserver extends android.database.DataSetObserver { + @Override - public void onDataSetChanged() { + public void onChanged() { dataSetChanged(); } } diff --git a/library/src/android/support/v4/view/VerticalViewPagerCompat.java b/library/src/android/support/v4/view/VerticalViewPagerCompat.java index 255c0dc..ab5a75b 100644 --- a/library/src/android/support/v4/view/VerticalViewPagerCompat.java +++ b/library/src/android/support/v4/view/VerticalViewPagerCompat.java @@ -1,11 +1,13 @@ + package android.support.v4.view; -public final class VerticalViewPagerCompat { - private VerticalViewPagerCompat() {} +import android.database.DataSetObserver; - public interface DataSetObserver extends PagerAdapter.DataSetObserver {} +public final class VerticalViewPagerCompat { + private VerticalViewPagerCompat() { + } public static void setDataSetObserver(PagerAdapter adapter, DataSetObserver observer) { - adapter.setDataSetObserver(observer); + adapter.registerDataSetObserver(observer); } } diff --git a/sample/res/layout/main.xml b/sample/res/layout/main.xml index c2fe21b..b1a0aec 100644 --- a/sample/res/layout/main.xml +++ b/sample/res/layout/main.xml @@ -20,7 +20,7 @@ android:layout_width="fill_parent" android:layout_height="fill_parent"> -