androidx.recyclerview.widget.RecyclerView#SCROLL_STATE_DRAGGING源码实例Demo

下面列出了androidx.recyclerview.widget.RecyclerView#SCROLL_STATE_DRAGGING 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: a   文件: FastScroller.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    if (isEnabled()) {
        switch (newState) {
            case RecyclerView.SCROLL_STATE_DRAGGING:
                getHandler().removeCallbacks(mScrollbarHider);
                cancelAnimation(mScrollbarAnimator);
                if (!isViewVisible(mScrollbar)) {
                    showScrollbar();
                }
                break;
            case RecyclerView.SCROLL_STATE_IDLE:
                if (mFadeScrollbar && !mHandleView.isSelected()) {
                    getHandler().postDelayed(mScrollbarHider, sScrollbarHideDelay);
                }
                break;
        }
    }
}
 
源代码2 项目: AndroidProject   文件: BaseAdapter.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {

    if (mScrollingListener == null) {
        return;
    }

    if (newState == RecyclerView.SCROLL_STATE_IDLE) {

        if (!recyclerView.canScrollVertically(1)) {
            //是否能向下滚动,false 表示已经滚动到底部
            mScrollingListener.onScrollDown(recyclerView);
        } else if (!recyclerView.canScrollVertically(-1)) {
            //是否能向上滚动,false 表示已经滚动到顶部
            mScrollingListener.onScrollTop(recyclerView);
        }

    } else if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
        //正在滚动中
        mScrollingListener.onScrolling(recyclerView);
    }
}
 
源代码3 项目: MyBookshelf   文件: FastScroller.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    if (isEnabled()) {
        switch (newState) {
            case RecyclerView.SCROLL_STATE_DRAGGING:
                getHandler().removeCallbacks(mScrollbarHider);
                cancelAnimation(mScrollbarAnimator);
                if (!isViewVisible(mScrollbar)) {
                    showScrollbar();
                }
                break;
            case RecyclerView.SCROLL_STATE_IDLE:
                if (mFadeScrollbar && !mHandleView.isSelected()) {
                    getHandler().postDelayed(mScrollbarHider, sScrollbarHideDelay);
                }
                break;
        }
    }
}
 
@Override
public void onScrollStateChanged(int state) {
    if (mCurrentScrollState == RecyclerView.SCROLL_STATE_IDLE && mCurrentScrollState != state) {
        mScrollStateListener.onScrollStart();
    }

    if (state == RecyclerView.SCROLL_STATE_IDLE) {
        //Scroll is not finished until current view is centered
        boolean isScrollEnded = onScrollEnd();
        if (isScrollEnded) {
            mScrollStateListener.onScrollEnd();
        } else {
            //Scroll continues and we don't want to set mCurrentScrollState to STATE_IDLE,
            //because this will then trigger .mScrollStateListener.onScrollStart()
            return;
        }
    } else if (state == RecyclerView.SCROLL_STATE_DRAGGING) {
        onDragStart();
    }
    mCurrentScrollState = state;
}
 
@Override
public void onScrollStateChanged(int state) {
    super.onScrollStateChanged(state);
    switch (state) {
        case RecyclerView.SCROLL_STATE_DRAGGING:
            //当手指按下时,停止当前正在播放的动画
            cancelAnimator();
            break;
        case RecyclerView.SCROLL_STATE_IDLE:
            //当列表滚动停止后,判断一下自动选中是否打开
            if (isAutoSelect) {
                //找到离目标落点最近的item索引
                smoothScrollToPosition(findShouldSelectPosition());
            }
            break;
        default:
            break;
    }
}
 
@Override
public final void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);

    switch (newState) {
        case RecyclerView.SCROLL_STATE_IDLE:
            isCanScrolledCallback = false;
            if (isIdleCallBack()) {
                if (callbackType == 1) {
                    onScrolledToTop();
                } else if (callbackType == 2) {
                    onScrolledToBottom();
                }
            }
            break;
        case RecyclerView.SCROLL_STATE_DRAGGING:
            isCanScrolledCallback = true;
            break;
    }
}
 
