Skip to content

Commit

Permalink
重写NavigatorHelper,代码更加优雅,为新特性做准备
Browse files Browse the repository at this point in the history
  • Loading branch information
hackware1993 committed Sep 11, 2016
1 parent d238916 commit 819d33d
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public void onAnimationUpdate(ValueAnimator animation) {
float positionOffsetSum = (Float) animation.getAnimatedValue();
int position = (int) positionOffsetSum;
float positionOffset = positionOffsetSum - position;
if (positionOffsetSum < 0) {
position = -1;
positionOffset = 1.0f + positionOffset;
}
dispatchPageScrolled(position, positionOffset, 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,190 +10,152 @@
* Created by hackware on 2016/6/26.
*/
public class NavigatorHelper {
private int mCurrentIndex;
private int mTotalCount;
private int mScrollState = ScrollState.SCROLL_STATE_IDLE;

// 转换后的回调
private OnNavigatorScrollListener mNavigatorScrollListener;

// 记录有哪些item处于未选中、未完全leave状态
private SparseBooleanArray mDeselectedItems = new SparseBooleanArray();
private SparseArray<Float> mLeavedPercents = new SparseArray<Float>();

private float mLastPositionOffsetSum;
private int mTotalCount;
private int mCurrentIndex;
private int mLastIndex;
private boolean mSkimOver;

public NavigatorHelper() {
}
private float mLastPositionOffsetSum;
private int mScrollState;

public int getSafeIndex(int index) {
return Math.max(Math.min(index, mTotalCount - 1), 0);
}
private boolean mSkimOver;
private NavigatorHelper.OnNavigatorScrollListener mNavigatorScrollListener;

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mNavigatorScrollListener != null) {
float currentPositionOffsetSum = position + positionOffset;
boolean leftToRight = currentPositionOffsetSum >= mLastPositionOffsetSum;
int safePosition = getSafeIndex(position);
if (mScrollState != ScrollState.SCROLL_STATE_IDLE) {
int enterIndex;
int leaveIndex;
float enterPercent;
float leavePercent;
float currentPositionOffsetSum = position + positionOffset;
boolean leftToRight = false;
if (mLastPositionOffsetSum <= currentPositionOffsetSum) {
leftToRight = true;
}
if (mScrollState != ScrollState.SCROLL_STATE_IDLE) {
if (currentPositionOffsetSum == mLastPositionOffsetSum) {
return;
}
int nextPosition = position + 1;
boolean normalDispatch = true;
if (positionOffset == 0.0f) {
if (leftToRight) {
enterIndex = getSafeIndex(position + 1);
enterPercent = positionOffset;
leaveIndex = safePosition;
leavePercent = positionOffset;
} else {
enterIndex = safePosition;
enterPercent = 1.0f - positionOffset;
leaveIndex = getSafeIndex(safePosition + 1);
leavePercent = 1.0f - positionOffset;
nextPosition = position - 1;
normalDispatch = false;
}
for (int i = 0; i < mTotalCount; i++) {
if (i == enterIndex || i == leaveIndex) {
continue;
}
Float leavedPercent = mLeavedPercents.get(i, 0.0f);
if (leavedPercent != 1.0f) {
mNavigatorScrollListener.onLeave(i, mTotalCount, 1.0f, leftToRight);
mLeavedPercents.put(i, 1.0f);
}
}
if (enterIndex == leaveIndex) {
if (enterIndex == mTotalCount - 1 && mLeavedPercents.get(enterIndex, 0.0f) != 0.0f && enterPercent == 0.0f && leftToRight) {
boolean dispatchEnterEvent = mSkimOver || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || enterIndex == mCurrentIndex;
if (dispatchEnterEvent) {
mNavigatorScrollListener.onEnter(enterIndex, mTotalCount, 1.0f, true);
mLeavedPercents.put(enterIndex, 0.0f);
}
}
return;
}
for (int i = 0; i < mTotalCount; i++) {
if (i == position || i == nextPosition) {
continue;
}
if (1.0f - mLeavedPercents.get(enterIndex, 0.0f) != enterPercent) {
boolean dispatchEnterEvent = mSkimOver || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || enterIndex == mCurrentIndex;
if (dispatchEnterEvent) {
mNavigatorScrollListener.onEnter(enterIndex, mTotalCount, enterPercent, leftToRight);
mLeavedPercents.put(enterIndex, 1.0f - enterPercent);
}
Float leavedPercent = mLeavedPercents.get(i, 0.0f);
if (leavedPercent != 1.0f) {
dispatchOnLeave(i, 1.0f, leftToRight, true);
}
if (mLeavedPercents.get(leaveIndex, 0.0f) != leavePercent) {
if (leftToRight && leaveIndex == getCurrentIndex() && leavePercent == 0.0f) {
boolean dispatchEnterEvent = mSkimOver || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || leaveIndex == mCurrentIndex;
if (dispatchEnterEvent) {
mNavigatorScrollListener.onEnter(leaveIndex, mTotalCount, 1.0f, true);
mLeavedPercents.put(leaveIndex, 0.0f);
}
} else {
boolean dispatchLeaveEvent = mSkimOver
|| mScrollState == ScrollState.SCROLL_STATE_DRAGGING
|| leaveIndex == mLastIndex
|| (leaveIndex == mCurrentIndex - 1 && mLeavedPercents.get(leaveIndex, 0.0f) != 1.0f)
|| (leaveIndex == mCurrentIndex + 1 && mLeavedPercents.get(leaveIndex, 0.0f) != 1.0f);
if (dispatchLeaveEvent) {
mNavigatorScrollListener.onLeave(leaveIndex, mTotalCount, leavePercent, leftToRight);
mLeavedPercents.put(leaveIndex, leavePercent);
}
}
}
if (normalDispatch) {
if (leftToRight) {
dispatchOnLeave(position, positionOffset, true, false);
dispatchOnEnter(nextPosition, positionOffset, true, false);
} else {
dispatchOnLeave(nextPosition, 1.0f - positionOffset, false, false);
dispatchOnEnter(position, 1.0f - positionOffset, false, false);
}
} else {
for (int i = 0; i < mTotalCount; i++) {
if (i == mCurrentIndex) {
continue;
}
boolean deselected = mDeselectedItems.get(i);
if (!deselected) {
mNavigatorScrollListener.onDeselected(i, mTotalCount);
mDeselectedItems.put(i, true);
}
Float leavedPercent = mLeavedPercents.get(i, 0.0f);
if (leavedPercent != 1.0f) {
mNavigatorScrollListener.onLeave(i, mTotalCount, 1.0f, leftToRight);
mLeavedPercents.put(i, 1.0f);
}
}
mNavigatorScrollListener.onEnter(mCurrentIndex, mTotalCount, 1.0f, false);
mLeavedPercents.put(mCurrentIndex, 0.0f);
mNavigatorScrollListener.onSelected(mCurrentIndex, mTotalCount);
mDeselectedItems.put(mCurrentIndex, false);
dispatchOnLeave(nextPosition, 1.0f - positionOffset, true, false);
dispatchOnEnter(position, 1.0f - positionOffset, true, false);
}
mLastPositionOffsetSum = currentPositionOffsetSum;
}
}

public void onPageSelected(int position) {
int currentIndex = setCurrentIndex(position);
if (mNavigatorScrollListener != null) {
mNavigatorScrollListener.onSelected(currentIndex, mTotalCount);
mDeselectedItems.put(currentIndex, false);
for (int i = 0, j = mTotalCount; i < j; i++) {
if (i == currentIndex) {
} else {
for (int i = 0; i < mTotalCount; i++) {
if (i == mCurrentIndex) {
continue;
}
boolean deselected = mDeselectedItems.get(i);
if (!deselected) {
mNavigatorScrollListener.onDeselected(i, mTotalCount);
mDeselectedItems.put(i, true);
dispatchOnDeselected(i);
}
Float leavedPercent = mLeavedPercents.get(i, 0.0f);
if (leavedPercent != 1.0f) {
dispatchOnLeave(i, 1.0f, false, true);
}
}
dispatchOnEnter(mCurrentIndex, 1.0f, false, true);
dispatchOnSelected(mCurrentIndex);
}
mLastPositionOffsetSum = currentPositionOffsetSum;
}

public void onPageScrollStateChanged(int state) {
mScrollState = state;
private void dispatchOnEnter(int index, float enterPercent, boolean leftToRight, boolean force) {
if (mSkimOver || index == mCurrentIndex || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || force) {
if (mNavigatorScrollListener != null) {
mNavigatorScrollListener.onEnter(index, mTotalCount, enterPercent, leftToRight);
}
mLeavedPercents.put(index, 1.0f - enterPercent);
}
}

public int getCurrentIndex() {
return getSafeIndex(mCurrentIndex);
private void dispatchOnLeave(int index, float leavePercent, boolean leftToRight, boolean force) {
if (mSkimOver || index == mLastIndex || mScrollState == ScrollState.SCROLL_STATE_DRAGGING || ((index == mCurrentIndex - 1 || index == mCurrentIndex + 1) && mLeavedPercents.get(index, 0.0f) != 1.0f) || force) {
if (mNavigatorScrollListener != null) {
mNavigatorScrollListener.onLeave(index, mTotalCount, leavePercent, leftToRight);
}
mLeavedPercents.put(index, leavePercent);
}
}

private int setCurrentIndex(int currentIndex) {
mLastIndex = mCurrentIndex;
mCurrentIndex = getSafeIndex(currentIndex);
return mCurrentIndex;
private void dispatchOnSelected(int index) {
if (mNavigatorScrollListener != null) {
mNavigatorScrollListener.onSelected(index, mTotalCount);
}
mDeselectedItems.put(index, false);
}

public int getTotalCount() {
return mTotalCount;
private void dispatchOnDeselected(int index) {
if (mNavigatorScrollListener != null) {
mNavigatorScrollListener.onDeselected(index, mTotalCount);
}
mDeselectedItems.put(index, true);
}

public void setTotalCount(int totalCount) {
mTotalCount = totalCount;
mDeselectedItems.clear();
mLeavedPercents.clear();
public void onPageSelected(int position) {
mLastIndex = mCurrentIndex;
mCurrentIndex = position;
dispatchOnSelected(mCurrentIndex);
for (int i = 0; i < mTotalCount; i++) {
if (i == mCurrentIndex) {
continue;
}
boolean deselected = mDeselectedItems.get(i);
if (!deselected) {
dispatchOnDeselected(i);
}
}
}

public int getScrollState() {
return mScrollState;
public void onPageScrollStateChanged(int state) {
mScrollState = state;
}

public boolean isSkimOver() {
return mSkimOver;
public void setNavigatorScrollListener(NavigatorHelper.OnNavigatorScrollListener navigatorScrollListener) {
mNavigatorScrollListener = navigatorScrollListener;
}

public void setSkimOver(boolean skimOver) {
mSkimOver = skimOver;
}

public OnNavigatorScrollListener getNavigatorScrollListener() {
return mNavigatorScrollListener;
public void setTotalCount(int totalCount) {
mTotalCount = totalCount;
mDeselectedItems.clear();
mLeavedPercents.clear();
}

public void setNavigatorScrollListener(OnNavigatorScrollListener navigatorScrollListener) {
mNavigatorScrollListener = navigatorScrollListener;
public int getTotalCount() {
return mTotalCount;
}

public void clear() {
mTotalCount = 0;
mCurrentIndex = 0;
mLastIndex = 0;
mLastPositionOffsetSum = 0.0f;
mScrollState = ScrollState.SCROLL_STATE_IDLE;
mDeselectedItems.clear();
mLeavedPercents.clear();
public int getCurrentIndex() {
return mCurrentIndex;
}

public int getScrollState() {
return mScrollState;
}

public interface OnNavigatorScrollListener {
Expand Down

0 comments on commit 819d33d

Please sign in to comment.