/** * Returns view for specified item * * @param index the item index * @return item view or empty view if index is out of bounds */ private View getItemView(int index) { if (viewAdapter == null || viewAdapter.getItemsCount() == 0) { return null; } int count = viewAdapter.getItemsCount(); if (!isValidItemIndex(index)) { return viewAdapter.getEmptyItem(recycle.getEmptyItem(), itemsLayout); } else { while (index < 0) { index = count + index; } } index %= count; return viewAdapter.getItem(index, recycle.getItem(), itemsLayout); }
/** * Scrolls the wheel * * @param delta the scrolling value */ private void doScroll(int delta) { scrollingOffset += delta; int itemHeight = getItemHeight(); int count = scrollingOffset / itemHeight; int pos = currentItem - count; int itemCount = viewAdapter.getItemsCount(); int fixPos = scrollingOffset % itemHeight; if (Math.abs(fixPos) <= itemHeight / 2) { fixPos = 0; } if (isCyclic && itemCount > 0) { if (fixPos > 0) { pos--; count++; } else if (fixPos < 0) { pos++; count--; } // fix position by rotating while (pos < 0) { pos += itemCount; } pos %= itemCount; } else { // if (pos < 0) { count = currentItem; pos = 0; } else if (pos >= itemCount) { count = currentItem - itemCount + 1; pos = itemCount - 1; } else if (pos > 0 && fixPos > 0) { pos--; count++; } else if (pos < itemCount - 1 && fixPos < 0) { pos++; count--; } } int offset = scrollingOffset; if (pos != currentItem) { setCurrentItem(pos, false); } else { invalidate(); } // update offset scrollingOffset = offset - count * itemHeight; if (scrollingOffset > getHeight()) { scrollingOffset = scrollingOffset % getHeight() + getHeight(); } }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (viewAdapter != null && viewAdapter.getItemsCount() > 0) { updateView(); drawItems(canvas); drawCenterRect(canvas); } drawShadows(canvas); }
/** * Sets the current item. Does nothing when index is wrong. * * @param index the item index * @param animated the animation flag */ public void setCurrentItem(int index, boolean animated) { if (viewAdapter == null || viewAdapter.getItemsCount() == 0) { return; // throw? } int itemCount = viewAdapter.getItemsCount(); if (index < 0 || index >= itemCount) { if (isCyclic) { while (index < 0) { index += itemCount; } index %= itemCount; } else { return; // throw? } } if (index != currentItem) { if (animated) { int itemsToScroll = index - currentItem; if (isCyclic) { int scroll = itemCount + Math.min(index, currentItem) - Math.max(index, currentItem); if (scroll < Math.abs(itemsToScroll)) { itemsToScroll = itemsToScroll < 0 ? scroll : -scroll; } } scroll(itemsToScroll, 0); } else { scrollingOffset = 0; int old = currentItem; currentItem = index; notifyChangingListeners(old, currentItem); invalidate(); } } }
/** * Checks whether intem index is valid * * @param index the item index * @return true if item index is not out of bounds or the wheel is cyclic */ private boolean isValidItemIndex(int index) { return viewAdapter != null && viewAdapter.getItemsCount() > 0 && (isCyclic || index >= 0 && index < viewAdapter.getItemsCount()); }