源代码7 项目: sketch   文件: ScrollingPauseLoadManager.java
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);

    if (AppConfig.INSTANCE.getBoolean(recyclerView.getContext(), AppConfig.Key.SCROLLING_PAUSE_LOAD) && recyclerView.getAdapter() != null) {
        if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
            sketch.getConfiguration().setPauseLoadEnabled(true);
        } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            if (sketch.getConfiguration().isPauseLoadEnabled()) {
                sketch.getConfiguration().setPauseLoadEnabled(false);
                recyclerView.getAdapter().notifyDataSetChanged();
            }
        }
    }

    if (recyclerScrollListener != null) {
        recyclerScrollListener.onScrollStateChanged(recyclerView, newState);
    }
}
 
源代码8 项目: mollyim-android   文件: ConversationFragment.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
  if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
    conversationDateHeader.show();
  } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
    conversationDateHeader.hide();
  }
}
 
源代码9 项目: LeanbackTvSample   文件: ContentFragment.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    switch (newState) {
        //当屏幕滚动且用户使用的触碰或手指还在屏幕上,停止加载图片
        case RecyclerView.SCROLL_STATE_DRAGGING:
            //由于用户的操作,屏幕产生惯性滑动,停止加载图片
        case RecyclerView.SCROLL_STATE_SETTLING:
            Glide.with(mActivity).pauseRequests();
            break;
        case RecyclerView.SCROLL_STATE_IDLE:
            Glide.with(mActivity).resumeRequests();
    }
}
 
源代码10 项目: PixImagePicker   文件: Pix.java
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);

    if (recyclerView.isEnabled()) {
        switch (newState) {
            case RecyclerView.SCROLL_STATE_DRAGGING:
                handler.removeCallbacks(mScrollbarHider);
                if (mScrollbar.getVisibility() != View.VISIBLE) {
                    Utility.cancelAnimation(mScrollbarAnimator);
                    if (!Utility.isViewVisible(mScrollbar) && (recyclerView.computeVerticalScrollRange()
                            - mViewHeight > 0)) {

                        mScrollbarAnimator = Utility.showScrollbar(mScrollbar, Pix.this);
                    }
                }
                break;
            case RecyclerView.SCROLL_STATE_IDLE:
                if (mHideScrollbar && !mHandleView.isSelected()) {
                    handler.postDelayed(mScrollbarHider, sScrollbarHideDelay);
                }
                break;
            default:
                break;
        }
    }
}
 
源代码11 项目: CardSlideView   文件: GalleryLayoutManager.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    state = newState;
    if (state == RecyclerView.SCROLL_STATE_DRAGGING) {
        isDrag = true;
    }
    if (state == RecyclerView.SCROLL_STATE_IDLE) {
        isDrag = false;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager == null) {
            return;
        }
        if (mSnapHelper == null) {
            return;
        }
        View snap = mSnapHelper.findSnapView(layoutManager);
        if (snap == null) {
            return;
        }
        int selectedPosition = layoutManager.getPosition(snap);
        if (mOnPageChangeListener != null && selectedPosition != mCurItem) {
            mCurItem = selectedPosition;
            mOnPageChangeListener.onPageSelected(mCurItem);
        }
    }
}
 
@Override
public void onScrollStateChanged(int state) {
    if (state == RecyclerView.SCROLL_STATE_DRAGGING) {
        needSnap = true;
    }
    super.onScrollStateChanged(state);
}
 
源代码13 项目: monero-wallet-android-app   文件: WeSwipeHelper.java
/**
 * Checks whether we should select a View for swiping.
 */
boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
    if (mSelected != null || action != MotionEvent.ACTION_MOVE
            || mActionState == ACTION_STATE_DRAG || !mCallback.isItemViewSwipeEnabled()) {
        return false;
    }
    if (mRecyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
        return false;
    }
    final RecyclerView.ViewHolder vh = findSwipedView(motionEvent);
    if (vh == null) {
        return false;
    }
    final int movementFlags = mCallback.getAbsoluteMovementFlags(mRecyclerView, vh);

    final int swipeFlags = (movementFlags & ACTION_MODE_SWIPE_MASK)
            >> (DIRECTION_FLAG_COUNT * ACTION_STATE_SWIPE);

    if (swipeFlags == 0) {
        return false;
    }

    // mDx and mDy are only set in allowed directions. We use custom x/y here instead of
    // updateDxDy to avoid swiping if user moves more in the other direction
    final float x = motionEvent.getX(pointerIndex);
    final float y = motionEvent.getY(pointerIndex);

    // Calculate the distance moved
    final float dx = x - mInitialTouchX;
    final float dy = y - mInitialTouchY;
    // swipe target is chose w/o applying flags so it does not really check if swiping in that
    // direction is allowed. This why here, we use mDx mDy to check slope value again.
    final float absDx = Math.abs(dx);
    final float absDy = Math.abs(dy);

    if (absDx < mSlop && absDy < mSlop) {
        return false;
    }
    if (absDx > absDy) {
        if (dx < 0 && (swipeFlags & LEFT) == 0) {
            return false;
        }
        if (dx > 0 && (swipeFlags & RIGHT) == 0) {
            return false;
        }
    } else {
        if (dy < 0 && (swipeFlags & UP) == 0) {
            return false;
        }
        if (dy > 0 && (swipeFlags & DOWN) == 0) {
            return false;
        }
    }
    mDx = mDy = 0f;
    mActivePointerId = motionEvent.getPointerId(0);
    select(vh, ACTION_STATE_SWIPE, false);
    return true;
}
 
源代码14 项目: CrazyDaily   文件: ItemTouchHelperExtension.java
/**
 * Checks whether we should select a View for swiping.
 */
private boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
    if (mSelected != null || action != MotionEvent.ACTION_MOVE
            || mActionState == ACTION_STATE_DRAG || !mCallback.isItemViewSwipeEnabled()) {
        return false;
    }
    if (mRecyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
        return false;
    }
    final ViewHolder vh = findSwipedView(motionEvent);
    if (vh == null) {
        return false;
    }
    final int movementFlags = mCallback.getAbsoluteMovementFlags(mRecyclerView, vh);

    final int swipeFlags = (movementFlags & ACTION_MODE_SWIPE_MASK)
            >> (DIRECTION_FLAG_COUNT * ACTION_STATE_SWIPE);

    if (swipeFlags == 0) {
        return false;
    }

    // mDx and mDy are only set in allowed directions. We use custom x/y here instead of
    // updateDxDy to avoid swiping if user moves more in the other direction
    final float x = MotionEventCompat.getX(motionEvent, pointerIndex);
    final float y = MotionEventCompat.getY(motionEvent, pointerIndex);

    // Calculate the distance moved
    final float dx = x - mInitialTouchX;
    final float dy = y - mInitialTouchY;
    // swipe target is chose w/o applying flags so it does not really check if swiping in that
    // direction is allowed. This why here, we use mDx mDy to check slope value again.
    final float absDx = Math.abs(dx);
    final float absDy = Math.abs(dy);

    if (absDx < mSlop && absDy < mSlop) {
        return false;
    }
    if (absDx > absDy) {
        if (dx < 0 && (swipeFlags & LEFT) == 0) {
            return false;
        }
        if (dx > 0 && (swipeFlags & RIGHT) == 0) {
            return false;
        }
    } else {
        if (dy < 0 && (swipeFlags & UP) == 0) {
            return false;
        }
        if (dy > 0 && (swipeFlags & DOWN) == 0) {
            return false;
        }
    }
    mDx = mDy = 0f;
    mActivePointerId = MotionEventCompat.getPointerId(motionEvent, 0);
    select(vh, ACTION_STATE_SWIPE);
    if (mPreOpened != null && mPreOpened != vh && vh != null) {
        closeOpenedPreItem();
    }
    return true;
}
 
