2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using Tizen.NUI.BaseComponents;
6 namespace Tizen.NUI.Components
9 /// A FlexibleViewLayoutManager is responsible for measuring and positioning item views within a FlexibleView
10 /// as well as determining the policy for when to recycle item views that are no longer visible to the user.
12 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
13 [EditorBrowsable(EditorBrowsableState.Never)]
14 public abstract class FlexibleViewLayoutManager : Disposable
42 private readonly int SCROLL_ANIMATION_DURATION = 500;
44 private FlexibleView mFlexibleView;
45 private FlexibleView.ChildHelper mChildHelper;
47 private List<FlexibleViewViewHolder> mPendingRecycleViews = new List<FlexibleViewViewHolder>();
49 private Animation mScrollAni;
52 /// Layout all relevant child views from the given adapter.
54 /// <param name="recycler">Recycler to use for fetching potentially cached views for a position</param>
55 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
56 [EditorBrowsable(EditorBrowsableState.Never)]
57 public abstract void OnLayoutChildren(FlexibleViewRecycler recycler);
60 /// Called after a full layout calculation is finished.
62 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
63 [EditorBrowsable(EditorBrowsableState.Never)]
64 public virtual void OnLayoutCompleted()
69 /// Gets the current focus position in adapter.
71 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
72 [EditorBrowsable(EditorBrowsableState.Never)]
73 public int FocusPosition
77 return mFlexibleView.FocusedItemIndex;
82 /// Gets the datas count in data sets.
84 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
85 [EditorBrowsable(EditorBrowsableState.Never)]
90 FlexibleViewAdapter b = mFlexibleView != null ? mFlexibleView.GetAdapter() : null;
92 return b != null ? b.GetItemCount() : 0;
97 /// Query if horizontal scrolling is currently supported. The default implementation returns false.
99 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
100 [EditorBrowsable(EditorBrowsableState.Never)]
101 public virtual bool CanScrollHorizontally()
107 /// Query if vertical scrolling is currently supported. The default implementation returns false.
109 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
110 [EditorBrowsable(EditorBrowsableState.Never)]
111 public virtual bool CanScrollVertically()
117 /// Scroll horizontally by dy pixels in screen coordinates.
119 /// <param name="dy">distance to scroll in pixels. Y increases as scroll position approaches the top.</param>
120 /// <param name="recycler">Recycler to use for fetching potentially cached views for a position</param>
121 /// <param name="immediate">Specify if the scroll need animation</param>
122 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
123 [EditorBrowsable(EditorBrowsableState.Never)]
124 public virtual float ScrollHorizontallyBy(float dy, FlexibleViewRecycler recycler, bool immediate)
130 /// Scroll vertically by dy pixels in screen coordinates.
132 /// <param name="dy">distance to scroll in pixels. Y increases as scroll position approaches the top.</param>
133 /// <param name="recycler">Recycler to use for fetching potentially cached views for a position</param>
134 /// <param name="immediate">Specify if the scroll need animation</param>
135 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
136 [EditorBrowsable(EditorBrowsableState.Never)]
137 public virtual float ScrollVerticallyBy(float dy, FlexibleViewRecycler recycler, bool immediate)
143 /// Compute the extent of the scrollbar's thumb within the range.
145 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
146 [EditorBrowsable(EditorBrowsableState.Never)]
147 public virtual float ComputeScrollExtent()
153 /// Compute the offset of the scrollbar's thumb within the range.
155 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
156 [EditorBrowsable(EditorBrowsableState.Never)]
157 public virtual float ComputeScrollOffset()
163 /// Compute the range that the scrollbar represents.
165 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
166 [EditorBrowsable(EditorBrowsableState.Never)]
167 public virtual float ComputeScrollRange()
173 /// Scroll the FlexibleView to make the position visible.
175 /// <param name="position">Scroll to this adapter position</param>
176 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
177 [EditorBrowsable(EditorBrowsableState.Never)]
178 public virtual void ScrollToPosition(int position)
184 /// Scroll to the specified adapter position with the given offset from resolved layout start.
186 /// <param name="position">Scroll to this adapter position</param>
187 /// <param name="offset">The distance (in pixels) between the start edge of the item view and start edge of the FlexibleView.</param>
188 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
189 [EditorBrowsable(EditorBrowsableState.Never)]
190 public virtual void ScrollToPositionWithOffset(int position, int offset)
195 internal void MoveFocus(FlexibleViewLayoutManager.Direction direction, FlexibleViewRecycler recycler)
197 int prevFocusPosition = FocusPosition;
198 int nextFocusPosition = GetNextPosition(FocusPosition, direction);
199 if (nextFocusPosition == FlexibleView.NO_POSITION)
204 FlexibleViewViewHolder nextFocusChild = FindItemViewByPosition(nextFocusPosition);
205 if (nextFocusChild == null)
207 nextFocusChild = OnFocusSearchFailed(null, direction, recycler);
210 if (nextFocusChild != null)
212 RequestChildRectangleOnScreen(mFlexibleView, nextFocusChild, recycler, false);
214 ChangeFocus(nextFocusPosition);
219 * Requests that the given child of the FlexibleViewRecyclerView be positioned onto the screen. This
220 * method can be called for both unfocusable and focusable child views. For unfocusable
221 * child views, focusedChildVisible is typically true in which case, layout manager
222 * makes the child view visible only if the currently focused child stays in-bounds of RV.
223 * @param parent The parent FlexibleViewRecyclerView.
224 * @param child The direct child making the request.
225 * @param rect The rectangle in the child's coordinates the child
226 * wishes to be on the screen.
227 * @param immediate True to forbid animated or delayed scrolling,
229 * @param focusedChildVisible Whether the currently focused view must stay visible.
230 * @return Whether the group scrolled to handle the operation
232 internal bool RequestChildRectangleOnScreen(FlexibleView parent, FlexibleViewViewHolder child, FlexibleViewRecycler recycler, bool immediate)
234 Vector2 scrollAmount = GetChildRectangleOnScreenScrollAmount(parent, child);
235 float dx = scrollAmount[0];
236 float dy = scrollAmount[1];
237 if (dx != 0 || dy != 0)
239 if (dx != 0 && CanScrollHorizontally())
241 ScrollHorizontallyBy(dx, recycler, immediate);
243 else if (dy != 0 && CanScrollVertically())
245 ScrollVerticallyBy(dy, recycler, immediate);
253 /// Calls {@code FlexibleView#RelayoutRequest} on the underlying FlexibleView.
255 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
256 [EditorBrowsable(EditorBrowsableState.Never)]
257 public void RelayoutRequest()
259 if (mFlexibleView != null)
261 mFlexibleView.LayoutManagerRelayoutRequest();
266 /// Lay out the given child view within the FlexibleView using coordinates that include view margins.
268 /// <param name="child">Child to lay out</param>
269 /// <param name="left">Left edge, with item view left margin included</param>
270 /// <param name="top">Top edge, with item view top margin included</param>
271 /// <param name="width">Width, with item view left and right margin included</param>
272 /// <param name="height">Height, with item view top and bottom margin included</param>
273 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
274 [EditorBrowsable(EditorBrowsableState.Never)]
275 public void LayoutChild(FlexibleViewViewHolder child, float left, float top, float width, float height)
277 if (null == child) return;
278 View itemView = child.ItemView;
279 itemView.SizeWidth = width - itemView.Margin.Start - itemView.Margin.End;
280 itemView.SizeHeight = height - itemView.Margin.Top - itemView.Margin.Bottom;
281 itemView.PositionX = left + itemView.Margin.Start;
282 itemView.PositionY = top + itemView.Margin.Top;
286 /// Change the FlexibleViewViewHolder with focusPosition to focus.
288 /// <param name="focusPosition">the newly focus position</param>
289 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
290 [EditorBrowsable(EditorBrowsableState.Never)]
291 public void ChangeFocus(int focusPosition)
293 if (mFlexibleView != null)
295 mFlexibleView.DispatchFocusChanged(focusPosition);
300 /// Return the current number of child views attached to the parent FlexibleView.
302 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
303 [EditorBrowsable(EditorBrowsableState.Never)]
304 public int ChildCount
308 return mChildHelper != null ? mChildHelper.GetChildCount() : 0;
313 /// Return the child view at the given index.
315 /// <param name="index">child index</param>
316 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
317 [EditorBrowsable(EditorBrowsableState.Never)]
318 public FlexibleViewViewHolder GetChildAt(int index)
320 return mChildHelper != null ? mChildHelper.GetChildAt(index) : null;
324 /// Finds the view which represents the given adapter position.
326 /// <param name="position">adapter position</param>
327 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
328 [EditorBrowsable(EditorBrowsableState.Never)]
329 public FlexibleViewViewHolder FindItemViewByPosition(int position)
331 return mFlexibleView.FindViewHolderForLayoutPosition(position);
335 /// Offset all child views attached to the parent FlexibleView by dx pixels along the horizontal axis.
337 /// <param name="dx">Pixels to offset by </param>
338 /// <param name="immediate">specify if the offset need animation</param>
339 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
340 [EditorBrowsable(EditorBrowsableState.Never)]
341 public void OffsetChildrenHorizontal(float dx, bool immediate)
343 if (mChildHelper == null)
353 int childCount = mChildHelper.GetChildCount();
354 if (immediate == true)
356 for (int i = childCount - 1; i >= 0; i--)
358 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
359 v.ItemView.PositionX += dx;
364 if (mScrollAni == null)
366 mScrollAni = new Animation();
367 mScrollAni.Duration = SCROLL_ANIMATION_DURATION;
368 mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
371 // avoid out of boundary of flexibleview. delta value might be used for shadow.
372 // this must be done before animation clear.
375 FlexibleViewViewHolder vh = mChildHelper.GetChildAt(0);
376 if (vh.LayoutPosition == 0)
378 if ((int)(vh.Left + dx) > 0)
384 vh = mChildHelper.GetChildAt(childCount - 1);
385 if (vh.LayoutPosition == ItemCount - 1)
387 if ((int)(vh.Right + dx) < (int)Width + PaddingRight)
389 dx = Width + PaddingRight - vh.Right;
394 // save position before animation clear.
395 float[] childrenPositon = new float[childCount];
396 for (int i = childCount - 1; i >= 0; i--)
398 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
399 childrenPositon[i] = v.ItemView.PositionX;
403 mScrollAni.Finished += OnScrollAnimationFinished;
405 for (int i = childCount - 1; i >= 0; i--)
407 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
408 // set position again because position might be changed after animation clear.
409 v.ItemView.PositionX = childrenPositon[i];
410 mScrollAni.AnimateTo(v.ItemView, "PositionX", v.ItemView.PositionX + dx);
417 /// Offset all child views attached to the parent FlexibleView by dy pixels along the vertical axis.
419 /// <param name="dy">Pixels to offset by </param>
420 /// <param name="immediate">specify if the offset need animation</param>
421 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
422 [EditorBrowsable(EditorBrowsableState.Never)]
423 public void OffsetChildrenVertical(float dy, bool immediate)
425 if (mChildHelper == null)
435 int childCount = mChildHelper.GetChildCount();
436 if (immediate == true)
438 for (int i = childCount - 1; i >= 0; i--)
440 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
441 v.ItemView.PositionY += dy;
446 if (mScrollAni == null)
448 mScrollAni = new Animation();
449 mScrollAni.Duration = SCROLL_ANIMATION_DURATION;
450 mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
453 // avoid out of boundary of flexibleview. delta value might be used for shadow.
454 // this must be done before animation clear.
457 FlexibleViewViewHolder vh = mChildHelper.GetChildAt(0);
458 if (vh.LayoutPosition == 0)
460 if ((int)(vh.Top + dy) > 0)
466 vh = mChildHelper.GetChildAt(childCount - 1);
467 if (vh.LayoutPosition == ItemCount - 1)
469 if ((int)(vh.Bottom + dy) < (int)Height + PaddingBottom)
471 dy = Height + PaddingBottom - vh.Bottom;
476 // save position before animation clear.
477 float[] childPositon = new float[childCount];
478 for (int i = childCount - 1; i >= 0; i--)
480 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
481 childPositon[i] = v.ItemView.PositionY;
485 mScrollAni.Finished += OnScrollAnimationFinished;
487 for (int i = childCount - 1; i >= 0; i--)
489 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
490 // set position again because position might be changed after animation clear.
491 v.ItemView.PositionY = childPositon[i];
492 mScrollAni.AnimateTo(v.ItemView, "PositionY", v.ItemView.PositionY + dy);
499 /// Return the width of the parent FlexibleView.
501 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
502 [EditorBrowsable(EditorBrowsableState.Never)]
507 return mFlexibleView != null ? mFlexibleView.SizeWidth : 0;
512 /// Return the height of the parent FlexibleView.
514 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
515 [EditorBrowsable(EditorBrowsableState.Never)]
520 return mFlexibleView != null ? mFlexibleView.SizeHeight : 0;
525 /// Return the left padding of the parent FlexibleView.
527 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
528 [EditorBrowsable(EditorBrowsableState.Never)]
529 public int PaddingLeft
533 return mFlexibleView?.Padding?.Start ?? 0;
538 /// Return the top padding of the parent FlexibleView.
540 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
541 [EditorBrowsable(EditorBrowsableState.Never)]
542 public int PaddingTop
546 return mFlexibleView?.Padding?.Top ?? 0;
551 /// Return the right padding of the parent FlexibleView.
553 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
554 [EditorBrowsable(EditorBrowsableState.Never)]
555 public int PaddingRight
559 return mFlexibleView?.Padding?.End ?? 0;
564 /// Return the bottom padding of the parent FlexibleView.
566 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
567 [EditorBrowsable(EditorBrowsableState.Never)]
568 public int PaddingBottom
572 return mFlexibleView?.Padding?.Bottom ?? 0;
577 /// Add a view to the currently attached FlexibleView if needed.<br />
578 /// FlexibleViewLayoutManagers should use this method to add views obtained from a FlexibleViewRecycler using getViewForPosition(int).<br />
580 /// <param name="holder">view to add</param>
581 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
582 [EditorBrowsable(EditorBrowsableState.Never)]
583 public void AddView(FlexibleViewViewHolder holder)
589 /// Add a view to the currently attached FlexibleView if needed.<br />
590 /// FlexibleViewLayoutManagers should use this method to add views obtained from a FlexibleViewRecycler using getViewForPosition(int).<br />
592 /// <param name="holder">view to add</param>
593 /// <param name="index">index to add child at</param>
594 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
595 [EditorBrowsable(EditorBrowsableState.Never)]
596 public void AddView(FlexibleViewViewHolder holder, int index)
598 AddViewInternal(holder, index, false);
602 /// Temporarily detach and scrap all currently attached child views.
603 /// Views will be scrapped into the given FlexibleViewRecycler.
604 /// The FlexibleViewRecycler may prefer to reuse scrap views before other views that were previously recycled.
606 /// <param name="recycler">Recycler to scrap views into</param>
607 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
608 [EditorBrowsable(EditorBrowsableState.Never)]
609 public void ScrapAttachedViews(FlexibleViewRecycler recycler)
611 if (null == mChildHelper || null == recycler)
618 mChildHelper.ScrapViews(recycler);
622 * Remove a child view and recycle it using the given FlexibleViewRecycler.
624 * @param index Index of child to remove and recycle
625 * @param recycler FlexibleViewRecycler to use to recycle child
627 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
628 [EditorBrowsable(EditorBrowsableState.Never)]
629 public void RemoveAndRecycleViewAt(int index, FlexibleViewRecycler recycler)
631 if (null == recycler) return;
632 FlexibleViewViewHolder v = mChildHelper.GetChildAt(index);
633 mChildHelper.RemoveViewAt(index);
634 recycler.RecycleView(v);
638 /// ecycles children between given indices..
640 /// <param name="recycler">Recycler to recycle views into</param>
641 /// <param name="startIndex">inclusive</param>
642 /// <param name="endIndex">exclusive</param>
643 /// <param name="immediate">recycle immediately or add to pending list and recycle later.</param>
644 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
645 [EditorBrowsable(EditorBrowsableState.Never)]
646 public void RecycleChildren(FlexibleViewRecycler recycler, int startIndex, int endIndex, bool immediate)
648 if (startIndex == endIndex)
652 if (endIndex > startIndex)
654 for (int i = startIndex; i < endIndex; i++)
656 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
657 if (v.PendingRecycle == false)
659 v.PendingRecycle = true;
660 mPendingRecycleViews.Add(v);
666 for (int i = startIndex; i > endIndex; i--)
668 FlexibleViewViewHolder v = mChildHelper.GetChildAt(i);
669 if (v.PendingRecycle == false)
671 v.PendingRecycle = true;
672 mPendingRecycleViews.Add(v);
676 if (immediate == true)
678 RecycleChildrenInt(recycler);
683 /// Retrieves a position that neighbor to current position by direction.
685 /// <param name="position">The anchor adapter position</param>
686 /// <param name="direction">The direction.</param>
687 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
688 [EditorBrowsable(EditorBrowsableState.Never)]
689 protected abstract int GetNextPosition(int position, FlexibleViewLayoutManager.Direction direction);
692 /// Retrieves the first visible item view.
694 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
695 [EditorBrowsable(EditorBrowsableState.Never)]
696 protected virtual FlexibleViewViewHolder FindFirstVisibleItemView()
702 /// Retrieves the last visible item view.
704 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
705 [EditorBrowsable(EditorBrowsableState.Never)]
706 protected virtual FlexibleViewViewHolder FindLastVisibleItemView()
712 /// Dispose FlexibleView and all children on it.
714 /// <param name="type">Dispose type.</param>
715 [EditorBrowsable(EditorBrowsableState.Never)]
716 protected override void Dispose(DisposeTypes type)
723 if (type == DisposeTypes.Explicit)
725 mScrollAni?.Dispose();
731 internal virtual FlexibleViewViewHolder OnFocusSearchFailed(FlexibleViewViewHolder focused, FlexibleViewLayoutManager.Direction direction, FlexibleViewRecycler recycler)
736 internal void SetRecyclerView(FlexibleView recyclerView)
738 mFlexibleView = recyclerView;
739 mChildHelper = recyclerView.GetChildHelper();
742 internal void StopScroll(bool doSomethingAfterAnimationStopped)
744 if (mScrollAni != null && mScrollAni.State == Animation.States.Playing)
746 mScrollAni.Finished -= OnScrollAnimationFinished;
749 if (doSomethingAfterAnimationStopped)
751 OnScrollAnimationFinished(mScrollAni, null);
757 * Returns the scroll amount that brings the given rect in child's coordinate system within
758 * the padded area of FlexibleViewRecyclerView.
759 * @param parent The parent FlexibleViewRecyclerView.
760 * @param child The direct child making the request.
761 * @param rect The rectangle in the child's coordinates the child
762 * wishes to be on the screen.
763 * @param immediate True to forbid animated or delayed scrolling,
765 * @return The array containing the scroll amount in x and y directions that brings the
766 * given rect into RV's padded area.
768 private Vector2 GetChildRectangleOnScreenScrollAmount(FlexibleView parent, FlexibleViewViewHolder child)
770 Vector2 ret = new Vector2(0, 0);
771 int parentLeft = PaddingLeft;
772 int parentTop = PaddingTop;
773 int parentRight = (int)Width - PaddingRight;
774 int parentBottom = (int)Height - PaddingBottom;
775 int childLeft = (int)child.Left;
776 int childTop = (int)child.Top;
777 int childRight = (int)child.Right;
778 int childBottom = (int)child.Bottom;
780 int offScreenLeft = Math.Min(0, childLeft - parentLeft);
781 int offScreenTop = Math.Min(0, childTop - parentTop);
782 int offScreenRight = Math.Max(0, childRight - parentRight);
783 int offScreenBottom = Math.Max(0, childBottom - parentBottom);
785 // Favor the "start" layout direction over the end when bringing one side or the other
786 // of a large rect into view. If we decide to bring in end because start is already
787 // visible, limit the scroll such that start won't go out of bounds.
788 int dx = offScreenLeft != 0 ? offScreenLeft
789 : Math.Min(childLeft - parentLeft, offScreenRight);
791 // Favor bringing the top into view over the bottom. If top is already visible and
792 // we should scroll to make bottom visible, make sure top does not go out of bounds.
793 int dy = offScreenTop != 0 ? offScreenTop
794 : Math.Min(childTop - parentTop, offScreenBottom);
802 private void OnScrollAnimationFinished(object sender, EventArgs e)
804 foreach (FlexibleViewViewHolder holder in mPendingRecycleViews)
806 holder.PendingRecycle = false;
808 mPendingRecycleViews.Clear();
810 int start = FlexibleView.NO_POSITION;
811 FlexibleViewViewHolder firstItemView = FindFirstVisibleItemView();
812 if (firstItemView != null)
813 start = firstItemView.LayoutPosition;
817 int itemCount = ChildCount;
819 int end = FlexibleView.NO_POSITION;
820 FlexibleViewViewHolder lastItemView = FindLastVisibleItemView();
821 if (lastItemView != null)
822 end = lastItemView.LayoutPosition;
826 List<FlexibleViewViewHolder> removedViewList = new List<FlexibleViewViewHolder>();
827 for (int i = 0; i < itemCount; i++)
829 FlexibleViewViewHolder v = GetChildAt(i);
831 //if item view of holder is visible, it should not be recycled.
832 if (v.LayoutPosition >= start && v.LayoutPosition <= end)
835 removedViewList.Add(v);
838 for (int i = 0; i < removedViewList.Count; i++)
840 FlexibleViewViewHolder v = removedViewList[i];
841 v.PendingRecycle = false;
842 mFlexibleView.GetRecycler().RecycleView(v);
843 mChildHelper.RemoveView(v);
849 private void AddViewInternal(FlexibleViewViewHolder holder, int index, bool disappearing)
851 if (null == holder) return;
852 if (holder.IsScrap())
855 mChildHelper.AttachView(holder, index);
859 mChildHelper.AddView(holder, index);
863 private void RecycleChildrenInt(FlexibleViewRecycler recycler)
865 if (null == recycler) return;
866 foreach (FlexibleViewViewHolder holder in mPendingRecycleViews)
868 holder.PendingRecycle = false;
869 recycler.RecycleView(holder);
870 mChildHelper.RemoveView(holder);
872 mPendingRecycleViews.Clear();
875 private void ScrapOrRecycleView(FlexibleViewRecycler recycler, FlexibleViewViewHolder itemView)
877 recycler.ScrapView(itemView);