2 * Copyright(c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.ComponentModel;
19 using System.Collections.Generic;
20 using Tizen.NUI.BaseComponents;
22 namespace Tizen.NUI.CommonUI
25 /// A flexible view for providing a limited window into a large data set.
27 /// <since_tizen> 6 </since_tizen>
28 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
29 [EditorBrowsable(EditorBrowsableState.Never)]
30 public class FlexibleView : Control
33 /// Constant value: -1.
35 /// <since_tizen> 6 </since_tizen>
36 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
37 [EditorBrowsable(EditorBrowsableState.Never)]
38 public static readonly int NO_POSITION = -1;
40 /// Constant value: -1.
42 /// <since_tizen> 6 </since_tizen>
43 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
44 [EditorBrowsable(EditorBrowsableState.Never)]
45 public static readonly int INVALID_TYPE = -1;
47 private Adapter mAdapter;
48 private LayoutManager mLayout;
49 private Recycler mRecycler;
50 private RecycledViewPool mRecyclerPool;
51 private ChildHelper mChildHelper;
53 private PanGestureDetector mPanGestureDetector;
55 private int mFocusedItemIndex = NO_POSITION;
57 private AdapterHelper mAdapteHelper;
59 private ScrollBar mScrollBar = null;
60 private Timer mScrollBarShowTimer = null;
62 private EventHandler<ItemClickEventArgs> clickEventHandlers;
63 private EventHandler<ItemTouchEventArgs> touchEventHandlers;
64 private EventHandler<NUI.StyleManager.StyleChangedEventArgs> styleChangedEventHandlers;
67 /// Creates a FlexibleView instance.
69 /// <since_tizen> 6 </since_tizen>
70 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
71 [EditorBrowsable(EditorBrowsableState.Never)]
74 mRecyclerPool = new RecycledViewPool(this);
76 mRecycler = new Recycler(this);
77 mRecycler.SetRecycledViewPool(mRecyclerPool);
79 mChildHelper = new ChildHelper(this);
81 mPanGestureDetector = new PanGestureDetector();
82 mPanGestureDetector.Attach(this);
83 mPanGestureDetector.Detected += OnPanGestureDetected;
85 mAdapteHelper = new AdapterHelper(this);
87 ClippingMode = ClippingModeType.ClipToBoundingBox;
93 /// <since_tizen> 6 </since_tizen>
94 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
95 [EditorBrowsable(EditorBrowsableState.Never)]
96 public event EventHandler<ItemClickEventArgs> ItemClickEvent
100 clickEventHandlers += value;
105 clickEventHandlers -= value;
111 /// Item touch event.
113 /// <since_tizen> 6 </since_tizen>
114 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
115 [EditorBrowsable(EditorBrowsableState.Never)]
116 public event EventHandler<ItemTouchEventArgs> ItemTouchEvent
120 touchEventHandlers += value;
125 touchEventHandlers -= value;
130 /// Style changed, for example default font size.
132 /// <since_tizen> 6 </since_tizen>
133 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
134 [EditorBrowsable(EditorBrowsableState.Never)]
135 public event EventHandler<NUI.StyleManager.StyleChangedEventArgs> StyleChanged
139 styleChangedEventHandlers += value;
144 styleChangedEventHandlers -= value;
149 /// overwrite the Padding.
151 /// <since_tizen> 6 </since_tizen>
152 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
153 [EditorBrowsable(EditorBrowsableState.Never)]
154 public new Extents Padding
161 /// Gets or sets the focused item index(adapter position).
163 /// <since_tizen> 6 </since_tizen>
164 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
165 [EditorBrowsable(EditorBrowsableState.Never)]
166 public int FocusedItemIndex
170 return mFocusedItemIndex;
174 if (value == mFocusedItemIndex)
179 if (mAdapter == null)
189 ViewHolder nextFocusView = FindViewHolderForAdapterPosition(value);
190 if (nextFocusView == null)
192 mLayout.ScrollToPosition(value);
196 mLayout.RequestChildRectangleOnScreen(this, nextFocusView, mRecycler, true);
197 DispatchFocusChanged(value);
203 /// Set a new adapter to provide child views on demand.
205 /// <since_tizen> 6 </since_tizen>
206 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
207 [EditorBrowsable(EditorBrowsableState.Never)]
208 public void SetAdapter(Adapter adapter)
216 mAdapter.ItemEvent += OnItemEvent;
220 /// Retrieves the previously set adapter or null if no adapter is set.
222 /// <since_tizen> 6 </since_tizen>
223 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
224 [EditorBrowsable(EditorBrowsableState.Never)]
225 public Adapter GetAdapter()
231 /// Set the FlexibleView.LayoutManager that this FlexibleView will use.
233 /// <since_tizen> 6 </since_tizen>
234 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
235 [EditorBrowsable(EditorBrowsableState.Never)]
236 public void SetLayoutManager(LayoutManager layoutManager)
238 mLayout = layoutManager;
240 mLayout.SetRecyclerView(this);
242 if (mLayout.CanScrollHorizontally())
244 mPanGestureDetector.AddDirection(PanGestureDetector.DirectionHorizontal);
246 else if (mLayout.CanScrollVertically())
248 mPanGestureDetector.AddDirection(PanGestureDetector.DirectionVertical);
253 /// Return the FlexibleView.LayoutManager currently responsible for layout policy for this FlexibleView.
255 /// <since_tizen> 6 </since_tizen>
256 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
257 [EditorBrowsable(EditorBrowsableState.Never)]
258 public LayoutManager GetLayoutManager()
265 /// Convenience method to scroll to a certain position
267 /// <param name="position">Adapter position</param>
268 /// <param name="offset">The distance (in pixels) between the start edge of the item view and start edge of the FlexibleView.</param>
269 /// <since_tizen> 6 </since_tizen>
270 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
271 [EditorBrowsable(EditorBrowsableState.Never)]
272 public void ScrollToPositionWithOffset(int position, int offset)
274 mLayout.ScrollToPositionWithOffset(position, offset);
278 /// Move focus by direction.
280 /// <param name="direction">Direction. Should be "Left", "Right", "Up" or "Down" </param>
281 /// <since_tizen> 6 </since_tizen>
282 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
283 [EditorBrowsable(EditorBrowsableState.Never)]
284 public void MoveFocus(FlexibleView.LayoutManager.Direction direction)
286 mLayout.MoveFocus(direction, mRecycler);
290 /// Attach a scrollbar to this FlexibleView.
292 /// <param name="scrollBar">ScrollBar</param>
293 /// <since_tizen> 6 </since_tizen>
294 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
295 [EditorBrowsable(EditorBrowsableState.Never)]
296 public void AttachScrollBar(ScrollBar scrollBar)
298 if (scrollBar == null)
302 mScrollBar = scrollBar;
307 /// Detach the scrollbar from this FlexibleView.
309 /// <since_tizen> 6 </since_tizen>
310 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
311 [EditorBrowsable(EditorBrowsableState.Never)]
312 public void DetachScrollBar()
314 if (mScrollBar == null)
323 /// Return the ViewHolder for the item in the given position of the data set as of the latest layout pass.
324 /// This method checks only the children of RecyclerView. If the item at the given position is not laid out, it will not create a new one.
326 /// <param name="position">The position of the item in the data set of the adapter</param>
327 /// <since_tizen> 6 </since_tizen>
328 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
329 [EditorBrowsable(EditorBrowsableState.Never)]
330 public ViewHolder FindViewHolderForLayoutPosition(int position)
332 int childCount = mChildHelper.GetChildCount();
333 for (int i = 0; i < childCount; i++)
335 if (mChildHelper.GetChildAt(i) is ViewHolder holder)
337 if (holder.LayoutPosition == position)
348 /// Return the ViewHolder for the item in the given position of the data set.
349 /// This method checks only the children of RecyclerView. If the item at the given position is not laid out, it will not create a new one.
351 /// <param name="position">The position of the item in the data set of the adapter</param>
352 /// <since_tizen> 6 </since_tizen>
353 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
354 [EditorBrowsable(EditorBrowsableState.Never)]
355 public ViewHolder FindViewHolderForAdapterPosition(int position)
357 int childCount = mChildHelper.GetChildCount();
358 for (int i = 0; i < childCount; i++)
360 if (mChildHelper.GetChildAt(i) is ViewHolder holder)
362 if (holder.AdapterPosition == position)
373 /// Return the recycler instance.
375 /// <since_tizen> 6 </since_tizen>
376 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
377 [EditorBrowsable(EditorBrowsableState.Never)]
378 public Recycler GetRecycler()
384 /// you can override it to clean-up your own resources.
386 /// <param name="type">DisposeTypes</param>
387 /// <since_tizen> 6 </since_tizen>
388 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
389 [EditorBrowsable(EditorBrowsableState.Never)]
390 protected override void Dispose(DisposeTypes type)
397 if (type == DisposeTypes.Explicit)
399 mLayout.StopScroll();
401 if (mAdapter != null)
403 mAdapter.ItemEvent -= OnItemEvent;
406 if (mPanGestureDetector != null)
408 mPanGestureDetector.Detected -= OnPanGestureDetected;
409 mPanGestureDetector.Dispose();
410 mPanGestureDetector = null;
413 if (mScrollBarShowTimer != null)
415 mScrollBarShowTimer.Tick -= OnShowTimerTick;
416 mScrollBarShowTimer.Stop();
417 mScrollBarShowTimer.Dispose();
418 mScrollBarShowTimer = null;
421 if (mRecyclerPool != null)
423 mRecyclerPool.Clear();
424 mRecyclerPool = null;
427 if (mChildHelper != null)
429 mChildHelper.Clear();
437 /// you can override it to create your own default attributes.
439 /// <since_tizen> 6 </since_tizen>
440 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
441 [EditorBrowsable(EditorBrowsableState.Never)]
442 protected override Attributes GetAttributes()
448 /// you can override it to relayout elements.
450 /// <since_tizen> 6 </since_tizen>
451 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
452 [EditorBrowsable(EditorBrowsableState.Never)]
453 public override void OnRelayout(Vector2 size, RelayoutContainer container)
455 if (mAdapter == null)
465 DispatchLayoutStep1();
467 mLayout.OnLayoutChildren(mRecycler);
469 RemoveAndRecycleScrapInt();
473 /// you can override it to do something for style change.
475 /// <since_tizen> 6 </since_tizen>
476 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
477 [EditorBrowsable(EditorBrowsableState.Never)]
478 public override void OnStyleChange(NUI.StyleManager styleManager, StyleChangeType change)
480 if (change == StyleChangeType.DefaultFontSizeChange)
482 NUI.StyleManager.StyleChangedEventArgs args = new NUI.StyleManager.StyleChangedEventArgs();
483 args.StyleManager = styleManager;
484 args.StyleChange = change;
486 styleChangedEventHandlers?.Invoke(this, args);
492 private void DispatchLayoutStep1()
494 ProcessAdapterUpdates();
499 private void ProcessAdapterUpdates()
501 mAdapteHelper.PreProcess();
504 private void OffsetPositionRecordsForInsert(int positionStart, int itemCount)
506 int childCount = mChildHelper.GetChildCount();
507 for (int i = 0; i < childCount; i++)
509 ViewHolder holder = mChildHelper.GetChildAt(i);
510 if (holder != null && holder.AdapterPosition >= positionStart)
512 holder.OffsetPosition(itemCount, false);
516 if (positionStart <= mFocusedItemIndex)
518 mFocusedItemIndex += itemCount;
522 private void OffsetPositionRecordsForRemove(int positionStart, int itemCount, bool applyToPreLayout)
524 int positionEnd = positionStart + itemCount;
525 int childCount = mChildHelper.GetChildCount();
526 for (int i = 0; i < childCount; i++)
528 ViewHolder holder = mChildHelper.GetChildAt(i);
531 if (holder.AdapterPosition >= positionEnd)
533 holder.OffsetPosition(-itemCount, applyToPreLayout);
535 else if (holder.AdapterPosition >= positionStart)
537 holder.FlagRemovedAndOffsetPosition(positionStart - 1, -itemCount, applyToPreLayout);
542 if (positionEnd <= mFocusedItemIndex)
544 mFocusedItemIndex -= itemCount;
546 else if (positionStart <= mFocusedItemIndex)
548 mFocusedItemIndex = positionStart;
549 if (mFocusedItemIndex >= mAdapter.GetItemCount())
551 mFocusedItemIndex = mAdapter.GetItemCount() - 1;
556 private void SaveOldPositions()
558 int childCount = mChildHelper.GetChildCount();
559 for (int i = 0; i < childCount; i++)
561 ViewHolder holder = mChildHelper.GetChildAt(i);
562 holder.SaveOldPosition();
566 private void ClearOldPositions()
568 int childCount = mChildHelper.GetChildCount();
569 for (int i = 0; i < childCount; i++)
571 ViewHolder holder = mChildHelper.GetChildAt(i);
572 holder.ClearOldPosition();
576 private void RemoveAndRecycleScrapInt()
578 int scrapCount = mRecycler.GetScrapCount();
579 for (int i = 0; i < scrapCount; i++)
581 ViewHolder scrap = mRecycler.GetScrapViewAt(i);
582 mChildHelper.RemoveView(scrap);
583 mRecycler.RecycleView(scrap);
588 private void ShowScrollBar(uint millisecond = 700, bool flagAni = false)
590 if (mScrollBar == null || mLayout == null)
595 float extent = mLayout.ComputeScrollExtent();
596 float range = mLayout.ComputeScrollRange();
601 float offset = mLayout.ComputeScrollOffset();
603 float size = mScrollBar.Direction == ScrollBar.DirectionType.Vertical ? mScrollBar.SizeHeight : mScrollBar.SizeWidth;
604 float thickness = mScrollBar.Direction == ScrollBar.DirectionType.Vertical ? mScrollBar.SizeWidth : mScrollBar.SizeHeight;
605 float length = (float)Math.Round(size * extent / range);
607 // avoid the tiny thumb
608 float minLength = thickness * 2;
609 if (length < minLength)
613 // avoid the too-big thumb
614 if (offset > range - extent)
616 offset = range - extent;
618 if (mScrollBar.Direction == ScrollBar.DirectionType.Vertical)
620 mScrollBar.ThumbSize = new Size2D((int)thickness, (int)length);
624 mScrollBar.ThumbSize = new Size2D((int)length, (int)thickness);
626 mScrollBar.MinValue = 0;
627 mScrollBar.MaxValue = (int)(range - extent);
628 mScrollBar.SetCurrentValue((int)offset, flagAni);
630 if (mScrollBarShowTimer == null)
632 mScrollBarShowTimer = new Timer(millisecond);
633 mScrollBarShowTimer.Tick += OnShowTimerTick;
637 mScrollBarShowTimer.Interval = millisecond;
639 mScrollBarShowTimer.Start();
642 private bool OnShowTimerTick(object source, EventArgs e)
644 if (mScrollBar != null)
652 private void DispatchFocusChanged(int nextFocusPosition)
654 mAdapter.OnFocusChange(this, mFocusedItemIndex, nextFocusPosition);
656 mFocusedItemIndex = nextFocusPosition;
661 private void DispatchChildAttached(ViewHolder holder)
663 if (mAdapter != null && holder != null)
665 mAdapter.OnViewAttachedToWindow(holder);
669 private void DispatchChildDetached(ViewHolder holder)
671 if (mAdapter != null && holder != null)
673 mAdapter.OnViewDetachedFromWindow(holder);
677 private void DispatchChildDestroyed(ViewHolder holder)
679 if (mAdapter != null && holder != null)
681 mAdapter.OnDestroyViewHolder(holder);
685 private void DispatchItemClicked(ViewHolder clickedHolder)
687 ItemClickEventArgs args = new ItemClickEventArgs();
688 args.ClickedView = clickedHolder;
689 OnClickEvent(this, args);
692 private void DispatchItemTouched(ViewHolder touchedHolder, Touch touchEvent)
694 ItemTouchEventArgs args = new ItemTouchEventArgs();
695 args.TouchedView = touchedHolder;
696 args.Touch = touchEvent;
697 OnTouchEvent(this, args);
700 private void OnPanGestureDetected(object source, PanGestureDetector.DetectedEventArgs e)
702 if (e.PanGesture.State == Gesture.StateType.Started)
704 mLayout.StopScroll();
706 else if (e.PanGesture.State == Gesture.StateType.Continuing)
708 if (mLayout.CanScrollVertically())
710 mLayout.ScrollVerticallyBy(e.PanGesture.Displacement.Y, mRecycler, true);
712 else if (mLayout.CanScrollHorizontally())
714 mLayout.ScrollHorizontallyBy(e.PanGesture.Displacement.X, mRecycler, true);
719 else if (e.PanGesture.State == Gesture.StateType.Finished)
721 if (mLayout.CanScrollVertically())
723 mLayout.ScrollVerticallyBy(e.PanGesture.Velocity.Y * 600, mRecycler, false);
725 else if (mLayout.CanScrollHorizontally())
727 mLayout.ScrollHorizontallyBy(e.PanGesture.Velocity.X * 600, mRecycler, false);
729 ShowScrollBar(1200, true);
734 private void OnItemEvent(object sender, Adapter.ItemEventArgs e)
738 case Adapter.ItemEventType.Insert:
739 mAdapteHelper.OnItemRangeInserted(e.param[0], e.param[1]);
742 case Adapter.ItemEventType.Remove:
743 mAdapteHelper.OnItemRangeRemoved(e.param[0], e.param[1]);
746 case Adapter.ItemEventType.Move:
748 case Adapter.ItemEventType.Change:
757 private void OnClickEvent(object sender, ItemClickEventArgs e)
759 clickEventHandlers?.Invoke(sender, e);
762 private void OnTouchEvent(object sender, ItemTouchEventArgs e)
764 touchEventHandlers?.Invoke(sender, e);
768 /// ItemClick Event Arguments.
770 /// <since_tizen> 6 </since_tizen>
771 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
772 [EditorBrowsable(EditorBrowsableState.Never)]
773 public class ItemClickEventArgs : EventArgs
776 /// The clicked ViewHolder.
778 /// <since_tizen> 6 </since_tizen>
779 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
780 [EditorBrowsable(EditorBrowsableState.Never)]
781 public ViewHolder ClickedView;
785 /// ItemTouch Event Arguments.
787 /// <since_tizen> 6 </since_tizen>
788 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
789 [EditorBrowsable(EditorBrowsableState.Never)]
790 public class ItemTouchEventArgs : TouchEventArgs
793 /// The touched ViewHolder.
795 /// <since_tizen> 6 </since_tizen>
796 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
797 [EditorBrowsable(EditorBrowsableState.Never)]
798 public ViewHolder TouchedView;
802 /// Adapters provide a binding from an app-specific data set to views that are displayed within a FlexibleView.
804 /// <since_tizen> 6 </since_tizen>
805 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
806 [EditorBrowsable(EditorBrowsableState.Never)]
807 public abstract class Adapter
809 private EventHandler<ItemEventArgs> itemEventHandlers;
811 internal event EventHandler<ItemEventArgs> ItemEvent
815 itemEventHandlers += value;
820 itemEventHandlers -= value;
824 internal enum ItemEventType
833 /// Called when FlexibleView needs a new FlexibleView.ViewHolder of the given type to represent an item.
835 /// <param name="viewType">The view type of the new View</param>
836 /// <since_tizen> 6 </since_tizen>
837 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
838 [EditorBrowsable(EditorBrowsableState.Never)]
839 public abstract ViewHolder OnCreateViewHolder(int viewType);
842 /// Called by FlexibleView to display the data at the specified position.
844 /// <param name="holder">The ViewHolder which should be updated to represent the contents of the item at the given position in the data set.</param>
845 /// <param name="position">The position of the item within the adapter's data set.</param>
846 /// <since_tizen> 6 </since_tizen>
847 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
848 [EditorBrowsable(EditorBrowsableState.Never)]
849 public abstract void OnBindViewHolder(ViewHolder holder, int position);
852 /// Called when a ViewHolder is never used.
854 /// <param name="holder">The ViewHolder which need to be disposed</param>
855 /// <since_tizen> 6 </since_tizen>
856 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
857 [EditorBrowsable(EditorBrowsableState.Never)]
858 public abstract void OnDestroyViewHolder(ViewHolder holder);
861 /// Returns the total number of items in the data set held by the adapter.
863 /// <since_tizen> 6 </since_tizen>
864 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
865 [EditorBrowsable(EditorBrowsableState.Never)]
866 public abstract int GetItemCount();
869 /// Return the view type of the item at position for the purposes of view recycling.
871 /// <param name="position">The position of the item within the adapter's data set.</param>
872 /// <since_tizen> 6 </since_tizen>
873 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
874 [EditorBrowsable(EditorBrowsableState.Never)]
875 public virtual int GetItemViewType(int position)
881 /// Called by FlexibleView when it starts observing this Adapter.
882 /// Keep in mind that same adapter may be observed by multiple FlexibleView.
884 /// <param name="flexibleView">The FlexibleView instance which started observing this adapter.</param>
885 /// <since_tizen> 6 </since_tizen>
886 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
887 [EditorBrowsable(EditorBrowsableState.Never)]
888 public virtual void OnAttachedToRecyclerView(FlexibleView flexibleView)
893 /// Called by FlexibleView when it stops observing this Adapter.
895 /// <param name="flexibleView">The FlexibleView instance which stopped observing this adapter.</param>
896 /// <since_tizen> 6 </since_tizen>
897 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
898 [EditorBrowsable(EditorBrowsableState.Never)]
899 public virtual void OnDetachedFromRecyclerView(FlexibleView flexibleView)
904 /// Called when FlexibleView focus changed.
906 /// <param name="flexibleView">The FlexibleView into which the focus ViewHolder changed.</param>
907 /// <param name="previousFocus">The position of previous focus</param>
908 /// <param name="currentFocus">The position of current focus</param>
909 /// <since_tizen> 6 </since_tizen>
910 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
911 [EditorBrowsable(EditorBrowsableState.Never)]
912 public virtual void OnFocusChange(FlexibleView flexibleView, int previousFocus, int currentFocus)
917 /// Called when a view created by this adapter has been recycled.
918 /// If an item view has large or expensive data bound to it such as large bitmaps, this may be a good place to release those resources
920 /// <param name="holder">The ViewHolder will be recycled.</param>
921 /// <since_tizen> 6 </since_tizen>
922 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
923 [EditorBrowsable(EditorBrowsableState.Never)]
924 public virtual void OnViewRecycled(ViewHolder holder)
929 /// Called when a view created by this adapter has been attached to a window.
930 /// This can be used as a reasonable signal that the view is about to be seen by the user.
932 /// <param name="holder">Holder of the view being attached.</param>
933 /// <since_tizen> 6 </since_tizen>
934 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
935 [EditorBrowsable(EditorBrowsableState.Never)]
936 public virtual void OnViewAttachedToWindow(ViewHolder holder)
941 /// Called when a view created by this adapter has been detached from its window.
943 /// <param name="holder">Holder of the view being detached.</param>
944 /// <since_tizen> 6 </since_tizen>
945 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
946 [EditorBrowsable(EditorBrowsableState.Never)]
947 public virtual void OnViewDetachedFromWindow(ViewHolder holder)
952 /// Notify any registered observers that the data set has changed.
954 /// <since_tizen> 6 </since_tizen>
955 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
956 [EditorBrowsable(EditorBrowsableState.Never)]
957 public void NotifyDataSetChanged()
962 /// Notify any registered observers that the data set has changed.
963 /// It indicates that any reflection of the data at position is out of date and should be updated.
965 /// <param name="position">Position of the item that has changed</param>
966 /// <since_tizen> 6 </since_tizen>
967 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
968 [EditorBrowsable(EditorBrowsableState.Never)]
969 public void NotifyItemChanged(int position)
971 ItemEventArgs args = new ItemEventArgs
973 EventType = ItemEventType.Change,
975 args.param[0] = position;
977 OnItemEvent(this, args);
981 /// Notify any registered observers that the itemCount items starting at position positionStart have changed.
982 /// An optional payload can be passed to each changed item.
984 /// <param name="positionStart">Position of the first item that has changed</param>
985 /// <param name="itemCount">Number of items that have changed</param>
986 /// <since_tizen> 6 </since_tizen>
987 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
988 [EditorBrowsable(EditorBrowsableState.Never)]
989 public void NotifyItemRangeChanged(int positionStart, int itemCount)
994 /// Notify any registered observers that the data set has been newly inserted.
995 /// It indicates that any reflection of the data at position is out of date and should be updated.
997 /// <param name="position">Position of the item that has been newly inserted</param>
998 /// <since_tizen> 6 </since_tizen>
999 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1000 [EditorBrowsable(EditorBrowsableState.Never)]
1001 public void NotifyItemInserted(int position)
1003 NotifyItemRangeInserted(position, 1);
1007 /// Notify any registered observers that the itemCount items starting at position positionStart have been newly inserted.
1009 /// <param name="positionStart">Position of the first item that was inserted</param>
1010 /// <param name="itemCount">Number of items inserted</param>
1011 /// <since_tizen> 6 </since_tizen>
1012 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1013 [EditorBrowsable(EditorBrowsableState.Never)]
1014 public void NotifyItemRangeInserted(int positionStart, int itemCount)
1016 ItemEventArgs args = new ItemEventArgs
1018 EventType = ItemEventType.Insert,
1020 args.param[0] = positionStart;
1021 args.param[1] = itemCount;
1022 OnItemEvent(this, args);
1026 /// Notify any registered observers that the item previously located at position has been removed from the data set.
1028 /// <param name="position">Previous position of the first item that was removed</param>
1029 /// <since_tizen> 6 </since_tizen>
1030 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1031 [EditorBrowsable(EditorBrowsableState.Never)]
1032 public void NotifyItemRemoved(int position)
1034 NotifyItemRangeRemoved(position, 1);
1038 /// Notify any registered observers that the itemCount items previously located at positionStart have been removed from the data set.
1040 /// <param name="positionStart">Previous position of the first item that was removed</param>
1041 /// <param name="itemCount">Number of items removed from the data set </param>
1042 /// <since_tizen> 6 </since_tizen>
1043 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1044 [EditorBrowsable(EditorBrowsableState.Never)]
1045 public void NotifyItemRangeRemoved(int positionStart, int itemCount)
1047 ItemEventArgs args = new ItemEventArgs
1049 EventType = ItemEventType.Remove,
1051 args.param[0] = positionStart;
1052 args.param[1] = itemCount;
1053 OnItemEvent(this, args);
1057 /// Notify any registered observers that the item reflected at fromPosition has been moved to toPosition.
1059 /// <param name="fromPosition">Previous position of the item</param>
1060 /// <param name="toPosition">New position of the item. </param>
1061 /// <since_tizen> 6 </since_tizen>
1062 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1063 [EditorBrowsable(EditorBrowsableState.Never)]
1064 public void NotifyItemMoved(int fromPosition, int toPosition)
1069 private void OnItemEvent(object sender, ItemEventArgs e)
1071 itemEventHandlers?.Invoke(sender, e);
1074 internal class ItemEventArgs : EventArgs
1078 /// Data change event parameters.
1080 public int[] param = new int[4];
1083 /// Data changed event type.
1085 public ItemEventType EventType
1094 /// A LayoutManager is responsible for measuring and positioning item views within a FlexibleView
1095 /// as well as determining the policy for when to recycle item views that are no longer visible to the user.
1097 /// <since_tizen> 6 </since_tizen>
1098 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1099 [EditorBrowsable(EditorBrowsableState.Never)]
1100 public abstract class LayoutManager
1105 public enum Direction
1128 private FlexibleView mFlexibleView;
1129 private ChildHelper mChildHelper;
1131 private List<ViewHolder> mPendingRecycleViews = new List<ViewHolder>();
1133 private Animation mScrollAni;
1136 /// Layout all relevant child views from the given adapter.
1138 /// <param name="recycler">Recycler to use for fetching potentially cached views for a position</param>
1139 /// <since_tizen> 6 </since_tizen>
1140 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1141 [EditorBrowsable(EditorBrowsableState.Never)]
1142 public abstract void OnLayoutChildren(Recycler recycler);
1145 /// Called after a full layout calculation is finished.
1147 /// <since_tizen> 6 </since_tizen>
1148 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1149 [EditorBrowsable(EditorBrowsableState.Never)]
1150 public virtual void OnLayoutCompleted()
1156 /// Gets the current focus position in adapter.
1158 /// <since_tizen> 6 </since_tizen>
1159 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1160 [EditorBrowsable(EditorBrowsableState.Never)]
1161 public int FocusPosition
1165 return mFlexibleView.mFocusedItemIndex;
1170 /// Gets the datas count in data sets.
1172 /// <since_tizen> 6 </since_tizen>
1173 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1174 [EditorBrowsable(EditorBrowsableState.Never)]
1175 public int ItemCount
1179 Adapter b = mFlexibleView != null ? mFlexibleView.mAdapter : null;
1181 return b != null ? b.GetItemCount() : 0;
1186 /// Query if horizontal scrolling is currently supported. The default implementation returns false.
1188 /// <since_tizen> 6 </since_tizen>
1189 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1190 [EditorBrowsable(EditorBrowsableState.Never)]
1191 public virtual bool CanScrollHorizontally()
1197 /// Query if vertical scrolling is currently supported. The default implementation returns false.
1199 /// <since_tizen> 6 </since_tizen>
1200 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1201 [EditorBrowsable(EditorBrowsableState.Never)]
1202 public virtual bool CanScrollVertically()
1208 /// Scroll horizontally by dy pixels in screen coordinates.
1210 /// <param name="dy">distance to scroll in pixels. Y increases as scroll position approaches the top.</param>
1211 /// <param name="recycler">Recycler to use for fetching potentially cached views for a position</param>
1212 /// <param name="immediate">Specify if the scroll need animation</param>
1213 /// <since_tizen> 6 </since_tizen>
1214 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1215 [EditorBrowsable(EditorBrowsableState.Never)]
1216 public virtual float ScrollHorizontallyBy(float dy, Recycler recycler, bool immediate)
1222 /// Scroll vertically by dy pixels in screen coordinates.
1224 /// <param name="dy">distance to scroll in pixels. Y increases as scroll position approaches the top.</param>
1225 /// <param name="recycler">Recycler to use for fetching potentially cached views for a position</param>
1226 /// <param name="immediate">Specify if the scroll need animation</param>
1227 /// <since_tizen> 6 </since_tizen>
1228 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1229 [EditorBrowsable(EditorBrowsableState.Never)]
1230 public virtual float ScrollVerticallyBy(float dy, Recycler recycler, bool immediate)
1236 /// Compute the extent of the scrollbar's thumb within the range.
1238 /// <since_tizen> 6 </since_tizen>
1239 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1240 [EditorBrowsable(EditorBrowsableState.Never)]
1241 public virtual float ComputeScrollExtent()
1247 /// Compute the offset of the scrollbar's thumb within the range.
1249 /// <since_tizen> 6 </since_tizen>
1250 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1251 [EditorBrowsable(EditorBrowsableState.Never)]
1252 public virtual float ComputeScrollOffset()
1258 /// Compute the range that the scrollbar represents.
1260 /// <since_tizen> 6 </since_tizen>
1261 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1262 [EditorBrowsable(EditorBrowsableState.Never)]
1263 public virtual float ComputeScrollRange()
1269 /// Scroll the FlexibleView to make the position visible.
1271 /// <param name="position">Scroll to this adapter position</param>
1272 /// <since_tizen> 6 </since_tizen>
1273 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1274 [EditorBrowsable(EditorBrowsableState.Never)]
1275 public virtual void ScrollToPosition(int position)
1281 /// Scroll to the specified adapter position with the given offset from resolved layout start.
1283 /// <param name="position">Scroll to this adapter position</param>
1284 /// <param name="offset">The distance (in pixels) between the start edge of the item view and start edge of the FlexibleView.</param>
1285 /// <since_tizen> 6 </since_tizen>
1286 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1287 [EditorBrowsable(EditorBrowsableState.Never)]
1288 public virtual void ScrollToPositionWithOffset(int position, int offset)
1293 internal void MoveFocus(FlexibleView.LayoutManager.Direction direction, Recycler recycler)
1295 int prevFocusPosition = FocusPosition;
1296 int nextFocusPosition = GetNextPosition(FocusPosition, direction);
1297 if (nextFocusPosition == NO_POSITION)
1302 FlexibleView.ViewHolder nextFocusChild = FindItemViewByPosition(nextFocusPosition);
1303 if (nextFocusChild == null)
1305 nextFocusChild = OnFocusSearchFailed(null, direction, recycler);
1308 if (nextFocusChild != null)
1310 RequestChildRectangleOnScreen(mFlexibleView, nextFocusChild, recycler, false);
1312 ChangeFocus(nextFocusPosition);
1317 * Requests that the given child of the RecyclerView be positioned onto the screen. This
1318 * method can be called for both unfocusable and focusable child views. For unfocusable
1319 * child views, focusedChildVisible is typically true in which case, layout manager
1320 * makes the child view visible only if the currently focused child stays in-bounds of RV.
1321 * @param parent The parent RecyclerView.
1322 * @param child The direct child making the request.
1323 * @param rect The rectangle in the child's coordinates the child
1324 * wishes to be on the screen.
1325 * @param immediate True to forbid animated or delayed scrolling,
1327 * @param focusedChildVisible Whether the currently focused view must stay visible.
1328 * @return Whether the group scrolled to handle the operation
1330 internal bool RequestChildRectangleOnScreen(FlexibleView parent, FlexibleView.ViewHolder child, Recycler recycler, bool immediate)
1332 Vector2 scrollAmount = GetChildRectangleOnScreenScrollAmount(parent, child);
1333 float dx = scrollAmount[0];
1334 float dy = scrollAmount[1];
1335 if (dx != 0 || dy != 0)
1337 if (dx != 0 && CanScrollHorizontally())
1339 ScrollHorizontallyBy(dx, recycler, immediate);
1341 else if (dy != 0 && CanScrollVertically())
1343 ScrollVerticallyBy(dy, recycler, immediate);
1351 /// Calls {@code FlexibleView#RelayoutRequest} on the underlying FlexibleView.
1353 /// <since_tizen> 6 </since_tizen>
1354 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1355 [EditorBrowsable(EditorBrowsableState.Never)]
1356 public void RelayoutRequest()
1358 if (mFlexibleView != null)
1360 mFlexibleView.RelayoutRequest();
1365 /// Lay out the given child view within the FlexibleView using coordinates that include view margins.
1367 /// <param name="child">Child to lay out</param>
1368 /// <param name="left">Left edge, with item view left margin included</param>
1369 /// <param name="top">Top edge, with item view top margin included</param>
1370 /// <param name="width">Width, with item view left and right margin included</param>
1371 /// <param name="height">Height, with item view top and bottom margin included</param>
1372 /// <since_tizen> 6 </since_tizen>
1373 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1374 [EditorBrowsable(EditorBrowsableState.Never)]
1375 public void LayoutChild(ViewHolder child, float left, float top, float width, float height)
1377 View itemView = child.ItemView;
1378 itemView.SizeWidth = width - itemView.Margin.Start - itemView.Margin.End;
1379 itemView.SizeHeight = height - itemView.Margin.Top - itemView.Margin.Bottom;
1380 itemView.PositionX = left + itemView.Margin.Start;
1381 itemView.PositionY = top + itemView.Margin.Top;
1385 /// Change the ViewHolder with focusPosition to focus.
1387 /// <param name="focusPosition">the newly focus position</param>
1388 /// <since_tizen> 6 </since_tizen>
1389 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1390 [EditorBrowsable(EditorBrowsableState.Never)]
1391 public void ChangeFocus(int focusPosition)
1393 if (mFlexibleView != null)
1395 mFlexibleView.DispatchFocusChanged(focusPosition);
1400 /// Return the current number of child views attached to the parent FlexibleView.
1402 /// <since_tizen> 6 </since_tizen>
1403 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1404 [EditorBrowsable(EditorBrowsableState.Never)]
1405 public int GetChildCount()
1407 return mChildHelper != null ? mChildHelper.GetChildCount() : 0;
1411 /// Return the child view at the given index.
1413 /// <param name="index">child index</param>
1414 /// <since_tizen> 6 </since_tizen>
1415 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1416 [EditorBrowsable(EditorBrowsableState.Never)]
1417 public ViewHolder GetChildAt(int index)
1419 return mChildHelper != null ? mChildHelper.GetChildAt(index) : null;
1423 /// Finds the view which represents the given adapter position.
1425 /// <param name="position">adapter position</param>
1426 /// <since_tizen> 6 </since_tizen>
1427 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1428 [EditorBrowsable(EditorBrowsableState.Never)]
1429 public ViewHolder FindItemViewByPosition(int position)
1431 return mFlexibleView.FindViewHolderForLayoutPosition(position);
1435 /// Offset all child views attached to the parent FlexibleView by dx pixels along the horizontal axis.
1437 /// <param name="dx">Pixels to offset by </param>
1438 /// <param name="immediate">specify if the offset need animation</param>
1439 /// <since_tizen> 6 </since_tizen>
1440 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1441 [EditorBrowsable(EditorBrowsableState.Never)]
1442 public void OffsetChildrenHorizontal(float dx, bool immediate)
1444 if (mChildHelper == null)
1449 if (mScrollAni == null)
1451 mScrollAni = new Animation();
1452 mScrollAni.Finished += OnScrollAnimationFinished;
1454 else if (mScrollAni.State == Animation.States.Playing)
1457 mScrollAni.Stop(Animation.EndActions.StopFinal);
1459 mScrollAni.Duration = 500;
1460 mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
1464 int childCount = mChildHelper.GetChildCount();
1465 if (immediate == true)
1467 for (int i = childCount - 1; i >= 0; i--)
1469 ViewHolder v = mChildHelper.GetChildAt(i);
1470 v.ItemView.PositionX += dx;
1475 for (int i = childCount - 1; i >= 0; i--)
1477 ViewHolder v = mChildHelper.GetChildAt(i);
1478 mScrollAni.AnimateTo(v.ItemView, "PositionX", v.ItemView.PositionX + dx);
1485 /// Offset all child views attached to the parent FlexibleView by dy pixels along the vertical axis.
1487 /// <param name="dy">Pixels to offset by </param>
1488 /// <param name="immediate">specify if the offset need animation</param>
1489 /// <since_tizen> 6 </since_tizen>
1490 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1491 [EditorBrowsable(EditorBrowsableState.Never)]
1492 public void OffsetChildrenVertical(float dy, bool immediate)
1494 if (mChildHelper == null)
1499 if (mScrollAni == null)
1501 mScrollAni = new Animation();
1502 mScrollAni.Finished += OnScrollAnimationFinished;
1504 else if (mScrollAni.State == Animation.States.Playing)
1507 mScrollAni.Stop(Animation.EndActions.StopFinal);
1509 mScrollAni.Duration = 500;
1510 mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
1514 int childCount = mChildHelper.GetChildCount();
1515 if (immediate == true)
1517 for (int i = childCount - 1; i >= 0; i--)
1519 ViewHolder v = mChildHelper.GetChildAt(i);
1520 v.ItemView.PositionY += dy;
1525 for (int i = childCount - 1; i >= 0; i--)
1527 ViewHolder v = mChildHelper.GetChildAt(i);
1528 mScrollAni.AnimateTo(v.ItemView, "PositionY", v.ItemView.PositionY + dy);
1535 /// Return the width of the parent FlexibleView.
1537 /// <since_tizen> 6 </since_tizen>
1538 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1539 [EditorBrowsable(EditorBrowsableState.Never)]
1540 public float GetWidth()
1542 return mFlexibleView != null ? mFlexibleView.SizeWidth : 0;
1546 /// Return the height of the parent FlexibleView.
1548 /// <since_tizen> 6 </since_tizen>
1549 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1550 [EditorBrowsable(EditorBrowsableState.Never)]
1551 public float GetHeight()
1553 return mFlexibleView != null ? mFlexibleView.SizeHeight : 0;
1557 /// Return the left padding of the parent FlexibleView.
1559 /// <since_tizen> 6 </since_tizen>
1560 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1561 [EditorBrowsable(EditorBrowsableState.Never)]
1562 public int GetPaddingLeft()
1564 return mFlexibleView != null ? mFlexibleView.Padding.Start : 0;
1568 /// Return the top padding of the parent FlexibleView.
1570 /// <since_tizen> 6 </since_tizen>
1571 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1572 [EditorBrowsable(EditorBrowsableState.Never)]
1573 public int GetPaddingTop()
1575 return mFlexibleView != null ? mFlexibleView.Padding.Top : 0;
1579 /// Return the right padding of the parent FlexibleView.
1581 /// <since_tizen> 6 </since_tizen>
1582 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1583 [EditorBrowsable(EditorBrowsableState.Never)]
1584 public int GetPaddingRight()
1586 return mFlexibleView != null ? mFlexibleView.Padding.End : 0;
1590 /// Return the bottom padding of the parent FlexibleView.
1592 /// <since_tizen> 6 </since_tizen>
1593 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1594 [EditorBrowsable(EditorBrowsableState.Never)]
1595 public int GetPaddingBottom()
1597 return mFlexibleView != null ? mFlexibleView.Padding.Bottom : 0;
1601 /// Add a view to the currently attached FlexibleView if needed.<br />
1602 /// LayoutManagers should use this method to add views obtained from a FlexibleView.Recycler using getViewForPosition(int).<br />
1604 /// <param name="holder">view to add</param>
1605 /// <since_tizen> 6 </since_tizen>
1606 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1607 [EditorBrowsable(EditorBrowsableState.Never)]
1608 public void AddView(ViewHolder holder)
1610 AddView(holder, -1);
1614 /// Add a view to the currently attached FlexibleView if needed.<br />
1615 /// LayoutManagers should use this method to add views obtained from a FlexibleView.Recycler using getViewForPosition(int).<br />
1617 /// <param name="holder">view to add</param>
1618 /// <param name="index">index to add child at</param>
1619 /// <since_tizen> 6 </since_tizen>
1620 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1621 [EditorBrowsable(EditorBrowsableState.Never)]
1622 public void AddView(ViewHolder holder, int index)
1624 AddViewInternal(holder, index, false);
1628 /// Temporarily detach and scrap all currently attached child views.
1629 /// Views will be scrapped into the given Recycler.
1630 /// The Recycler may prefer to reuse scrap views before other views that were previously recycled.
1632 /// <param name="recycler">Recycler to scrap views into</param>
1633 /// <since_tizen> 6 </since_tizen>
1634 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1635 [EditorBrowsable(EditorBrowsableState.Never)]
1636 public void ScrapAttachedViews(Recycler recycler)
1638 if (mChildHelper == null)
1645 mChildHelper.ScrapViews(recycler);
1649 * Remove a child view and recycle it using the given Recycler.
1651 * @param index Index of child to remove and recycle
1652 * @param recycler Recycler to use to recycle child
1654 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1655 [EditorBrowsable(EditorBrowsableState.Never)]
1656 public void RemoveAndRecycleViewAt(int index, Recycler recycler)
1658 ViewHolder v = mChildHelper.GetChildAt(index);
1659 mChildHelper.RemoveViewAt(index);
1660 recycler.RecycleView(v);
1664 /// ecycles children between given indices..
1666 /// <param name="recycler">Recycler to recycle views into</param>
1667 /// <param name="startIndex">inclusive</param>
1668 /// <param name="endIndex">exclusive</param>
1669 /// <param name="immediate">recycle immediately or add to pending list and recycle later.</param>
1670 /// <since_tizen> 6 </since_tizen>
1671 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1672 [EditorBrowsable(EditorBrowsableState.Never)]
1673 public void RecycleChildren(FlexibleView.Recycler recycler, int startIndex, int endIndex, bool immediate)
1675 if (startIndex == endIndex)
1679 if (endIndex > startIndex)
1681 for (int i = startIndex; i < endIndex; i++)
1683 ViewHolder v = mChildHelper.GetChildAt(i);
1684 if (v.PendingRecycle == false)
1686 v.PendingRecycle = true;
1687 mPendingRecycleViews.Add(v);
1693 for (int i = startIndex; i > endIndex; i--)
1695 ViewHolder v = mChildHelper.GetChildAt(i);
1696 if (v.PendingRecycle == false)
1698 v.PendingRecycle = true;
1699 mPendingRecycleViews.Add(v);
1703 if (immediate == true)
1705 RecycleChildrenInt(recycler);
1710 /// Retrieves a position that neighbor to current position by direction.
1712 /// <param name="position">The anchor adapter position</param>
1713 /// <param name="direction">The direction.</param>
1714 /// <since_tizen> 6 </since_tizen>
1715 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1716 [EditorBrowsable(EditorBrowsableState.Never)]
1717 protected abstract int GetNextPosition(int position, FlexibleView.LayoutManager.Direction direction);
1719 internal virtual ViewHolder OnFocusSearchFailed(FlexibleView.ViewHolder focused, LayoutManager.Direction direction, Recycler recycler)
1724 internal void SetRecyclerView(FlexibleView recyclerView)
1726 mFlexibleView = recyclerView;
1727 mChildHelper = recyclerView.mChildHelper;
1730 internal void StopScroll()
1732 if (mScrollAni != null && mScrollAni.State == Animation.States.Playing)
1734 mScrollAni.Stop(Animation.EndActions.StopFinal);
1736 OnScrollAnimationFinished(mScrollAni, null);
1741 * Returns the scroll amount that brings the given rect in child's coordinate system within
1742 * the padded area of RecyclerView.
1743 * @param parent The parent RecyclerView.
1744 * @param child The direct child making the request.
1745 * @param rect The rectangle in the child's coordinates the child
1746 * wishes to be on the screen.
1747 * @param immediate True to forbid animated or delayed scrolling,
1749 * @return The array containing the scroll amount in x and y directions that brings the
1750 * given rect into RV's padded area.
1752 private Vector2 GetChildRectangleOnScreenScrollAmount(FlexibleView parent, FlexibleView.ViewHolder child)
1754 Vector2 ret = new Vector2(0, 0);
1755 int parentLeft = GetPaddingLeft();
1756 int parentTop = GetPaddingTop();
1757 int parentRight = (int)GetWidth() - GetPaddingRight();
1758 int parentBottom = (int)GetHeight() - GetPaddingBottom();
1759 int childLeft = (int)child.Left;
1760 int childTop = (int)child.Top;
1761 int childRight = (int)child.Right;
1762 int childBottom = (int)child.Bottom;
1764 int offScreenLeft = Math.Min(0, childLeft - parentLeft);
1765 int offScreenTop = Math.Min(0, childTop - parentTop);
1766 int offScreenRight = Math.Max(0, childRight - parentRight);
1767 int offScreenBottom = Math.Max(0, childBottom - parentBottom);
1769 // Favor the "start" layout direction over the end when bringing one side or the other
1770 // of a large rect into view. If we decide to bring in end because start is already
1771 // visible, limit the scroll such that start won't go out of bounds.
1772 int dx= offScreenLeft != 0 ? offScreenLeft
1773 : Math.Min(childLeft - parentLeft, offScreenRight);
1775 // Favor bringing the top into view over the bottom. If top is already visible and
1776 // we should scroll to make bottom visible, make sure top does not go out of bounds.
1777 int dy = offScreenTop != 0 ? offScreenTop
1778 : Math.Min(childTop - parentTop, offScreenBottom);
1786 private void OnScrollAnimationFinished(object sender, EventArgs e)
1788 RecycleChildrenInt(mFlexibleView.mRecycler);
1791 private void AddViewInternal(ViewHolder holder, int index, bool disappearing)
1793 if (holder.IsScrap())
1796 mChildHelper.AttachView(holder, index);
1800 mChildHelper.AddView(holder, index);
1804 private void RecycleChildrenInt(FlexibleView.Recycler recycler)
1806 foreach(ViewHolder holder in mPendingRecycleViews)
1808 holder.PendingRecycle = false;
1809 recycler.RecycleView(holder);
1810 mChildHelper.RemoveView(holder);
1812 mPendingRecycleViews.Clear();
1815 private void ScrapOrRecycleView(Recycler recycler, ViewHolder itemView)
1817 recycler.ScrapView(itemView);
1823 /// A ViewHolder describes an item view and metadata about its place within the FlexibleView.
1825 /// <since_tizen> 6 </since_tizen>
1826 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1827 [EditorBrowsable(EditorBrowsableState.Never)]
1828 public class ViewHolder
1831 * This ViewHolder has been bound to a position; AdapterPosition, mItemId and mItemViewType
1834 //static readonly int FLAG_BOUND = 1 << 0;
1837 * The data this ViewHolder's view reflects is stale and needs to be rebound
1838 * by the adapter. AdapterPosition and mItemId are consistent.
1840 //static readonly int FLAG_UPDATE = 1 << 1;
1843 * This ViewHolder's data is invalid. The identity implied by AdapterPosition and mItemId
1844 * are not to be trusted and may no longer match the item view type.
1845 * This ViewHolder must be fully rebound to different data.
1847 //static readonly int FLAG_INVALID = 1 << 2;
1850 * This ViewHolder points at data that represents an item previously removed from the
1851 * data set. Its view may still be used for things like outgoing animations.
1853 //static readonly int FLAG_REMOVED = 1 << 3;
1856 * This ViewHolder should not be recycled. This flag is set via setIsRecyclable()
1857 * and is intended to keep views around during animations.
1859 //static readonly int FLAG_NOT_RECYCLABLE = 1 << 4;
1862 * This ViewHolder is returned from scrap which means we are expecting an addView call
1863 * for this itemView. When returned from scrap, ViewHolder stays in the scrap list until
1864 * the end of the layout pass and then recycled by RecyclerView if it is not added back to
1867 //static readonly int FLAG_RETURNED_FROM_SCRAP = 1 << 5;
1870 * This ViewHolder is fully managed by the LayoutManager. We do not scrap, recycle or remove
1871 * it unless LayoutManager is replaced.
1872 * It is still fully visible to the LayoutManager.
1874 //static readonly int FLAG_IGNORE = 1 << 7;
1877 private int mPreLayoutPosition = NO_POSITION;
1880 /// ViewHolder constructor.
1882 /// <param name="itemView">View</param>
1883 /// <since_tizen> 6 </since_tizen>
1884 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1885 [EditorBrowsable(EditorBrowsableState.Never)]
1886 public ViewHolder(View itemView)
1888 if (itemView == null)
1890 throw new ArgumentNullException("itemView may not be null");
1892 this.ItemView = itemView;
1896 /// Returns the view.
1898 /// <since_tizen> 6 </since_tizen>
1899 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1900 [EditorBrowsable(EditorBrowsableState.Never)]
1901 public View ItemView { get; }
1904 /// Returns the left edge includes the view left margin.
1906 /// <since_tizen> 6 </since_tizen>
1907 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1908 [EditorBrowsable(EditorBrowsableState.Never)]
1913 return ItemView.PositionX - ItemView.Margin.Start;
1918 /// Returns the right edge includes the view right margin.
1920 /// <since_tizen> 6 </since_tizen>
1921 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1922 [EditorBrowsable(EditorBrowsableState.Never)]
1927 return ItemView.PositionX + ItemView.SizeWidth + ItemView.Margin.End;
1932 /// Returns the top edge includes the view top margin.
1934 /// <since_tizen> 6 </since_tizen>
1935 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1936 [EditorBrowsable(EditorBrowsableState.Never)]
1941 return ItemView.PositionY - ItemView.Margin.Top;
1946 /// Returns the bottom edge includes the view bottom margin.
1948 /// <since_tizen> 6 </since_tizen>
1949 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1950 [EditorBrowsable(EditorBrowsableState.Never)]
1955 return ItemView.PositionY + ItemView.SizeHeight + ItemView.Margin.Bottom;
1960 /// Returns the position of the ViewHolder in terms of the latest layout pass.
1962 /// <since_tizen> 6 </since_tizen>
1963 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1964 [EditorBrowsable(EditorBrowsableState.Never)]
1965 public int LayoutPosition
1969 return mPreLayoutPosition == NO_POSITION ? AdapterPosition : mPreLayoutPosition;
1974 /// Returns the Adapter position of the item represented by this ViewHolder.
1976 /// <since_tizen> 6 </since_tizen>
1977 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1978 [EditorBrowsable(EditorBrowsableState.Never)]
1979 public int AdapterPosition { get; internal set; } = NO_POSITION;
1982 /// Get old position of item view.
1984 /// <since_tizen> 6 </since_tizen>
1985 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1986 [EditorBrowsable(EditorBrowsableState.Never)]
1987 public int OldPosition { get; private set; } = NO_POSITION;
1990 /// Gets or sets item view type.
1992 /// <since_tizen> 6 </since_tizen>
1993 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1994 [EditorBrowsable(EditorBrowsableState.Never)]
1995 public int ItemViewType { get; set; } = INVALID_TYPE;
1997 internal bool IsBound
2003 internal Recycler ScrapContainer { get; set; }
2005 internal bool PendingRecycle
2012 internal bool IsScrap()
2014 return ScrapContainer != null;
2017 internal void Unscrap()
2019 ScrapContainer.UnscrapView(this);
2023 internal void FlagRemovedAndOffsetPosition(int mNewPosition, int offset, bool applyToPreLayout)
2025 //AddFlags(ViewHolder.FLAG_REMOVED);
2026 OffsetPosition(offset, applyToPreLayout);
2027 AdapterPosition = mNewPosition;
2030 internal void OffsetPosition(int offset, bool applyToPreLayout)
2032 if (OldPosition == NO_POSITION)
2034 OldPosition = AdapterPosition;
2036 if (mPreLayoutPosition == NO_POSITION)
2038 mPreLayoutPosition = AdapterPosition;
2040 if (applyToPreLayout)
2042 mPreLayoutPosition += offset;
2044 AdapterPosition += offset;
2047 internal void ClearOldPosition()
2049 OldPosition = NO_POSITION;
2050 mPreLayoutPosition = NO_POSITION;
2053 internal void SaveOldPosition()
2055 if (OldPosition == NO_POSITION)
2057 OldPosition = AdapterPosition;
2061 private void SetFlags(int flags, int mask)
2063 mFlags = (mFlags & ~mask) | (flags & mask);
2066 private void AddFlags(int flags)
2074 /// A Recycler is responsible for managing scrapped or detached item views for reuse.
2075 /// A "scrapped" view is a view that is still attached to its parent FlexibleView but that has been marked for removal or reuse.
2077 /// <since_tizen> 6 </since_tizen>
2078 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2079 [EditorBrowsable(EditorBrowsableState.Never)]
2080 public class Recycler
2082 private FlexibleView mFlexibleView;
2083 private RecycledViewPool mRecyclerPool;
2085 private List<ViewHolder> mAttachedScrap = new List<ViewHolder>();
2086 private List<ViewHolder> mChangedScrap = null;
2087 //private List<ItemView> mCachedViews = new List<ItemView>();
2089 //private List<ViewHolder> mUnmodifiableAttachedScrap;
2091 private int mCacheSizeMax = 2;
2094 /// Recycler constructor.
2096 /// <since_tizen> 6 </since_tizen>
2097 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2098 [EditorBrowsable(EditorBrowsableState.Never)]
2099 public Recycler(FlexibleView recyclerView)
2101 mFlexibleView = recyclerView;
2104 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2105 [EditorBrowsable(EditorBrowsableState.Never)]
2106 public void SetViewCacheSize(int viewCount)
2108 mCacheSizeMax = viewCount;
2112 /// Obtain a view initialized for the given position.
2114 /// <param name="position">Position to obtain a view for</param>
2115 /// <since_tizen> 6 </since_tizen>
2116 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2117 [EditorBrowsable(EditorBrowsableState.Never)]
2118 public ViewHolder GetViewForPosition(int position)
2120 Adapter b = mFlexibleView != null ? mFlexibleView.mAdapter : null;
2125 if (position < 0 || position >= b.GetItemCount())
2130 int type = b.GetItemViewType(position);
2131 ViewHolder itemView = null;
2132 for (int i = 0; i < mAttachedScrap.Count; i++)
2134 if (mAttachedScrap[i].LayoutPosition == position && mAttachedScrap[i].ItemViewType == type)
2136 itemView = mAttachedScrap[i];
2140 if (itemView == null)
2142 itemView = mRecyclerPool.GetRecycledView(type);
2143 if (itemView == null)
2145 itemView = b.OnCreateViewHolder(type);
2148 if (!itemView.IsBound)
2150 b.OnBindViewHolder(itemView, position);
2151 itemView.IsBound = true;
2154 itemView.AdapterPosition = position;
2155 itemView.ItemViewType = type;
2162 /// Recycle a detached view.
2164 /// <param name="itemView">Removed holder for recycling</param>
2165 /// <since_tizen> 6 </since_tizen>
2166 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2167 [EditorBrowsable(EditorBrowsableState.Never)]
2168 public void RecycleView(ViewHolder itemView)
2170 itemView.ScrapContainer = null;
2171 mRecyclerPool.PutRecycledView(itemView);
2175 /// Returns the count in scrap list.
2177 /// <since_tizen> 6 </since_tizen>
2178 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2179 [EditorBrowsable(EditorBrowsableState.Never)]
2180 public int GetScrapCount()
2182 return mAttachedScrap.Count;
2186 /// Gets the scrap view at index.
2188 /// <param name="index">index</param>
2189 /// <since_tizen> 6 </since_tizen>
2190 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2191 [EditorBrowsable(EditorBrowsableState.Never)]
2192 public ViewHolder GetScrapViewAt(int index)
2194 return mAttachedScrap[index];
2198 /// Clear scrap views out of this recycler. Detached views contained within a recycled view pool will remain.
2200 /// <since_tizen> 6 </since_tizen>
2201 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
2202 [EditorBrowsable(EditorBrowsableState.Never)]
2205 mAttachedScrap.Clear();
2206 if (mChangedScrap != null)
2208 mChangedScrap.Clear();
2212 internal void ScrapView(ViewHolder itemView)
2214 mAttachedScrap.Add(itemView);
2215 itemView.ScrapContainer = this;
2218 internal void UnscrapView(ViewHolder itemView)
2220 mAttachedScrap.Remove(itemView);
2221 itemView.ScrapContainer = null;
2224 internal void SetRecycledViewPool(RecycledViewPool pool)
2226 mRecyclerPool = pool;
2230 internal class RecycledViewPool
2232 private FlexibleView mFlexibleView;
2234 private int mMaxTypeCount = 10;
2235 private List<ViewHolder>[] mScrap;
2237 public RecycledViewPool(FlexibleView flexibleView)
2239 mFlexibleView = flexibleView;
2240 mScrap = new List<ViewHolder>[mMaxTypeCount];
2243 //public void SetViewTypeCount(int typeCount)
2247 public ViewHolder GetRecycledView(int viewType)
2249 if (viewType >= mMaxTypeCount || mScrap[viewType] == null)
2254 int index = mScrap[viewType].Count - 1;
2259 ViewHolder recycledView = mScrap[viewType][index];
2260 mScrap[viewType].RemoveAt(index);
2262 return recycledView;
2265 public void PutRecycledView(ViewHolder view)
2267 int viewType = view.ItemViewType;
2268 if (mScrap[viewType] == null)
2270 mScrap[viewType] = new List<ViewHolder>();
2272 view.IsBound = false;
2273 mScrap[viewType].Add(view);
2278 for (int i = 0; i < mMaxTypeCount; i++)
2280 if (mScrap[i] == null)
2284 for (int j = 0; j < mScrap[i].Count; j++)
2286 mFlexibleView.DispatchChildDestroyed(mScrap[i][j]);
2293 private class ChildHelper
2295 private FlexibleView mFlexibleView;
2297 private List<ViewHolder> mViewList = new List<ViewHolder>();
2299 //private List<ViewHolder> mRemovePendingViews;
2301 private Dictionary<uint, ViewHolder> itemViewTable = new Dictionary<uint, ViewHolder>();
2302 private TapGestureDetector mTapGestureDetector;
2304 public ChildHelper(FlexibleView owner)
2306 mFlexibleView = owner;
2308 mTapGestureDetector = new TapGestureDetector();
2309 mTapGestureDetector.Detected += OnTapGestureDetected;
2314 foreach(ViewHolder holder in mViewList)
2316 mFlexibleView.Remove(holder.ItemView);
2318 mFlexibleView.DispatchChildDestroyed(holder);
2323 public void ScrapViews(Recycler recycler)
2326 foreach (ViewHolder itemView in mViewList)
2328 recycler.ScrapView(itemView);
2334 public void AttachView(ViewHolder holder, int index)
2338 index = mViewList.Count;
2340 mViewList.Insert(index, holder);
2342 if (!itemViewTable.ContainsKey(holder.ItemView.ID))
2344 mTapGestureDetector.Attach(holder.ItemView);
2345 holder.ItemView.TouchEvent += OnTouchEvent;
2348 itemViewTable[holder.ItemView.ID] = holder;
2351 public void AddView(ViewHolder holder, int index)
2353 mFlexibleView.Add(holder.ItemView);
2355 mFlexibleView.DispatchChildAttached(holder);
2357 AttachView(holder, index);
2360 public bool RemoveView(ViewHolder holder)
2362 mFlexibleView.Remove(holder.ItemView);
2364 mFlexibleView.DispatchChildDetached(holder);
2366 return mViewList.Remove(holder);
2369 public bool RemoveViewAt(int index)
2371 ViewHolder itemView = mViewList[index];
2372 return RemoveView(itemView);
2375 public bool RemoveViewsRange(int index, int count)
2377 for (int i = index; i < index + count; i++)
2379 ViewHolder holder = mViewList[i];
2380 mFlexibleView.Remove(holder.ItemView);
2382 mViewList.RemoveRange(index, count);
2386 public int GetChildCount()
2388 return mViewList.Count;
2391 public ViewHolder GetChildAt(int index)
2393 if (index < 0 || index >= mViewList.Count)
2397 return mViewList[index];
2400 private void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e)
2402 View itemView = e.View as View;
2403 if (itemView == null)
2407 if (itemViewTable.ContainsKey(itemView.ID))
2409 ViewHolder holder = itemViewTable[itemView.ID];
2410 mFlexibleView.FocusedItemIndex = holder.AdapterPosition;
2412 mFlexibleView.DispatchItemClicked(holder);
2416 private bool OnTouchEvent(object source, TouchEventArgs e)
2418 View itemView = source as View;
2419 if (itemView != null && itemViewTable.ContainsKey(itemView.ID))
2421 ViewHolder holder = itemViewTable[itemView.ID];
2423 mFlexibleView.DispatchItemTouched(holder, e.Touch);
2430 private class AdapterHelper
2432 private FlexibleView mFlexibleView;
2434 private List<UpdateOp> mPendingUpdates = new List<UpdateOp>();
2436 private int mExistingUpdateTypes = 0;
2438 public AdapterHelper(FlexibleView flexibleView)
2440 mFlexibleView = flexibleView;
2444 * @return True if updates should be processed.
2446 public bool OnItemRangeInserted(int positionStart, int itemCount)
2452 mPendingUpdates.Add(new UpdateOp(UpdateOp.ADD, positionStart, itemCount));
2453 mExistingUpdateTypes |= UpdateOp.ADD;
2454 return mPendingUpdates.Count == 1;
2458 * @return True if updates should be processed.
2460 public bool OnItemRangeRemoved(int positionStart, int itemCount)
2466 mPendingUpdates.Add(new UpdateOp(UpdateOp.REMOVE, positionStart, itemCount));
2467 mExistingUpdateTypes |= UpdateOp.REMOVE;
2468 return mPendingUpdates.Count == 1;
2471 public void PreProcess()
2473 int count = mPendingUpdates.Count;
2474 for (int i = 0; i < count; i++)
2476 UpdateOp op = mPendingUpdates[i];
2480 mFlexibleView.OffsetPositionRecordsForInsert(op.positionStart, op.itemCount);
2482 case UpdateOp.REMOVE:
2483 mFlexibleView.OffsetPositionRecordsForRemove(op.positionStart, op.itemCount, false);
2485 case UpdateOp.UPDATE:
2491 mPendingUpdates.Clear();
2497 * Queued operation to happen when child views are updated.
2499 private class UpdateOp
2502 public const int ADD = 1;
2504 public const int REMOVE = 1 << 1;
2506 public const int UPDATE = 1 << 2;
2508 public const int MOVE = 1 << 3;
2510 public const int POOL_SIZE = 30;
2514 public int positionStart;
2516 // holds the target position if this is a MOVE
2517 public int itemCount;
2519 public UpdateOp(int cmd, int positionStart, int itemCount)
2522 this.positionStart = positionStart;
2523 this.itemCount = itemCount;
2526 public bool Equals(UpdateOp op)
2532 if (cmd == MOVE && Math.Abs(itemCount - positionStart) == 1)
2534 // reverse of this is also true
2535 if (itemCount == op.positionStart && positionStart == op.itemCount)
2540 if (itemCount != op.itemCount)
2544 if (positionStart != op.positionStart)
2554 private class ItemViewInfo