源代码15 项目: RecyclerViewAdapter   文件: RcvStickyLayout.java
private void updateScrollState(int scrollState)
{
    int firstVisibleP = RecyclerView.NO_POSITION;
    int firstCompleteVisibleP = RecyclerView.NO_POSITION;
    if (mLayoutManager instanceof LinearLayoutManager)
    {
        firstVisibleP = ((LinearLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
        firstCompleteVisibleP = ((LinearLayoutManager) mLayoutManager).findFirstCompletelyVisibleItemPosition();
    } else if (mLayoutManager instanceof GridLayoutManager)
    {
        firstVisibleP = ((GridLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
        firstCompleteVisibleP = ((GridLayoutManager) mLayoutManager).findFirstCompletelyVisibleItemPosition();
    } else if (mLayoutManager instanceof StaggeredGridLayoutManager)
    {
        firstVisibleP = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(null)[0];
        firstCompleteVisibleP = ((StaggeredGridLayoutManager) mLayoutManager).findFirstCompletelyVisibleItemPositions(null)[0];
    }

    //需要隐藏悬浮布局的时机
    if (mFirstStickyPosition == RecyclerView.NO_POSITION || firstVisibleP == RecyclerView.NO_POSITION
            || firstVisibleP < mFirstStickyPosition)
    {
        setVisibility(GONE);
        mCurrentIndicatePosition = RecyclerView.NO_POSITION;
        return;
    }
    setVisibility(VISIBLE);

    if (firstCompleteVisibleP == RecyclerView.NO_POSITION && firstVisibleP >= mFirstStickyPosition)
    {
        firstCompleteVisibleP = firstVisibleP;
    }
    //两个Section相顶效果
    if (mAdapter.isSectionLabelViewType(mAdapter.getItemViewType(firstCompleteVisibleP)))
    {
        int top = mLayoutManager.findViewByPosition(firstCompleteVisibleP).getTop();
        if (top >= 0 && top < mStickyHeight)
        {
            setY(top - mStickyHeight);
        } else
        {
            setY(0);
        }
    } else
    {
        setY(0);
    }

    if (scrollState == RecyclerView.SCROLL_STATE_IDLE || scrollState == RecyclerView.SCROLL_STATE_DRAGGING)
    {
        //停止或者手触摸拉动的情况
        updateStickyLayout(getLastSectionPosition(firstVisibleP));
    } else
    {
        //惯性滑动的情况
        if (firstVisibleP < mAdapterItemCount && firstCompleteVisibleP < mAdapterItemCount)
        {
            if (firstVisibleP > mCurrentIndicatePosition && firstVisibleP != RecyclerView.NO_POSITION
                    && mAdapter.isSectionLabelViewType(mAdapter.getItemViewType(firstVisibleP)))
            {
                updateStickyLayout(firstVisibleP);
            } else if (firstVisibleP < mCurrentIndicatePosition && firstCompleteVisibleP != RecyclerView.NO_POSITION
                    && mAdapter.isSectionLabelViewType(mAdapter.getItemViewType(firstCompleteVisibleP)))
            {
                updateStickyLayout(getLastStickyPosition(mCurrentIndicatePosition));
            }
        }
    }
}
 
/**
 * Checks whether we should select a View for swiping.
 */
private boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
  if (selected != null || action != MotionEvent.ACTION_MOVE) {
    return false;
  }
  if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
    return false;
  }
  final RecyclerView.ViewHolder vh = findSwipedView(motionEvent);
  if (vh == null) {
    return false;
  }

  final int movementFlags = callback.getAbsMovementFlags(recyclerView, vh);

  final int swipeFlags =
      (movementFlags & ACTION_MODE_SWIPE_MASK) >> (DIRECTION_FLAG_COUNT * ACTION_STATE_SWIPE);

  if (swipeFlags == 0) {
    return false;
  }

  // dX and dY are only set in allowed directions. We use custom x/y here instead of
  // updateDxDy to avoid swiping if user moves more in the other direction
  final float x = motionEvent.getX(pointerIndex);
  final float y = motionEvent.getY(pointerIndex);

  // Calculate the distance moved
  final float dx = x - initialTouchX;
  final float dy = y - initialTouchY;
  // swipe target is chose w/o applying flags so it does not really check if swiping in that
  // direction is allowed. This why here, we use dX dY to check slope value again.
  final float absDx = Math.abs(dx);
  final float absDy = Math.abs(dy);

  if (absDx < slop && absDy < slop) {
    return false;
  }
  if (absDx > absDy) {
    if (dx < 0 && (swipeFlags & LEFT) == 0) {
      return false;
    }
    if (dx > 0 && (swipeFlags & RIGHT) == 0) {
      return false;
    }
  } else {
    if (dy < 0 && (swipeFlags & UP) == 0) {
      return false;
    }
    if (dy > 0 && (swipeFlags & DOWN) == 0) {
      return false;
    }
  }
  dX = dY = 0f;
  activePointerId = motionEvent.getPointerId(0);
  select((SwipeOpenViewHolder) vh, ACTION_STATE_SWIPE);
  return true;
}
 
源代码17 项目: Carbon   文件: ItemTouchHelper.java
/**
 * Checks whether we should select a View for swiping.
 */
boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
    if (mSelected != null || action != MotionEvent.ACTION_MOVE
            || mActionState == ACTION_STATE_DRAG || !mCallback.isItemViewSwipeEnabled()) {
        return false;
    }
    if (mRecyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
        return false;
    }
    final ViewHolder vh = findSwipedView(motionEvent);
    if (vh == null) {
        return false;
    }
    final int movementFlags = mCallback.getAbsoluteMovementFlags(mRecyclerView, vh);
    final int swipeFlags = (movementFlags & ACTION_MODE_SWIPE_MASK)
            >> (DIRECTION_FLAG_COUNT * ACTION_STATE_SWIPE);
    if (swipeFlags == 0) {
        return false;
    }
    // mDx and mDy are only set in allowed directions. We use custom x/y here instead of
    // updateDxDy to avoid swiping if user moves more in the other direction
    final float x = motionEvent.getX(pointerIndex);
    final float y = motionEvent.getY(pointerIndex);
    // Calculate the distance moved
    final float dx = x - mInitialTouchX;
    final float dy = y - mInitialTouchY;
    // swipe target is chose w/o applying flags so it does not really check if swiping in that
    // direction is allowed. This why here, we use mDx mDy to check slope value again.
    final float absDx = Math.abs(dx);
    final float absDy = Math.abs(dy);
    if (absDx < mSlop && absDy < mSlop) {
        return false;
    }
    if (absDx > absDy) {
        if (dx < 0 && (swipeFlags & LEFT) == 0) {
            return false;
        }
        if (dx > 0 && (swipeFlags & RIGHT) == 0) {
            return false;
        }
    } else {
        if (dy < 0 && (swipeFlags & UP) == 0) {
            return false;
        }
        if (dy > 0 && (swipeFlags & DOWN) == 0) {
            return false;
        }
    }
    mDx = mDy = 0f;
    mActivePointerId = motionEvent.getPointerId(0);
    select(vh, ACTION_STATE_SWIPE);
    return true;
}
 
源代码18 项目: Hentoid   文件: ScrollPositionListener.java
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    if (!Preferences.isViewerSwipeToTurn() || !isScrollEnabled) {
        recyclerView.stopScroll();
        return;
    }

    LinearLayoutManager llm = (LinearLayoutManager) recyclerView.getLayoutManager();
    if (llm != null) {
        if (RecyclerView.SCROLL_STATE_DRAGGING == newState) {
            dragStartPositionX = recyclerView.computeHorizontalScrollOffset();
            dragStartPositionY = recyclerView.computeVerticalScrollOffset();
            isSettlingX = false;
            isSettlingY = false;
        } else if (RecyclerView.SCROLL_STATE_SETTLING == newState) {
            // If the settling position is different from the original position, ignore that scroll
            // (e.g. snapping back to the original position after a small scroll)
            if (recyclerView.computeHorizontalScrollOffset() != dragStartPositionX)
                isSettlingX = true;
            if (recyclerView.computeVerticalScrollOffset() != dragStartPositionY)
                isSettlingY = true;
        } else if (RecyclerView.SCROLL_STATE_IDLE == newState) {
            // Don't do anything if we're not on a boundary
            if (!(llm.findLastVisibleItemPosition() == llm.getItemCount() - 1 || 0 == llm.findFirstVisibleItemPosition()))
                return;

            if (recyclerView.computeHorizontalScrollOffset() == dragStartPositionX && !isSettlingX && llm.canScrollHorizontally()) {
                if (0 == dragStartPositionX && !llm.getReverseLayout())
                    onStartOutOfBoundScroll.run();
                else if (0 == dragStartPositionX) onEndOutOfBoundScroll.run();
                else if (llm.getReverseLayout()) onStartOutOfBoundScroll.run();
                else onEndOutOfBoundScroll.run();
            }
            if (recyclerView.computeVerticalScrollOffset() == dragStartPositionY && !isSettlingY && llm.canScrollVertically()) {
                if (0 == dragStartPositionY && !llm.getReverseLayout())
                    onStartOutOfBoundScroll.run();
                else if (0 == dragStartPositionY) onEndOutOfBoundScroll.run();
                else if (llm.getReverseLayout()) onStartOutOfBoundScroll.run();
                else onEndOutOfBoundScroll.run();
            }
        }
    }
}
 
