Adding RTL paging.
Change-Id: Ic27d499cb76c7c30da37ed93f5372dd8441118b7
This commit is contained in:
@@ -256,6 +256,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: this is a reimplementation of View.isLayoutRtl() since that is currently hidden api.
|
||||
*/
|
||||
public boolean isLayoutRtl() {
|
||||
return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by subclasses to mark that data is ready, and that we can begin loading and laying
|
||||
* out pages.
|
||||
@@ -401,17 +408,28 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
|
||||
@Override
|
||||
public void scrollTo(int x, int y) {
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
mUnboundedScrollX = x;
|
||||
|
||||
if (x < 0) {
|
||||
boolean isXBeforeFirstPage = isRtl ? (x > mMaxScrollX) : (x < 0);
|
||||
boolean isXAfterLastPage = isRtl ? (x < 0) : (x > mMaxScrollX);
|
||||
if (isXBeforeFirstPage) {
|
||||
super.scrollTo(0, y);
|
||||
if (mAllowOverScroll) {
|
||||
overScroll(x);
|
||||
if (isRtl) {
|
||||
overScroll(x - mMaxScrollX);
|
||||
} else {
|
||||
overScroll(x);
|
||||
}
|
||||
}
|
||||
} else if (x > mMaxScrollX) {
|
||||
} else if (isXAfterLastPage) {
|
||||
super.scrollTo(mMaxScrollX, y);
|
||||
if (mAllowOverScroll) {
|
||||
overScroll(x - mMaxScrollX);
|
||||
if (isRtl) {
|
||||
overScroll(x);
|
||||
} else {
|
||||
overScroll(x - mMaxScrollX);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mOverScrollX = x;
|
||||
@@ -566,7 +584,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
updateScrollingIndicatorPosition();
|
||||
|
||||
if (childCount > 0) {
|
||||
mMaxScrollX = getChildOffset(childCount - 1) - getRelativeChildOffset(childCount - 1);
|
||||
final int index = isLayoutRtl() ? 0 : childCount - 1;
|
||||
mMaxScrollX = getChildOffset(index) - getRelativeChildOffset(index);
|
||||
} else {
|
||||
mMaxScrollX = 0;
|
||||
}
|
||||
@@ -631,9 +650,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
|
||||
final int verticalPadding = getPaddingTop() + getPaddingBottom();
|
||||
final int childCount = getChildCount();
|
||||
int childLeft = getRelativeChildOffset(0);
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final int startIndex = isRtl ? childCount - 1 : 0;
|
||||
final int endIndex = isRtl ? -1 : childCount;
|
||||
final int delta = isRtl ? -1 : 1;
|
||||
int childLeft = getRelativeChildOffset(startIndex);
|
||||
for (int i = startIndex; i != endIndex; i += delta) {
|
||||
final View child = getPageAt(i);
|
||||
if (child.getVisibility() != View.GONE) {
|
||||
final int childWidth = getScaledMeasuredWidth(child);
|
||||
@@ -710,6 +733,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
}
|
||||
|
||||
protected int getChildOffset(int index) {
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
int[] childOffsets = Float.compare(mLayoutScale, 1f) == 0 ?
|
||||
mChildOffsets : mChildOffsetsWithLayoutScale;
|
||||
|
||||
@@ -719,8 +743,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
if (getChildCount() == 0)
|
||||
return 0;
|
||||
|
||||
int offset = getRelativeChildOffset(0);
|
||||
for (int i = 0; i < index; ++i) {
|
||||
final int startIndex = isRtl ? getChildCount() - 1 : 0;
|
||||
final int endIndex = isRtl ? index : index;
|
||||
final int delta = isRtl ? -1 : 1;
|
||||
int offset = getRelativeChildOffset(startIndex);
|
||||
for (int i = startIndex; i != endIndex; i += delta) {
|
||||
offset += getScaledMeasuredWidth(getPageAt(i)) + mPageSpacing;
|
||||
}
|
||||
if (childOffsets != null) {
|
||||
@@ -754,28 +781,31 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
}
|
||||
|
||||
protected void getVisiblePages(int[] range) {
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
final int pageCount = getChildCount();
|
||||
|
||||
if (pageCount > 0) {
|
||||
final int screenWidth = getMeasuredWidth();
|
||||
int leftScreen = 0;
|
||||
int leftScreen = isRtl ? pageCount - 1 : 0;
|
||||
int rightScreen = 0;
|
||||
int endIndex = isRtl ? 0 : pageCount - 1;
|
||||
int delta = isRtl ? -1 : 1;
|
||||
View currPage = getPageAt(leftScreen);
|
||||
while (leftScreen < pageCount - 1 &&
|
||||
while (leftScreen != endIndex &&
|
||||
currPage.getX() + currPage.getWidth() -
|
||||
currPage.getPaddingRight() < getScrollX()) {
|
||||
leftScreen++;
|
||||
leftScreen += delta;
|
||||
currPage = getPageAt(leftScreen);
|
||||
}
|
||||
rightScreen = leftScreen;
|
||||
currPage = getPageAt(rightScreen + 1);
|
||||
while (rightScreen < pageCount - 1 &&
|
||||
currPage = getPageAt(rightScreen + delta);
|
||||
while (rightScreen != endIndex &&
|
||||
currPage.getX() - currPage.getPaddingLeft() < getScrollX() + screenWidth) {
|
||||
rightScreen++;
|
||||
currPage = getPageAt(rightScreen + 1);
|
||||
rightScreen += delta;
|
||||
currPage = getPageAt(rightScreen + delta);
|
||||
}
|
||||
range[0] = leftScreen;
|
||||
range[1] = rightScreen;
|
||||
range[0] = Math.min(leftScreen, rightScreen);
|
||||
range[1] = Math.max(leftScreen, rightScreen);
|
||||
} else {
|
||||
range[0] = -1;
|
||||
range[1] = -1;
|
||||
@@ -854,6 +884,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
|
||||
@Override
|
||||
public boolean dispatchUnhandledMove(View focused, int direction) {
|
||||
// XXX-RTL: This will be fixed in a future CL
|
||||
if (direction == View.FOCUS_LEFT) {
|
||||
if (getCurrentPage() > 0) {
|
||||
snapToPage(getCurrentPage() - 1);
|
||||
@@ -870,6 +901,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
|
||||
@Override
|
||||
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
|
||||
// XXX-RTL: This will be fixed in a future CL
|
||||
if (mCurrentPage >= 0 && mCurrentPage < getPageCount()) {
|
||||
getPageAt(mCurrentPage).addFocusables(views, direction, focusableMode);
|
||||
}
|
||||
@@ -930,14 +962,23 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
* Return true if a tap at (x, y) should trigger a flip to the previous page.
|
||||
*/
|
||||
protected boolean hitsPreviousPage(float x, float y) {
|
||||
return (x < getRelativeChildOffset(mCurrentPage) - mPageSpacing);
|
||||
if (isLayoutRtl()) {
|
||||
return (x > (getMeasuredWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
|
||||
} else {
|
||||
return (x < getRelativeChildOffset(mCurrentPage) - mPageSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a tap at (x, y) should trigger a flip to the next page.
|
||||
*/
|
||||
protected boolean hitsNextPage(float x, float y) {
|
||||
return (x > (getMeasuredWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
|
||||
if (isLayoutRtl()) {
|
||||
return (x < getRelativeChildOffset(mCurrentPage) - mPageSpacing);
|
||||
} else {
|
||||
return (x > (getMeasuredWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1269,12 +1310,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
// We give flings precedence over large moves, which is why we short-circuit our
|
||||
// test for a large move if a fling has been registered. That is, a large
|
||||
// move to the left and fling to the right will register as a fling to the right.
|
||||
if (((isSignificantMove && deltaX > 0 && !isFling) ||
|
||||
(isFling && velocityX > 0)) && mCurrentPage > 0) {
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
|
||||
boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
|
||||
if (((isSignificantMove && !isDeltaXLeft && !isFling) ||
|
||||
(isFling && !isVelocityXLeft)) && mCurrentPage > 0) {
|
||||
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
|
||||
snapToPageWithVelocity(finalPage, velocityX);
|
||||
} else if (((isSignificantMove && deltaX < 0 && !isFling) ||
|
||||
(isFling && velocityX < 0)) &&
|
||||
} else if (((isSignificantMove && isDeltaXLeft && !isFling) ||
|
||||
(isFling && isVelocityXLeft)) &&
|
||||
mCurrentPage < getChildCount() - 1) {
|
||||
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
|
||||
snapToPageWithVelocity(finalPage, velocityX);
|
||||
@@ -1342,7 +1386,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
|
||||
}
|
||||
if (hscroll != 0 || vscroll != 0) {
|
||||
if (hscroll > 0 || vscroll > 0) {
|
||||
boolean isForwardScroll = isLayoutRtl() ? (hscroll < 0 || vscroll < 0)
|
||||
: (hscroll > 0 || vscroll > 0);
|
||||
if (isForwardScroll) {
|
||||
scrollRight();
|
||||
} else {
|
||||
scrollLeft();
|
||||
@@ -1400,10 +1446,14 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
}
|
||||
|
||||
protected int getChildIndexForRelativeOffset(int relativeOffset) {
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
final int childCount = getChildCount();
|
||||
int left;
|
||||
int right;
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
final int startIndex = isRtl ? childCount - 1 : 0;
|
||||
final int endIndex = isRtl ? -1 : childCount;
|
||||
final int delta = isRtl ? -1 : 1;
|
||||
for (int i = startIndex; i != endIndex; i += delta) {
|
||||
left = getRelativeChildOffset(i);
|
||||
right = (left + getScaledMeasuredWidth(getPageAt(i)));
|
||||
if (left <= relativeOffset && relativeOffset <= right) {
|
||||
@@ -1839,17 +1889,20 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
}
|
||||
|
||||
private void updateScrollingIndicatorPosition() {
|
||||
final boolean isRtl = isLayoutRtl();
|
||||
if (!isScrollingIndicatorEnabled()) return;
|
||||
if (mScrollIndicator == null) return;
|
||||
int numPages = getChildCount();
|
||||
int pageWidth = getMeasuredWidth();
|
||||
int lastChildIndex = Math.max(0, getChildCount() - 1);
|
||||
int maxScrollX = getChildOffset(lastChildIndex) - getRelativeChildOffset(lastChildIndex);
|
||||
int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
|
||||
int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
|
||||
mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
|
||||
|
||||
float offset = Math.max(0f, Math.min(1f, (float) getScrollX() / maxScrollX));
|
||||
float scrollPos = isRtl ? mMaxScrollX - getScrollX() : getScrollX();
|
||||
float offset = Math.max(0f, Math.min(1f, (float) scrollPos / mMaxScrollX));
|
||||
if (isRtl) {
|
||||
offset = 1f - offset;
|
||||
}
|
||||
int indicatorSpace = trackWidth / numPages;
|
||||
int indicatorPos = (int) (offset * (trackWidth - indicatorSpace)) + mScrollIndicatorPaddingLeft;
|
||||
if (hasElasticScrollIndicator()) {
|
||||
|
||||
Reference in New Issue
Block a user