protected override FlexibleViewViewHolder FindLastVisibleItemView() { int childCount = ChildCount; if (mShouldReverseLayout == false) { for (int i = childCount - 1; i >= 0; i--) { FlexibleViewViewHolder child = GetChildAt(i); int start = (int)mOrientationHelper.GetViewHolderStart(child); if (start > 0 && start < (int)mOrientationHelper.GetEnd()) { return(child); } } } else { for (int i = 0; i < childCount; i++) { FlexibleViewViewHolder child = GetChildAt(i); int start = (int)mOrientationHelper.GetViewHolderStart(child); if (start > 0 && start < (int)mOrientationHelper.GetEnd()) { return(child); } } } return(null); }
protected override FlexibleViewViewHolder FindFirstVisibleItemView() { int childCount = ChildCount; if (mShouldReverseLayout == false) { for (int i = 0; i < childCount; i++) { FlexibleViewViewHolder child = GetChildAt(i); int end = (int)orientationHelper.GetViewHolderEnd(child); if (end >= 0 && end < (int)orientationHelper.GetEnd()) { return(child); } } } else { for (int i = childCount - 1; i >= 0; i--) { FlexibleViewViewHolder child = GetChildAt(i); int end = (int)orientationHelper.GetViewHolderEnd(child); if (end >= 0 && end < (int)orientationHelper.GetEnd()) { return(child); } } } return(null); }
/** * Returns the scroll amount that brings the given rect in child's coordinate system within * the padded area of FlexibleViewRecyclerView. * @param parent The parent FlexibleViewRecyclerView. * @param child The direct child making the request. * @param rect The rectangle in the child's coordinates the child * wishes to be on the screen. * @param immediate True to forbid animated or delayed scrolling, * false otherwise * @return The array containing the scroll amount in x and y directions that brings the * given rect into RV's padded area. */ private Vector2 GetRectOfVisibleChildScrollAmount(FlexibleView parent, FlexibleViewViewHolder child) { Vector2 ret = new Vector2(0, 0); int parentLeft = PaddingLeft; int parentTop = PaddingTop; int parentRight = (int)Width - PaddingRight; int parentBottom = (int)Height - PaddingBottom; int childLeft = (int)child.Left; int childTop = (int)child.Top; int childRight = (int)child.Right; int childBottom = (int)child.Bottom; Extents offset = new Extents((ushort)Math.Min(0, childLeft - parentLeft), (ushort)Math.Max(0, childRight - parentRight), (ushort)Math.Min(0, childTop - parentTop), (ushort)Math.Max(0, childBottom - parentBottom)); int dx = offset.Start != 0 ? offset.Start : Math.Min(childLeft - parentLeft, offset.End); int dy = offset.Top != 0 ? offset.Top : Math.Min(childTop - parentTop, offset.Bottom); ret.X = -dx; ret.Y = -dy; return(ret); }
/** * Returns the scroll amount that brings the given rect in child's coordinate system within * the padded area of FlexibleViewRecyclerView. * @param parent The parent FlexibleViewRecyclerView. * @param child The direct child making the request. * @param rect The rectangle in the child's coordinates the child * wishes to be on the screen. * @param immediate True to forbid animated or delayed scrolling, * false otherwise * @return The array containing the scroll amount in x and y directions that brings the * given rect into RV's padded area. */ private Vector2 GetChildRectangleOnScreenScrollAmount(FlexibleView parent, FlexibleViewViewHolder child) { Vector2 ret = new Vector2(0, 0); int parentLeft = PaddingLeft; int parentTop = PaddingTop; int parentRight = (int)Width - PaddingRight; int parentBottom = (int)Height - PaddingBottom; int childLeft = (int)child.Left; int childTop = (int)child.Top; int childRight = (int)child.Right; int childBottom = (int)child.Bottom; int offScreenLeft = Math.Min(0, childLeft - parentLeft); int offScreenTop = Math.Min(0, childTop - parentTop); int offScreenRight = Math.Max(0, childRight - parentRight); int offScreenBottom = Math.Max(0, childBottom - parentBottom); // Favor the "start" layout direction over the end when bringing one side or the other // of a large rect into view. If we decide to bring in end because start is already // visible, limit the scroll such that start won't go out of bounds. int dx = offScreenLeft != 0 ? offScreenLeft : Math.Min(childLeft - parentLeft, offScreenRight); // Favor bringing the top into view over the bottom. If top is already visible and // we should scroll to make bottom visible, make sure top does not go out of bounds. int dy = offScreenTop != 0 ? offScreenTop : Math.Min(childTop - parentTop, offScreenBottom); ret.X = -dx; ret.Y = -dy; return(ret); }
private void Cache(FlexibleViewRecycler recycler, LayoutState layoutState, bool immediate, float scrolled = 0) { if (layoutState.LayoutDirection == LayoutState.LAYOUT_END) { // get the first child in the direction we are going FlexibleViewViewHolder child = GetChildClosestToEnd(); if (child != null) { if (child.ItemView.Focusable == false || orientationHelper.GetViewHolderEnd(child) + scrolled < orientationHelper.GetEnd()) { layoutState.Available = MAX_SCROLL_FACTOR * orientationHelper.GetTotalSpace(); layoutState.Extra = 0; layoutState.ScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN; layoutState.Recycle = false; Fill(recycler, layoutState, true, immediate); } } } else { FlexibleViewViewHolder child = GetChildClosestToStart(); if (child != null) { if (child.ItemView.Focusable == false || orientationHelper.GetViewHolderStart(child) + scrolled > 0) { layoutState.Available = MAX_SCROLL_FACTOR * orientationHelper.GetTotalSpace(); layoutState.Extra = 0; layoutState.ScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN; layoutState.Recycle = false; Fill(recycler, layoutState, true, immediate); } } } }
private void OffsetPositionRecordsForRemove(int positionStart, int itemCount, bool applyToPreLayout) { int positionEnd = positionStart + itemCount; int childCount = mChildHelper.GetChildCount(); for (int i = 0; i < childCount; i++) { FlexibleViewViewHolder holder = mChildHelper.GetChildAt(i); if (holder != null) { if (holder.AdapterPosition >= positionEnd) { holder.OffsetPosition(-itemCount, applyToPreLayout); } else if (holder.AdapterPosition >= positionStart) { holder.FlagRemovedAndOffsetPosition(positionStart - 1, -itemCount, applyToPreLayout); } } } if (positionEnd <= mFocusedItemIndex) { mFocusedItemIndex -= itemCount; } else if (positionStart <= mFocusedItemIndex) { mFocusedItemIndex = positionStart; if (mFocusedItemIndex >= mAdapter.GetItemCount()) { mFocusedItemIndex = mAdapter.GetItemCount() - 1; } } }
private void DispatchChildDestroyed(FlexibleViewViewHolder holder) { if (mAdapter != null && holder != null) { mAdapter.OnDestroyViewHolder(holder); } }
private void DispatchChildDetached(FlexibleViewViewHolder holder) { if (mAdapter != null && holder != null) { mAdapter.OnViewDetachedFromWindow(holder); } }
private void DispatchChildAttached(FlexibleViewViewHolder holder) { if (adapter != null && holder != null) { adapter.OnViewAttachedToWindow(holder); } }
private void DispatchItemClicked(FlexibleViewViewHolder clickedHolder) { FlexibleViewItemClickedEventArgs args = new FlexibleViewItemClickedEventArgs(); args.ClickedView = clickedHolder; OnClickEvent(this, args); }
internal override FlexibleViewViewHolder OnFocusSearchFailed(FlexibleViewViewHolder focused, FlexibleViewLayoutManager.Direction direction, FlexibleViewRecycler recycler) { if (ChildCount == 0) { return(null); } int layoutDir = ConvertFocusDirectionToLayoutDirection(direction); if (layoutDir == LayoutState.INVALID_LAYOUT) { return(null); } int maxScroll = (int)(MAX_SCROLL_FACTOR * orientationHelper.GetTotalSpace()); UpdateLayout(layoutDir, maxScroll, false); mLayoutState.ScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN; mLayoutState.Recycle = false; Fill(recycler, mLayoutState, true, true); FlexibleViewViewHolder nextFocus; if (layoutDir == LayoutState.LAYOUT_START) { nextFocus = GetChildAt(0); } else { nextFocus = GetChildAt(ChildCount - 1); } return(nextFocus); }
private FlexibleViewViewHolder FindLastCompleteVisibleItemView() { int childCount = ChildCount; if (mShouldReverseLayout == false) { for (int i = childCount - 1; i >= 0; i--) { FlexibleViewViewHolder child = GetChildAt(i); if ((int)orientationHelper.GetViewHolderEnd(child) < (int)orientationHelper.GetEnd()) { return(child); } } } else { for (int i = 0; i < childCount; i++) { FlexibleViewViewHolder child = GetChildAt(i); if ((int)orientationHelper.GetViewHolderEnd(child) < (int)orientationHelper.GetEnd()) { return(child); } } } return(null); }
public void RecycleChildren(FlexibleViewRecycler recycler, int startIndex, int endIndex, bool immediate) { if (startIndex == endIndex) { return; } if (endIndex > startIndex) { for (int i = startIndex; i < endIndex; i++) { FlexibleViewViewHolder v = mChildHelper.GetChildAt(i); if (v.PendingRecycle == false) { v.PendingRecycle = true; mPendingRecycleViews.Add(v); } } } else { for (int i = startIndex; i > endIndex; i--) { FlexibleViewViewHolder v = mChildHelper.GetChildAt(i); if (v.PendingRecycle == false) { v.PendingRecycle = true; mPendingRecycleViews.Add(v); } } } if (immediate == true) { RecycleChildrenInt(recycler); } }
private void OnScrollAnimationFinished(object sender, EventArgs e) { foreach (FlexibleViewViewHolder holder in mPendingRecycleViews) { holder.PendingRecycle = false; } mPendingRecycleViews.Clear(); int start = FlexibleView.NO_POSITION; FlexibleViewViewHolder firstItemView = FindFirstVisibleItemView(); if (firstItemView != null) { start = firstItemView.LayoutPosition; } else { start = 0; } int itemCount = ChildCount; int end = FlexibleView.NO_POSITION; FlexibleViewViewHolder lastItemView = FindLastVisibleItemView(); if (lastItemView != null) { end = lastItemView.LayoutPosition; } else { end = itemCount - 1; } List <FlexibleViewViewHolder> removedViewList = new List <FlexibleViewViewHolder>(); for (int i = 0; i < itemCount; i++) { FlexibleViewViewHolder v = GetChildAt(i); //if item view of holder is visible, it should not be recycled. if (v.LayoutPosition >= start && v.LayoutPosition <= end) { continue; } removedViewList.Add(v); } for (int i = 0; i < removedViewList.Count; i++) { FlexibleViewViewHolder v = removedViewList[i]; v.PendingRecycle = false; mFlexibleView.GetRecycler().RecycleView(v); mChildHelper.RemoveView(v); } // relayout }
internal virtual void LayoutChunk(FlexibleViewRecycler recycler, LayoutState layoutState, LayoutChunkResult result) { FlexibleViewViewHolder holder = layoutState.Next(recycler); if (holder == null) { // if we are laying out views in scrap, this may return null which means there is // no more items to layout. result.Finished = true; return; } if (mShouldReverseLayout == (layoutState.LayoutDirection == LayoutState.LAYOUT_START)) { AddView(holder); } else { AddView(holder, 0); } result.Consumed = orientationHelper.GetViewHolderMeasurement(holder); float left, top, width, height; if (Orientation == VERTICAL) { width = Width - PaddingLeft - PaddingRight; height = result.Consumed; left = PaddingLeft; if (layoutState.LayoutDirection == LayoutState.LAYOUT_END) { top = layoutState.Offset; } else { top = layoutState.Offset - height; } LayoutChild(holder, left, top, width, height); } else { width = result.Consumed; height = Height - PaddingTop - PaddingBottom; top = PaddingTop; if (layoutState.LayoutDirection == LayoutState.LAYOUT_END) { left = layoutState.Offset; } else { left = layoutState.Offset - width; } LayoutChild(holder, left, top, width, height); } result.Focusable = true; }
public bool RemoveView(FlexibleViewViewHolder holder) { mFlexibleView.Remove(holder.ItemView); mFlexibleView.DispatchChildDetached(holder); return(mViewList.Remove(holder)); }
public void AddView(FlexibleViewViewHolder holder, int index) { mFlexibleView.Add(holder.ItemView); mFlexibleView.DispatchChildAttached(holder); AttachView(holder, index); }
// Gets the view for the next element that we should layout. // Also updates current item index to the next item, based on {@link #mItemDirection} // // @return The next element that we should layout. public FlexibleViewViewHolder Next(FlexibleViewRecycler recycler) { FlexibleViewViewHolder itemView = recycler.GetViewForPosition(CurrentPosition); CurrentPosition += ItemDirection; return(itemView); }
private void DispatchItemTouched(FlexibleViewViewHolder touchedHolder, Touch touchEvent) { FlexibleViewItemTouchEventArgs args = new FlexibleViewItemTouchEventArgs(); args.TouchedView = touchedHolder; args.Touch = touchEvent; OnTouchEvent(this, args); }
public void RecycleView(FlexibleViewViewHolder itemView) { if (null == itemView) { return; } itemView.ScrapContainer = null; mRecyclerPool.PutRecycledView(itemView); }
public bool RemoveViewsRange(int index, int count) { for (int i = index; i < index + count; i++) { FlexibleViewViewHolder holder = mViewList[i]; mFlexibleView.Remove(holder.ItemView); } mViewList.RemoveRange(index, count); return(false); }
private void ClearOldPositions() { int childCount = mChildHelper.GetChildCount(); for (int i = 0; i < childCount; i++) { FlexibleViewViewHolder holder = mChildHelper.GetChildAt(i); holder.ClearOldPosition(); } }
public void RemoveAndRecycleViewAt(int index, FlexibleViewRecycler recycler) { if (null == recycler) { return; } FlexibleViewViewHolder v = mChildHelper.GetChildAt(index); mChildHelper.RemoveViewAt(index); recycler.RecycleView(v); }
private void RemoveAndRecycleScrapInt() { int scrapCount = mRecycler.GetScrapCount(); for (int i = 0; i < scrapCount; i++) { FlexibleViewViewHolder scrap = mRecycler.GetScrapViewAt(i); mChildHelper.RemoveView(scrap); mRecycler.RecycleView(scrap); } mRecycler.Clear(); }
private bool OnTouchEvent(object source, View.TouchEventArgs e) { View itemView = source as View; if (itemView != null && itemViewTable.ContainsKey(itemView.ID)) { FlexibleViewViewHolder holder = itemViewTable[itemView.ID]; mFlexibleView.DispatchItemTouched(holder, e.Touch); return(true); } return(false); }
public void LayoutChild(FlexibleViewViewHolder child, float left, float top, float width, float height) { if (null == child) { return; } View itemView = child.ItemView; itemView.SizeWidth = width - itemView.Margin.Start - itemView.Margin.End; itemView.SizeHeight = height - itemView.Margin.Top - itemView.Margin.Bottom; itemView.PositionX = left + itemView.Margin.Start; itemView.PositionY = top + itemView.Margin.Top; }
public override float ComputeScrollExtent() { FlexibleViewViewHolder startChild = FindFirstVisibleItemView(); FlexibleViewViewHolder endChild = FindLastVisibleItemView(); if (ChildCount == 0 || startChild == null || endChild == null) { return(0); } float extend = mOrientationHelper.GetViewHolderEnd(endChild) - mOrientationHelper.GetViewHolderStart(startChild); return(Math.Min(mOrientationHelper.GetTotalSpace(), extend)); }
public void PutRecycledView(FlexibleViewViewHolder view) { int viewType = view.ItemViewType; if (viewType >= mMaxTypeCount) { return; } if (mScrap[viewType] == null) { mScrap[viewType] = new List <FlexibleViewViewHolder>(); } view.IsBound = false; mScrap[viewType].Add(view); }
private void AddViewInternal(FlexibleViewViewHolder holder, int index, bool disappearing) { if (null == holder) { return; } if (holder.IsScrap()) { holder.Unscrap(); mChildHelper.AttachView(holder, index); } else { mChildHelper.AddView(holder, index); } }
public override float ComputeScrollRange() { FlexibleViewViewHolder startChild = FindFirstVisibleItemView(); FlexibleViewViewHolder endChild = FindLastVisibleItemView(); if (ChildCount == 0 || startChild == null || endChild == null) { return(0); } float laidOutArea = mOrientationHelper.GetViewHolderEnd(endChild) - mOrientationHelper.GetViewHolderStart(startChild); int laidOutRange = Math.Abs(startChild.LayoutPosition - endChild.LayoutPosition) + 1; // estimate a size for full list. return(laidOutArea / laidOutRange * ItemCount); }