源代码19 项目: MaterialDateTimePicker   文件: DayPickerView.java
/**
 * This moves to the specified time in the view. If the time is not already
 * in range it will move the list so that the first of the month containing
 * the time is at the top of the view. If the new time is already in view
 * the list will not be scrolled unless forceScroll is true. This time may
 * optionally be highlighted as selected as well.
 *
 * @param day         The day to move to
 * @param animate     Whether to scroll to the given time or just redraw at the
 *                    new location
 * @param setSelected Whether to set the given time as selected
 * @param forceScroll Whether to recenter even if the time is already
 *                    visible
 * @return Whether or not the view animated to the new location
 */
public boolean goTo(MonthAdapter.CalendarDay day, boolean animate, boolean setSelected, boolean forceScroll) {

    // Set the selected day
    if (setSelected) {
        mSelectedDay.set(day);
    }

    mTempDay.set(day);
    int minMonth = mController.getStartDate().get(Calendar.MONTH);
    final int position = (day.year - mController.getMinYear())
            * MonthAdapter.MONTHS_IN_YEAR + day.month - minMonth;

    View child;
    int i = 0;
    int top = 0;
    // Find a child that's completely in the view
    do {
        child = getChildAt(i++);
        if (child == null) {
            break;
        }
        top = child.getTop();
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "child at " + (i - 1) + " has top " + top);
        }
    } while (top < 0);

    // Compute the first and last position visible
    int selectedPosition = child != null ? getChildAdapterPosition(child) : 0;

    if (setSelected) {
        mAdapter.setSelectedDay(mSelectedDay);
    }

    if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "GoTo position " + position);
    }
    // Check if the selected day is now outside of our visible range
    // and if so scroll to the month that contains it
    if (position != selectedPosition || forceScroll) {
        setMonthDisplayed(mTempDay);
        mPreviousScrollState = RecyclerView.SCROLL_STATE_DRAGGING;
        if (animate) {
            smoothScrollToPosition(position);
            if (pageListener != null) pageListener.onPageChanged(position);
            return true;
        } else {
            postSetSelection(position);
        }
    } else if (setSelected) {
        setMonthDisplayed(mSelectedDay);
    }
    return false;
}