static int CalculateCenterItemIndex(int firstVisibleItemIndex, int lastVisibleItemIndex, LinearLayoutManager linearLayoutManager) { // This can happen if a layout pass has not happened yet if (firstVisibleItemIndex == -1) { return(firstVisibleItemIndex); } var keyValuePairs = new Dictionary <int, int>(); for (var i = firstVisibleItemIndex; i <= lastVisibleItemIndex; i++) { var view = linearLayoutManager.FindViewByPosition(i); var rect = new Rect(); view.GetLocalVisibleRect(rect); keyValuePairs[i] = rect.Height(); } var center = keyValuePairs.Values.Sum() / 2.0; foreach (var keyValuePair in keyValuePairs) { center -= keyValuePair.Value; if (center <= 0) { return(keyValuePair.Key); } } return(firstVisibleItemIndex); }
/** * Returns true iff the {@link RecyclerView} is scrolled to the * top of its content (i.e. its first item is completely visible). */ private static bool IsRvScrolledToTop(RecyclerView rv) { LinearLayoutManager lm = (LinearLayoutManager)rv.GetLayoutManager(); return(lm.FindFirstVisibleItemPosition() == 0 && lm.FindViewByPosition(0).Top == 0); }
public virtual int GetRowPositionOffset() { Android.Views.View child = mRowHeaderLayoutManager.FindViewByPosition(mRowHeaderLayoutManager.FindFirstVisibleItemPosition()); if (child != null) { return(child.Left); } return(0); }
public override void OnDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { base.OnDrawOver(c, parent, state); int itemCount = parent.GetAdapter().ItemCount; // center horizontally, calculate width and subtract half from center float totalLength = mIndicatorItemLength * itemCount; float paddingBetweenItems = Math.Max(0, itemCount - 1) * mIndicatorItemPadding; float indicatorTotalWidth = totalLength + paddingBetweenItems; float indicatorStartX = (parent.Width - indicatorTotalWidth) / 2F; float indicatorPosY = parent.Height - mIndicatorHeight / 2F; drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount); // find active page (which should be highlighted) LinearLayoutManager layoutManager = (LinearLayoutManager)parent.GetLayoutManager(); int activePosition = layoutManager.FindLastVisibleItemPosition(); if (activePosition == RecyclerView.NoPosition) { return; } // find offset of active page (if the user is scrolling) View activeChild = layoutManager.FindViewByPosition(activePosition); int left = activeChild.Left; int width = activeChild.Width; // on swipe the active item will be positioned from [-width, 0] // interpolate offset for smooth animation float progress = mInterpolator.GetInterpolation(left * -1 / (float)width); drawHighlights(c, indicatorStartX, indicatorPosY, activePosition, progress, itemCount); }
/// <summary> /// This method calculates the current scroll position and its offset to help new attached /// recyclerView on window at that position and offset /// </summary> /// <seealso cref="GetScrollPosition()"/> /// <seealso cref="GetScrollPositionOffset()"/> private void RenewScrollPosition(RecyclerView recyclerView) { LinearLayoutManager layoutManager = (LinearLayoutManager)recyclerView.GetLayoutManager(); mScrollPosition = layoutManager.FindFirstCompletelyVisibleItemPosition(); // That means there is no completely visible Position. if (mScrollPosition == -1) { mScrollPosition = layoutManager.FindFirstVisibleItemPosition(); // That means there is just a visible item on the screen if (mScrollPosition == layoutManager.FindLastVisibleItemPosition()) { } else { // in this case we use the position which is the last & first visible item. // That means there are 2 visible item on the screen. However, second one is not // completely visible. mScrollPosition = mScrollPosition + 1; } } mScrollPositionOffset = layoutManager.FindViewByPosition(mScrollPosition).Left; }
public override bool Fling(int velocityX, int velocityY) { if (ItemCount < 1) { return(true); } FlingEventArgs flingEventArgs; if (velocityX > 0) { flingEventArgs = new FlingEventArgs(FlingDirection.Right, CurrentItem); if (CurrentItem == ItemCount - 1) { return(true); } } else { flingEventArgs = new FlingEventArgs(FlingDirection.Left, CurrentItem); } if (BeforeFling != null) { BeforeFling(this, flingEventArgs); } LinearLayoutManager linearLayoutManager = (LinearLayoutManager)GetLayoutManager(); //these four variables identify the views you see on screen. int lastVisibleView = linearLayoutManager.FindLastVisibleItemPosition(); int firstVisibleView = linearLayoutManager.FindFirstVisibleItemPosition(); View firstView = linearLayoutManager.FindViewByPosition(firstVisibleView); View lastView = linearLayoutManager.FindViewByPosition(lastVisibleView); //these variables get the distance you need to scroll in order to center your views. //my views have variable sizes, so I need to calculate side margins separately. //note the subtle difference in how right and left margins are calculated, as well as //the resulting scroll distances. int leftMargin = (screenWidth - lastView.Width) / 2; int rightMargin = (screenWidth - firstView.Width) / 2 + firstView.Width; int leftEdge = lastView.Left; int rightEdge = firstView.Right; int scrollDistanceLeft = leftEdge - leftMargin; int scrollDistanceRight = rightMargin - rightEdge; //if(user swipes to the left) if (velocityX > 0) { CurrentItem = lastVisibleView - 1; SmoothScrollBy(scrollDistanceLeft, 0); } else { CurrentItem = firstVisibleView - 1; SmoothScrollBy(-scrollDistanceRight, 0); } if (OnFling != null) { OnFling(this, flingEventArgs); } return(true); }