oldValue = colView.selectedItem;
colView.selectedItem = newValue;
- var args = new SelectionChangedEventArgs(oldValue, newValue);
+ var args = new SelectionChangedEventArgs(oldValue, newValue);
foreach (RecyclerViewItem item in colView.ContentContainer.Children.Where((item) => item is RecyclerViewItem))
{
if (item.BindingContext == null)
if (itemsSource == null)
{
- InternalItemSource?.Dispose();
- InternalItemSource = null;
+ InternalSource?.Dispose();
+ InternalSource = null;
itemsLayouter?.Clear();
ClearCache();
return;
newNotifyCollectionChanged.CollectionChanged += CollectionChanged;
}
- InternalItemSource?.Dispose();
- InternalItemSource = ItemsSourceFactory.Create(this);
+ InternalSource?.Dispose();
+ InternalSource = ItemsSourceFactory.Create(this);
if (itemsLayouter == null) return;
ContentContainer.Add(value);
}
header = value;
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.HasHeader = (value != null);
+ InternalSource.HasHeader = (value != null);
}
needInitalizeLayouter = true;
ReinitializeLayout();
}
if (value != null)
{
- value.Index = InternalItemSource?.Count ?? 0;
+ value.Index = InternalSource?.Count ?? 0;
value.ParentItemsView = this;
value.IsFooter = true;
ContentContainer.Add(value);
}
footer = value;
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.HasFooter = (value != null);
+ InternalSource.HasFooter = (value != null);
}
needInitalizeLayouter = true;
ReinitializeLayout();
isGrouped = value;
needInitalizeLayouter = true;
//Need to re-intialize Internal Item Source.
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.Dispose();
- InternalItemSource = null;
+ InternalSource.Dispose();
+ InternalSource = null;
}
if (ItemsSource != null)
{
- InternalItemSource = ItemsSourceFactory.Create(this);
+ InternalSource = ItemsSourceFactory.Create(this);
}
ReinitializeLayout();
needInitalizeLayouter = true;
//Need to re-intialize Internal Item Source.
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.Dispose();
- InternalItemSource = null;
+ InternalSource.Dispose();
+ InternalSource = null;
}
if (ItemsSource != null)
{
- InternalItemSource = ItemsSourceFactory.Create(this);
+ InternalSource = ItemsSourceFactory.Create(this);
}
ReinitializeLayout();
needInitalizeLayouter = true;
//Need to re-intialize Internal Item Source.
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.Dispose();
- InternalItemSource = null;
+ InternalSource.Dispose();
+ InternalSource = null;
}
if (ItemsSource != null)
{
- InternalItemSource = ItemsSourceFactory.Create(this);
+ InternalSource = ItemsSourceFactory.Create(this);
}
ReinitializeLayout();
/// <summary>
/// Internal encapsulated items data source.
/// </summary>
- internal new IGroupableItemSource InternalItemSource
+ internal new IGroupableItemSource InternalSource
{
get
{
- return (base.InternalItemSource as IGroupableItemSource);
+ return (base.InternalSource as IGroupableItemSource);
}
set
{
- base.InternalItemSource = value;
+ base.InternalSource = value;
}
}
throw new Exception("Item Layouter must exist.");
}
- if ((InternalItemSource == null) || needInitalizeLayouter)
+ if ((InternalSource == null) || needInitalizeLayouter)
{
delayedScrollTo = true;
delayedScrollToParam = (position, animate);
throw new Exception("Item Layouter must exist.");
}
- if ((InternalItemSource == null) || needInitalizeLayouter)
+ if ((InternalSource == null) || needInitalizeLayouter)
{
delayedIndexScrollTo = true;
delayedIndexScrollToParam = (index, animate, align);
return;
}
- if (index < 0 || index >= InternalItemSource.Count)
+ if (index < 0 || index >= InternalSource.Count)
{
- throw new Exception("index is out of boundary. index should be a value between (0, " + InternalItemSource.Count.ToString() + ").");
+ throw new Exception("index is out of boundary. index should be a value between (0, " + InternalSource.Count.ToString() + ").");
}
float scrollPos, curPos, curSize, curItemSize;
curItemSize = height;
}
- //Console.WriteLine("[NUI] ScrollTo [{0}:{1}], curPos{2}, itemPos{3}, curSize{4}, itemSize{5}", InternalItemSource.GetPosition(item), align, curPos, scrollPos, curSize, curItemSize);
+ //Console.WriteLine("[NUI] ScrollTo [{0}:{1}], curPos{2}, itemPos{3}, curSize{4}, itemSize{5}", InternalSource.GetPosition(item), align, curPos, scrollPos, curSize, curItemSize);
switch (align)
{
case ItemScrollTo.Start:
return true;
}
- // Realize and Decorate the item.
-
- internal override RecyclerViewItem RealizeItem(int index)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal override RecyclerViewItem RealizeItem(int index)
{
RecyclerViewItem item;
if (index == 0 && Header != null)
return Header;
}
- if (index == InternalItemSource.Count - 1 && Footer != null)
+ if (index == InternalSource.Count - 1 && Footer != null)
{
Footer.Show();
return Footer;
if (isGrouped)
{
- var context = InternalItemSource.GetItem(index);
- if (InternalItemSource.IsGroupHeader(index))
+ var context = InternalSource.GetItem(index);
+ if (InternalSource.IsGroupHeader(index))
{
item = RealizeGroupHeader(index, context);
}
- else if (InternalItemSource.IsGroupFooter(index))
+ else if (InternalSource.IsGroupFooter(index))
{
//group selection?
{
throw new Exception("Item realize failed by Null content return.");
}
- item.ParentGroup = InternalItemSource.GetGroupParent(index);
+ item.ParentGroup = InternalSource.GetGroupParent(index);
}
}
else
return item;
}
- // Unrealize and caching the item.
- internal override void UnrealizeItem(RecyclerViewItem item, bool recycle = true)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal override void UnrealizeItem(RecyclerViewItem item, bool recycle = true)
{
if (item == null)
{
return;
}
- if (item.isGroupHeader || item.isGroupFooter)
+ if (item.IsGroupHeader || item.IsGroupFooter)
{
item.Index = -1;
item.ParentItemsView = null;
selectedItems.Clear();
selectedItems = null;
}
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.Dispose();
- InternalItemSource = null;
+ InternalSource.Dispose();
+ InternalSource = null;
}
}
if (command != null)
{
var commandParameter = colView.SelectionChangedCommandParameter;
+ if (commandParameter == null)
+ {
+ commandParameter = args;
+ }
if (command.CanExecute(commandParameter))
{
if (needInitalizeLayouter)
{
- if (InternalItemSource == null)
+ if (InternalSource == null)
{
return;
}
- InternalItemSource.HasHeader = (header != null);
- InternalItemSource.HasFooter = (footer != null);
+ InternalSource.HasHeader = (header != null);
+ InternalSource.HasFooter = (footer != null);
itemsLayouter.Clear();
ClearCache();
return false;
}
- if (item.isGroupHeader)
+ if (item.IsGroupHeader)
{
recycleGroupHeaderCache.Add(item);
}
- else if (item.isGroupFooter)
+ else if (item.IsGroupFooter)
{
recycleGroupFooterCache.Add(item);
}
}
groupHeader.Template = templ;
- groupHeader.isGroupHeader = true;
- groupHeader.isGroupFooter = false;
+ groupHeader.IsGroupHeader = true;
+ groupHeader.IsGroupFooter = false;
ContentContainer.Add(groupHeader);
}
}
groupFooter.Template = templ;
- groupFooter.isGroupHeader = false;
- groupFooter.isGroupFooter = true;
+ groupFooter.IsGroupHeader = false;
+ groupFooter.IsGroupFooter = true;
ContentContainer.Add(groupFooter);
}
}
}
- /* open when ImageView using Uri not string
- /// <summary>
- /// Image image's resource url in DefaultGridItem.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public string ImageUrl
- {
- get
- {
- return Image.ResourceUrl;
- }
- set
- {
- Image.ResourceUrl = value;
- }
- }
- */
+ /// <summary>
+ /// Image resource url in DefaultGridItem.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public string ResourceUrl
+ {
+ get => GetValue(ResourceUrlProperty) as string;
+ set
+ {
+ SetValue(ResourceUrlProperty, value);
+ NotifyPropertyChanged();
+ }
+ }
+
+ internal string InternalResourceUrl
+ {
+ get
+ {
+ return Image.ResourceUrl;
+ }
+ set
+ {
+ Image.ResourceUrl = value;
+ }
+ }
+
/// <summary>
/// DefaultGridItem's text part.
RelativeLayout.SetRightTarget(itemImage, this);
RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
+ RelativeLayout.SetFillHorizontal(itemImage, true);
+ RelativeLayout.SetFillVertical(itemImage, true);
if (itemLabel != null)
{
return instance.InternalText;
});
+
+ /// <summary>
+ /// ResourceUrlProperty
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly BindableProperty ResourceUrlProperty = BindableProperty.Create(nameof(ResourceUrl), typeof(string), typeof(DefaultGridItem), default(string), propertyChanged: (bindable, oldValue, newValue) =>
+ {
+ var instance = (DefaultGridItem)bindable;
+ if (newValue != null)
+ {
+ instance.InternalResourceUrl = newValue as string;
+ }
+ },
+ defaultValueCreator: (bindable) =>
+ {
+ var instance = (DefaultGridItem)bindable;
+ return instance.InternalResourceUrl;
+ });
+
/// <summary>
/// LabelOrientationTypeProperty
/// </summary>
{
internal RecyclerView ParentItemsView = null;
internal object ParentGroup = null;
- internal bool isGroupHeader;
- internal bool isGroupFooter;
private bool styleApplied = false;
/// <summary>
else if (collectionView.SelectionMode is ItemSelectionMode.Multiple)
{
var selectedList = collectionView.SelectedItems;
- bool contains = selectedList.Contains(context);
- if (newSelected && !contains)
+ if (selectedList != null)
{
- selectedList.Add(context);
- }
- else if (!newSelected && contains)
- {
- selectedList.Remove(context);
+ bool contains = selectedList.Contains(context);
+ if (newSelected && !contains)
+ {
+ selectedList.Add(context);
+ }
+ else if (!newSelected && contains)
+ {
+ selectedList.Remove(context);
+ }
}
}
}
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsRealized { get; internal set; }
- internal bool IsHeader { get; set; }
- internal bool IsFooter { get; set; }
- internal bool IsPressed { get; set; } = false;
+
+ /// <summary>
+ /// State of Pressed.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsPressed { get; set; } = false;
+
+ /// <summary>
+ /// Boolean flag to check this item is header.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsHeader { get; set; }
+
+ /// <summary>
+ /// Boolean flag to check this item is footer.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsFooter { get; set; }
+
+ /// <summary>
+ /// Boolean flag to check this item is group header.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsGroupHeader { get; set; }
+
+ /// <summary>
+ /// Boolean flag to check this item is group footer.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsGroupFooter { get; set; }
+
/// <summary>
/// Called after a key event is received by the view that has had its focus set.
/// <since_tizen> 9 </since_tizen>
public class GridLayouter : ItemsLayouter
{
- private CollectionView colView;
+ private CollectionView collectionView;
private (float Width, float Height) sizeCandidate;
private int spanSize = 1;
private float align = 0.5f;
private Timer requestLayoutTimer = null;
private bool isSourceEmpty;
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected new IGroupableItemSource Source => collectionView?.InternalSource;
+
+ /// <summary>
+ /// Span Size
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected int SpanSize => spanSize;
+
+ /// <summary>
+ /// Size Candidate
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected (float Width, float Height) SizeCandidate => sizeCandidate;
+
+ /// <summary>
+ /// Visible ViewItem.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override List<GroupInfo> GroupItems => groups;
+
/// <summary>
/// Clean up ItemsLayouter.
/// </summary>
/// <since_tizen> 9 </since_tizen>
public override void Initialize(RecyclerView view)
{
- colView = view as CollectionView;
- if (colView == null)
+ collectionView = view as CollectionView;
+ if (collectionView == null)
{
throw new ArgumentException("GridLayouter only can be applied CollectionView.", nameof(view));
}
// 1. Clean Up
foreach (RecyclerViewItem item in VisibleItems)
{
- colView.UnrealizeItem(item, false);
+ collectionView.UnrealizeItem(item, false);
}
VisibleItems.Clear();
groups.Clear();
-
FirstVisible = 0;
LastVisible = 0;
- IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+ IsHorizontal = (collectionView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
- RecyclerViewItem header = colView?.Header;
- RecyclerViewItem footer = colView?.Footer;
+ RecyclerViewItem header = collectionView?.Header;
+ RecyclerViewItem footer = collectionView?.Footer;
float width, height;
- int count = colView.InternalItemSource.Count;
+ int count = Source.Count;
int pureCount = count - (header? 1 : 0) - (footer? 1 : 0);
// 2. Get the header / footer and size deligated item and measure the size.
if (header != null)
{
- MeasureChild(colView, header);
+ MeasureChild(collectionView, header);
width = header.Layout != null? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
height = header.Layout != null? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
headerMargin = new Extents(itemMargin);
hasHeader = true;
- colView.UnrealizeItem(header);
+ collectionView.UnrealizeItem(header);
}
if (footer != null)
{
- MeasureChild(colView, footer);
+ MeasureChild(collectionView, footer);
width = footer.Layout != null? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
height = footer.Layout != null? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
footer.Index = count - 1;
hasFooter = true;
- colView.UnrealizeItem(footer);
+ collectionView.UnrealizeItem(footer);
}
if (pureCount == 0)
{
isSourceEmpty = true;
- base.Initialize(colView);
+ base.Initialize(collectionView);
return;
}
isSourceEmpty = false;
int firstIndex = header? 1 : 0;
- if (colView.IsGrouped)
+ if (collectionView.IsGrouped)
{
isGrouped = true;
- if (colView.GroupHeaderTemplate != null)
+ if (collectionView.GroupHeaderTemplate != null)
{
- while (!colView.InternalItemSource.IsGroupHeader(firstIndex)) firstIndex++;
+ while (!Source.IsGroupHeader(firstIndex)) firstIndex++;
//must be always true
- if (colView.InternalItemSource.IsGroupHeader(firstIndex))
+ if (Source.IsGroupHeader(firstIndex))
{
- RecyclerViewItem groupHeader = colView.RealizeItem(firstIndex);
+ RecyclerViewItem groupHeader = collectionView.RealizeItem(firstIndex);
firstIndex++;
if (groupHeader == null) throw new Exception("[" + firstIndex + "] Group Header failed to realize!");
}
else
{
- MeasureChild(colView, groupHeader);
+ MeasureChild(collectionView, groupHeader);
width = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
width + itemMargin.Start + itemMargin.End:
height + itemMargin.Top + itemMargin.Bottom;
groupHeaderMargin = new Extents(itemMargin);
- colView.UnrealizeItem(groupHeader);
+ collectionView.UnrealizeItem(groupHeader);
}
}
else
groupHeaderSize = 0F;
}
- if (colView.GroupFooterTemplate != null)
+ if (collectionView.GroupFooterTemplate != null)
{
int firstFooter = firstIndex;
- while (!colView.InternalItemSource.IsGroupFooter(firstFooter)) firstFooter++;
+ while (!Source.IsGroupFooter(firstFooter)) firstFooter++;
//must be always true
- if (colView.InternalItemSource.IsGroupFooter(firstFooter))
+ if (Source.IsGroupFooter(firstFooter))
{
- RecyclerViewItem groupFooter = colView.RealizeItem(firstFooter);
+ RecyclerViewItem groupFooter = collectionView.RealizeItem(firstFooter);
if (groupFooter == null) throw new Exception("[" + firstFooter + "] Group Footer failed to realize!");
// Need to Set proper height or width on scroll direction.
}
else
{
- MeasureChild(colView, groupFooter);
+ MeasureChild(collectionView, groupFooter);
width = groupFooter.Layout.MeasuredWidth.Size.AsRoundedValue();
height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
height + itemMargin.Top + itemMargin.Bottom;
groupFooterMargin = new Extents(itemMargin);
- colView.UnrealizeItem(groupFooter);
+ collectionView.UnrealizeItem(groupFooter);
}
}
else
bool failed = false;
//Final Check of FirstIndex
- while (colView.InternalItemSource.IsHeader(firstIndex) ||
- colView.InternalItemSource.IsGroupHeader(firstIndex) ||
- colView.InternalItemSource.IsGroupFooter(firstIndex))
+ if ((Source.Count - 1 < firstIndex) ||
+ (Source.IsFooter(firstIndex) && (Source.Count - 1) == firstIndex))
{
- if (colView.InternalItemSource.IsFooter(firstIndex))
+ StepCandidate = 0F;
+ failed = true;
+ }
+
+ while (!failed &&
+ Source.IsHeader(firstIndex) ||
+ Source.IsGroupHeader(firstIndex) ||
+ Source.IsGroupFooter(firstIndex))
+ {
+ if (Source.IsFooter(firstIndex)
+ || ((Source.Count - 1) <= firstIndex))
{
StepCandidate = 0F;
failed = true;
if (!failed)
{
// Get Size Deligate. FIXME if group exist index must be changed.
- RecyclerViewItem sizeDeligate = colView.RealizeItem(firstIndex);
+ RecyclerViewItem sizeDeligate = collectionView.RealizeItem(firstIndex);
if (sizeDeligate == null)
{
throw new Exception("Cannot create content from DatTemplate.");
}
- sizeDeligate.BindingContext = colView.InternalItemSource.GetItem(firstIndex);
+ sizeDeligate.BindingContext = Source.GetItem(firstIndex);
// Need to Set proper height or width on scroll direction.
if (sizeDeligate.Layout == null)
}
else
{
- MeasureChild(colView, sizeDeligate);
+ MeasureChild(collectionView, sizeDeligate);
width = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
if (width == 0) width = 1;
if (height == 0) height = 1;
spanSize = IsHorizontal?
- Convert.ToInt32(Math.Truncate((double)((colView.Size.Height - Padding.Top - Padding.Bottom) / height))) :
- Convert.ToInt32(Math.Truncate((double)((colView.Size.Width - Padding.Start - Padding.End) / width)));
+ Convert.ToInt32(Math.Truncate((double)((collectionView.Size.Height - Padding.Top - Padding.Bottom) / height))) :
+ Convert.ToInt32(Math.Truncate((double)((collectionView.Size.Width - Padding.Start - Padding.End) / width)));
sizeCandidate = (width, height);
- colView.UnrealizeItem(sizeDeligate);
+ collectionView.UnrealizeItem(sizeDeligate);
}
if (StepCandidate < 1) StepCandidate = 1;
if (isGrouped)
{
float Current = 0.0F;
- IGroupableItemSource source = colView.InternalItemSource;
+ IGroupableItemSource source = Source;
GroupInfo currentGroup = null;
object currentParent = null;
if (currentGroup != null)
{
currentGroup.Count++;
- int index = i - currentGroup.StartIndex - ((colView.GroupHeaderTemplate != null) ? 1 : 0);
+ int index = i - currentGroup.StartIndex - ((collectionView.GroupHeaderTemplate != null) ? 1 : 0);
if ((index % spanSize) == 0)
{
currentGroup.GroupSize += StepCandidate;
ScrollContentSize + Padding.Start + Padding.End:
ScrollContentSize + Padding.Top + Padding.Bottom;
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
- base.Initialize(colView);
+ base.Initialize(collectionView);
//Console.WriteLine("Init Done, StepCnadidate{0}, spanSize{1}, Scroll{2}", StepCandidate, spanSize, ScrollContentSize);
}
{
// Layouting is only possible after once it intialized.
if (!IsInitialized) return;
- int LastIndex = colView.InternalItemSource.Count;
+ int LastIndex = Source.Count;
if (!force && PrevScrollPosition == Math.Abs(scrollPosition)) return;
PrevScrollPosition = Math.Abs(scrollPosition);
int prevFirstVisible = FirstVisible;
int prevLastVisible = LastVisible;
- bool IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+ bool IsHorizontal = (collectionView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
(float X, float Y) visibleArea = (PrevScrollPosition,
- PrevScrollPosition + (IsHorizontal? colView.Size.Width : colView.Size.Height)
+ PrevScrollPosition + (IsHorizontal? collectionView.Size.Width : collectionView.Size.Height)
);
- //Console.WriteLine("[NUI] itemsView [{0},{1}] [{2},{3}]", colView.Size.Width, colView.Size.Height, colView.ContentContainer.Size.Width, colView.ContentContainer.Size.Height);
+ //Console.WriteLine("[NUI] itemsView [{0},{1}] [{2},{3}]", collectionView.Size.Width, collectionView.Size.Height, collectionView.ContentContainer.Size.Width, collectionView.ContentContainer.Size.Height);
// 1. Set First/Last Visible Item Index.
(int start, int end) = FindVisibleItems(visibleArea);
{
//Console.WriteLine("[NUI] Unrealize{0}!", item.Index);
unrealizedItems.Add(item);
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
}
VisibleItems.RemoveAll(unrealizedItems.Contains);
}
if (item == null)
{
- item = colView.RealizeItem(i);
+ item = collectionView.RealizeItem(i);
if (item != null) VisibleItems.Add(item);
else throw new Exception("Failed to create RecycerViewItem index of ["+ i + "]");
}
item.Position = new Position(x, y);
//Linear Item need to be resized!
- if (item.IsHeader || item.IsFooter || item.isGroupHeader || item.isGroupFooter)
+ if (item.IsHeader || item.IsFooter || item.IsGroupHeader || item.IsGroupFooter)
{
var size = (IsHorizontal? item.SizeWidth: item.SizeHeight);
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureFirst)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureFirst)
{
if (item.IsHeader) size = headerSize;
else if (item.IsFooter) size = footerSize;
- else if (item.isGroupHeader) size = groupHeaderSize;
- else if (item.isGroupFooter) size = groupFooterSize;
+ else if (item.IsGroupHeader) size = groupHeaderSize;
+ else if (item.IsGroupFooter) size = groupFooterSize;
}
if (IsHorizontal && item.HeightSpecification == LayoutParamPolicies.MatchParent)
{
{
// Insert Single item.
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
- if (isSourceEmpty)
+ if (collectionView == null) return;
+ if (isSourceEmpty || StepCandidate <= 1)
{
- Initialize(colView);
+ Initialize(collectionView);
}
// Will be null if not a group.
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Wrong! Grid Layouter do not support MeasureAll!
}
else
{
- int pureCount = groupInfo.Count - 1 - (colView.GroupFooterTemplate == null? 0: 1);
+ int pureCount = groupInfo.Count - 1 - (collectionView.GroupFooterTemplate == null? 0: 1);
if (pureCount % spanSize == 0)
{
currentSize = StepCandidate;
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Wrong! Grid Layouter do not support MeasureAll!
}
- int pureCount = colView.InternalItemSource.Count - (hasHeader? 1: 0) - (hasFooter? 1: 0);
+ int pureCount = Source.Count - (hasHeader? 1: 0) - (hasFooter? 1: 0);
// Count comes after updated in ungrouped case!
if (pureCount % spanSize == 1)
// 3. Update Scroll Content Size
ScrollContentSize += currentSize;
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
foreach (RecyclerViewItem item in VisibleItems)
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Insert Group
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
- if (isSourceEmpty)
+ if (collectionView == null) return;
+ if (isSourceEmpty || StepCandidate <= 1)
{
- Initialize(colView);
+ Initialize(collectionView);
}
float currentSize = StepCandidate;
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Wrong! Grid Layouter do not support MeasureAll!
}
else
{
- int index = current - groupStartIndex - ((colView.GroupHeaderTemplate != null)? 1: 0);
+ int index = current - groupStartIndex - ((collectionView.GroupHeaderTemplate != null)? 1: 0);
if ((index % spanSize) == 0)
{
groupInfo.GroupSize += StepCandidate;
}
// 3. Update Scroll Content Size
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
foreach (RecyclerViewItem item in VisibleItems)
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Remove Single
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = 0;
// Remove Group
// groupInfo.Dispose();
groups.Remove(groupInfo);
+ parentIndex--;
}
else
{
groupInfo.Count--;
// Skip footer case as footer cannot exist alone without header.
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Wrong! Grid Layouter do not support MeasureAll!
}
else
{
- int pureCount = groupInfo.Count - 1 - (colView.GroupFooterTemplate == null? 0: 1);
+ int pureCount = groupInfo.Count - 1 - (collectionView.GroupFooterTemplate == null? 0: 1);
if (pureCount % spanSize == 0)
{
currentSize = StepCandidate;
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Wrong! Grid Layouter do not support MeasureAll!
}
- int pureCount = colView.InternalItemSource.Count - (hasHeader? 1: 0) - (hasFooter? 1: 0);
+ int pureCount = Source.Count - (hasHeader? 1: 0) - (hasFooter? 1: 0);
// Count comes after updated in ungrouped case!
if (pureCount % spanSize == 0)
ScrollContentSize -= currentSize;
// 3. Update Scroll Content Size
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
RecyclerViewItem targetItem = null;
if (item.Index == startIndex)
{
targetItem = item;
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
else if (item.Index > startIndex)
{
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Remove Group
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
// Check item is group parent or not
// if group parent, add new gorupinfo
currentSize = groupInfo.GroupSize;
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Wrong! Grid Layouter do not support MeasureAll!
}
ScrollContentSize -= currentSize;
// 2. Update Scroll Content Size
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 3. Update Visible Items.
List<RecyclerViewItem> unrealizedItems = new List<RecyclerViewItem>();
&& (item.Index < startIndex + count))
{
unrealizedItems.Add(item);
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
else if (item.Index >= startIndex + count)
{
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Reorder Single
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
}
}
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// Position Adjust
float scrollPosition = PrevScrollPosition;
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Reorder Groups
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
View nextFocusedView = null;
int targetSibling = -1;
- bool IsHorizontal = colView.ScrollingDirection == ScrollableBase.Direction.Horizontal;
+ bool IsHorizontal = collectionView.ScrollingDirection == ScrollableBase.Direction.Horizontal;
switch (direction)
{
if (targetSibling > -1 && targetSibling < Container.Children.Count)
{
RecyclerViewItem candidate = Container.Children[targetSibling] as RecyclerViewItem;
- if (candidate != null && candidate.Index >= 0 && candidate.Index < colView.InternalItemSource.Count)
+ if (candidate != null && candidate.Index >= 0 && candidate.Index < Source.Count)
{
nextFocusedView = candidate;
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override (int start, int end) FindVisibleItems((float X, float Y) visibleArea)
{
- int MaxIndex = colView.InternalItemSource.Count - 1 - (hasFooter ? 1 : 0);
+ int MaxIndex = Source.Count - 1 - (hasFooter ? 1 : 0);
int adds = spanSize * 2;
int skipGroup = -1;
(int start, int end) found = (0, 0);
return found;
}
- internal override (float X, float Y) GetItemPosition(int index)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal override (float X, float Y) GetItemPosition(int index)
{
float xPos, yPos;
int spaceStartX = Padding.Start;
int spaceStartY = Padding.Top;
int emptyArea = IsHorizontal?
- (int)(colView.Size.Height - Padding.Top - Padding.Bottom - (sizeCandidate.Height * spanSize)) :
- (int)(colView.Size.Width - Padding.Start - Padding.End - (sizeCandidate.Width * spanSize));
+ (int)(collectionView.Size.Height - Padding.Top - Padding.Bottom - (sizeCandidate.Height * spanSize)) :
+ (int)(collectionView.Size.Width - Padding.Start - Padding.End - (sizeCandidate.Width * spanSize));
if (hasHeader && index == 0)
{
return (spaceStartX + headerMargin.Start, spaceStartY + headerMargin.Top);
}
- if (hasFooter && index == colView.InternalItemSource.Count - 1)
+ if (hasFooter && index == Source.Count - 1)
{
xPos = IsHorizontal?
ScrollContentSize - Padding.End - footerSize + footerMargin.Start:
GroupInfo myGroup = GetGroupInfo(index);
if (isGrouped && null != myGroup)
{
- if (colView.InternalItemSource.IsGroupHeader(index))
+ if (Source.IsGroupHeader(index))
{
spaceStartX+= groupHeaderMargin.Start;
spaceStartY+= groupHeaderMargin.Top;
spaceStartY:
myGroup.GroupPosition + groupHeaderMargin.Top;
}
- else if (colView.InternalItemSource.IsGroupFooter(index))
+ else if (Source.IsGroupFooter(index))
{
spaceStartX+= groupFooterMargin.Start;
spaceStartY+= groupFooterMargin.Top;
}
else
{
- int pureIndex = index - myGroup.StartIndex - ((colView.GroupHeaderTemplate != null)? 1: 0);
+ int pureIndex = index - myGroup.StartIndex - ((collectionView.GroupHeaderTemplate != null)? 1: 0);
int division = pureIndex / spanSize;
int remainder = pureIndex % spanSize;
if (division < 0) division = 0;
}
else
{
- int pureIndex = index - (colView.Header ? 1 : 0);
+ int pureIndex = index - (collectionView.Header ? 1 : 0);
// int convert must be truncate value.
int division = pureIndex / spanSize;
int remainder = pureIndex % spanSize;
return (xPos, yPos);
}
- internal override (float Width, float Height) GetItemSize(int index)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal override (float Width, float Height) GetItemSize(int index)
{
return (sizeCandidate.Width - CandidateMargin.Start - CandidateMargin.End,
sizeCandidate.Height - CandidateMargin.Top - CandidateMargin.Bottom);
}
+
private void DelayedRequestLayout(float scrollPosition , bool force = true)
{
if (requestLayoutTimer != null)
requestLayoutTimer.Start();
}
- private RecyclerViewItem GetVisibleItem(int index)
- {
- foreach (RecyclerViewItem item in VisibleItems)
- {
- if (item.Index == index) return item;
- }
-
- return null;
- }
-
private GroupInfo GetGroupInfo(int index)
{
if (Visited != null)
return null;
}
*/
-
- class GroupInfo
- {
- public object GroupParent;
- public int StartIndex;
- public int Count;
- public float GroupSize;
- public float GroupPosition;
- //Items relative position from the GroupPosition
- }
}
}
}
}
+
+ /// <summary>
+ /// Internal item source that organized.
+ /// Check IItemSource and IGrouppedItemSoure also.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected IItemSource Source => ItemsView?.InternalSource;
+
/// <summary>
/// Container which contains ViewItems.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- protected View Container { get; set; }
+ protected View Container =>ItemsView?.ContentContainer;
/// <summary>
/// Parent ItemsView.
protected List<RecyclerViewItem> VisibleItems { get; } = new List<RecyclerViewItem>();
/// <summary>
+ /// Visible ViewItem.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual List<GroupInfo> GroupItems { get; }
+
+ /// <summary>
/// Flag of layouter initialization.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void Initialize(RecyclerView view)
{
ItemsView = view ?? throw new ArgumentNullException(nameof(view));
- Container = view.ContentContainer;
PrevScrollPosition = 0.0f;
IsHorizontal = (view.ScrollingDirection == ScrollableBase.Direction.Horizontal);
{
if (ItemsView != null) Container.Size = ItemsView.Size;
Container.Position = new Position(0.0f, 0.0f);
- Container = null;
}
ItemsView = null;
}
}
}
- internal virtual (float X, float Y) GetItemPosition(int index)
+ /// <summary>
+ /// Get item position.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal virtual (float X, float Y) GetItemPosition(int index)
{
return (0, 0);
}
- internal virtual (float Width, float Height) GetItemSize(int index)
+ /// <summary>
+ /// Get item size.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal virtual (float Width, float Height) GetItemSize(int index)
{
return (0, 0);
}
+
+ /// <summary>
+ /// Get visible item object on index if it is realized.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual RecyclerViewItem GetVisibleItem(int index)
+ {
+
+ foreach (RecyclerViewItem item in VisibleItems)
+ {
+ if (item.Index == index) return item;
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// The data class for group informations.
+ /// inherited class can use this data to managing group items feature.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal class GroupInfo
+ {
+ /// <summary>
+ /// Group parent object.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public object GroupParent;
+
+ /// <summary>
+ /// Group start index.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public int StartIndex;
+
+ /// <summary>
+ /// Group count.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public int Count;
+
+ /// <summary>
+ /// Group size. this value is size of scrollable axis only.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public float GroupSize;
+
+ /// <summary>
+ /// Group position. this value is size of scrollable axis only.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public float GroupPosition;
+
+ /// <summary>
+ /// List of group items position.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public List<float> ItemPosition = new List<float>();
+ }
}
}
private readonly List<float> ItemPosition = new List<float>();
private readonly List<float> ItemSize = new List<float>();
private int ItemSizeChanged = -1;
- private CollectionView colView;
+ private CollectionView collectionView;
private bool hasHeader;
private float headerSize;
private Extents headerMargin;
private Timer requestLayoutTimer = null;
private bool isSourceEmpty;
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected new IGroupableItemSource Source => collectionView?.InternalSource;
+
+ /// <summary>
+ /// Visible ViewItem.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override List<GroupInfo> GroupItems => groups;
+
/// <summary>
/// Clean up ItemsLayouter.
/// </summary>
/// <since_tizen> 9 </since_tizen>
public override void Initialize(RecyclerView view)
{
- colView = view as CollectionView;
- if (colView == null)
+ collectionView = view as CollectionView;
+ if (collectionView == null)
{
throw new ArgumentException("LinearLayouter only can be applied CollectionView.", nameof(view));
}
- // 1. Clean Up
- Clear();
+ // 1. Clean Up
+ foreach (RecyclerViewItem item in VisibleItems)
+ {
+ collectionView.UnrealizeItem(item, false);
+ }
+ VisibleItems.Clear();
+ groups.Clear();
FirstVisible = 0;
LastVisible = 0;
- IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+ IsHorizontal = (collectionView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
- RecyclerViewItem header = colView?.Header;
- RecyclerViewItem footer = colView?.Footer;
+ RecyclerViewItem header = collectionView?.Header;
+ RecyclerViewItem footer = collectionView?.Footer;
float width, height;
- int count = colView.InternalItemSource.Count;
+ int count = Source.Count;
if (header != null)
{
- MeasureChild(colView, header);
+ MeasureChild(collectionView, header);
width = header.Layout != null? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
height = header.Layout != null? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
headerMargin = new Extents(itemMargin);
hasHeader = true;
- colView.UnrealizeItem(header);
+ collectionView.UnrealizeItem(header);
}
else hasHeader = false;
if (footer != null)
{
- MeasureChild(colView, footer);
+ MeasureChild(collectionView, footer);
width = footer.Layout != null? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
height = footer.Layout != null? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
footer.Index = count - 1;
hasFooter = true;
- colView.UnrealizeItem(footer);
+ collectionView.UnrealizeItem(footer);
}
else hasFooter = false;
int firstIndex = hasHeader? 1 : 0;
- if (colView.IsGrouped)
+ if (collectionView.IsGrouped)
{
isGrouped = true;
- if (colView.GroupHeaderTemplate != null)
+ if (collectionView.GroupHeaderTemplate != null)
{
- while (!colView.InternalItemSource.IsGroupHeader(firstIndex)) firstIndex++;
+ while (!Source.IsGroupHeader(firstIndex)) firstIndex++;
//must be always true
- if (colView.InternalItemSource.IsGroupHeader(firstIndex))
+ if (Source.IsGroupHeader(firstIndex))
{
- RecyclerViewItem groupHeader = colView.RealizeItem(firstIndex);
+ RecyclerViewItem groupHeader = collectionView.RealizeItem(firstIndex);
firstIndex++;
if (groupHeader == null) throw new Exception("[" + firstIndex + "] Group Header failed to realize!");
}
else
{
- MeasureChild(colView, groupHeader);
+ MeasureChild(collectionView, groupHeader);
width = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
width + itemMargin.Start + itemMargin.End:
height + itemMargin.Top + itemMargin.Bottom;
groupHeaderMargin = new Extents(itemMargin);
- colView.UnrealizeItem(groupHeader);
+ collectionView.UnrealizeItem(groupHeader);
}
}
else
groupHeaderSize = 0F;
}
- if (colView.GroupFooterTemplate != null)
+ if (collectionView.GroupFooterTemplate != null)
{
int firstFooter = firstIndex;
- while (!colView.InternalItemSource.IsGroupFooter(firstFooter)) firstFooter++;
+ while (!Source.IsGroupFooter(firstFooter)) firstFooter++;
//must be always true
- if (colView.InternalItemSource.IsGroupFooter(firstFooter))
+ if (Source.IsGroupFooter(firstFooter))
{
- RecyclerViewItem groupFooter = colView.RealizeItem(firstFooter);
+ RecyclerViewItem groupFooter = collectionView.RealizeItem(firstFooter);
if (groupFooter == null) throw new Exception("[" + firstFooter + "] Group Footer failed to realize!");
// Need to Set proper height or width on scroll direction.
}
else
{
- MeasureChild(colView, groupFooter);
+ MeasureChild(collectionView, groupFooter);
width = groupFooter.Layout.MeasuredWidth.Size.AsRoundedValue();
height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
width + itemMargin.Start + itemMargin.End:
height + itemMargin.Top + itemMargin.Bottom;
groupFooterMargin = new Extents(itemMargin);
- colView.UnrealizeItem(groupFooter);
+ collectionView.UnrealizeItem(groupFooter);
}
}
else
bool failed = false;
//Final Check of FirstIndex
- while (colView.InternalItemSource.IsHeader(firstIndex) ||
- colView.InternalItemSource.IsGroupHeader(firstIndex) ||
- colView.InternalItemSource.IsGroupFooter(firstIndex))
+ if ((Source.Count - 1 < firstIndex) ||
+ (Source.IsFooter(firstIndex) && (Source.Count - 1) == firstIndex))
{
- if (colView.InternalItemSource.IsFooter(firstIndex)
- || ((colView.InternalItemSource.Count - 1) <= firstIndex))
+ StepCandidate = 0F;
+ failed = true;
+ }
+
+ while (!failed &&
+ Source.IsHeader(firstIndex) ||
+ Source.IsGroupHeader(firstIndex) ||
+ Source.IsGroupFooter(firstIndex))
+ {
+ if (Source.IsFooter(firstIndex)
+ || ((Source.Count - 1) <= firstIndex))
{
StepCandidate = 0F;
failed = true;
if (!failed)
{
- RecyclerViewItem sizeDeligate = colView.RealizeItem(firstIndex);
+ RecyclerViewItem sizeDeligate = collectionView.RealizeItem(firstIndex);
if (sizeDeligate == null)
{
// error !
throw new Exception("Cannot create content from DatTemplate.");
}
- sizeDeligate.BindingContext = colView.InternalItemSource.GetItem(firstIndex);
+ sizeDeligate.BindingContext = Source.GetItem(firstIndex);
// Need to Set proper height or width on scroll direction.
if (sizeDeligate.Layout == null)
}
else
{
- MeasureChild(colView, sizeDeligate);
+ MeasureChild(collectionView, sizeDeligate);
width = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
CandidateMargin = new Extents(itemMargin);
if (StepCandidate == 0) StepCandidate = 1; //????
- colView.UnrealizeItem(sizeDeligate, false);
+ collectionView.UnrealizeItem(sizeDeligate, false);
}
float Current = IsHorizontal? Padding.Start : Padding.Top;
- IGroupableItemSource source = colView.InternalItemSource;
+ IGroupableItemSource source = Source;
GroupInfo currentGroup = null;
object currentParent = null;
for (int i = 0; i < count; i++)
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
if (i == 0 && hasHeader)
ItemSize.Add(headerSize);
GroupSize = currentSize,
GroupPosition = Current
};
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
currentGroup.ItemPosition.Add(0);
groups.Add(currentGroup);
if (source.IsGroupHeader(i)) Current += currentSize;
{
currentGroup.Count++;
currentGroup.GroupSize += groupFooterSize;
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
Current += groupFooterSize;
}
{
currentGroup.Count++;
currentGroup.GroupSize += StepCandidate;
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
Current += StepCandidate;
}
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
ItemPosition.Add(Current);
if (i == 0 && hasHeader) Current += headerSize;
}
ScrollContentSize = Current + (IsHorizontal? Padding.End : Padding.Bottom);
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
base.Initialize(view);
//Console.WriteLine("[NUI] Init Done, StepCnadidate{0}, Scroll{1}", StepCandidate, ScrollContentSize);
force = true;
}
- int LastIndex = colView.InternalItemSource.Count - 1;
+ int LastIndex = Source.Count - 1;
if (!force && PrevScrollPosition == Math.Abs(scrollPosition)) return;
PrevScrollPosition = Math.Abs(scrollPosition);
int prevLastVisible = LastVisible;
(float X, float Y) visibleArea = (PrevScrollPosition,
- PrevScrollPosition + (IsHorizontal? colView.Size.Width : colView.Size.Height)
+ PrevScrollPosition + (IsHorizontal? collectionView.Size.Width : collectionView.Size.Height)
);
// 1. Set First/Last Visible Item Index.
if (item.Index < FirstVisible || item.Index > LastVisible)
{
unrealizedItems.Add(item);
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
}
VisibleItems.RemoveAll(unrealizedItems.Contains);
if (item == null)
{
- item = colView.RealizeItem(i);
+ item = collectionView.RealizeItem(i);
if (item != null) VisibleItems.Add(item);
else throw new Exception("Failed to create RecycerViewItem index of ["+ i + "]");
}
var size = (IsHorizontal? item.SizeWidth: item.SizeHeight);
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureFirst)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureFirst)
{
- if (item.IsHeader || item.IsFooter || item.isGroupHeader || item.isGroupFooter)
+ if (item.IsHeader || item.IsFooter || item.IsGroupHeader || item.IsGroupFooter)
{
if (item.IsHeader) size = headerSize;
else if (item.IsFooter) size = footerSize;
- else if (item.isGroupHeader) size = groupHeaderSize;
- else if (item.isGroupFooter) size = groupFooterSize;
+ else if (item.IsGroupHeader) size = groupHeaderSize;
+ else if (item.IsGroupFooter) size = groupFooterSize;
}
else size = StepCandidate;
}
{
if (item == null)
throw new ArgumentNullException(nameof(item));
- if (colView == null) return;
+ if (collectionView == null) return;
if (!IsInitialized ||
- (colView.SizingStrategy == ItemSizingStrategy.MeasureFirst &&
+ (collectionView.SizingStrategy == ItemSizingStrategy.MeasureFirst &&
item.Index != 0) ||
(item.Index < 0))
return;
float PrevSize, CurrentSize;
- if (item.Index == (colView.InternalItemSource.Count - 1))
+ if (item.Index == (Source.Count - 1))
{
PrevSize = ScrollContentSize - ItemPosition[item.Index];
}
if (CurrentSize != PrevSize)
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
ItemSize[item.Index] = CurrentSize;
else
StepCandidate = CurrentSize;
{
// Insert Single item.
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
- if (isSourceEmpty)
+ if (isSourceEmpty || StepCandidate == 0)
{
- Initialize(colView);
+ Initialize(collectionView);
}
// Will be null if not a group.
// 1. Handle MeasureAll
/*
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need To Implement
}
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
float curPos = groupInfo.ItemPosition[startIndex - groupInfo.StartIndex];
groupInfo.ItemPosition.Insert(startIndex - groupInfo.StartIndex, curPos);
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Need to Implements
}
// 3. Update Scroll Content Size
ScrollContentSize += currentSize;
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
foreach (RecyclerViewItem item in VisibleItems)
LastVisible++;
}
- if (FirstVisible > colView.InternalItemSource.Count - 1) FirstVisible = colView.InternalItemSource.Count -1;
- if (LastVisible > colView.InternalItemSource.Count - 1) LastVisible = colView.InternalItemSource.Count -1;
+ if (FirstVisible > Source.Count - 1) FirstVisible = Source.Count -1;
+ if (LastVisible > Source.Count - 1) LastVisible = Source.Count -1;
float scrollPosition = PrevScrollPosition;
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Insert Group
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
- if (isSourceEmpty)
+ if (isSourceEmpty || StepCandidate == 0)
{
- Initialize(colView);
+ Initialize(collectionView);
}
float currentSize = StepCandidate;
// 1. Handle MeasureAll
/*
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need To Implement
}
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need To Implement
/*
}
// 3. Update Scroll Content Size
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
foreach (RecyclerViewItem item in VisibleItems)
LastVisible = LastVisible + count;
}
- if (FirstVisible > colView.InternalItemSource.Count - 1) FirstVisible = colView.InternalItemSource.Count -1;
- if (LastVisible > colView.InternalItemSource.Count - 1) LastVisible = colView.InternalItemSource.Count -1;
+ if (FirstVisible > Source.Count - 1) FirstVisible = Source.Count -1;
+ if (LastVisible > Source.Count - 1) LastVisible = Source.Count -1;
// Position Adjust
float scrollPosition = PrevScrollPosition;
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Remove Single
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
// 1. Handle MeasureAll
/*
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need To Implement
}
// Remove Group
// groupInfo.Dispose();
groups.Remove(groupInfo);
+ parentIndex--;
}
else
{
groupInfo.Count--;
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need to Implement this.
}
}
else
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Need to Implements
}
ScrollContentSize -= currentSize;
// 3. Update Scroll Content Size
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
RecyclerViewItem targetItem = null;
if (item.Index == startIndex)
{
targetItem = item;
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
else if (item.Index > startIndex)
{
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Remove Group
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
// 1. Handle MeasureAll
/*
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need To Implement
}
// Check item is group parent or not
// if group parent, add new gorupinfo
currentSize = groupInfo.GroupSize;
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
// Update ItemSize and ItemPosition
}
ScrollContentSize -= currentSize;
// 3. Update Scroll Content Size
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// 4. Update Visible Items.
List<RecyclerViewItem> unrealizedItems = new List<RecyclerViewItem>();
&& (item.Index < startIndex + count))
{
unrealizedItems.Add(item);
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
else if (item.Index >= startIndex + count)
{
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Reorder Single
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
// 1. Handle MeasureAll
/*
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//Need To Implement
}
if (FirstVisible < 0) FirstVisible = 0;
if (LastVisible < 0) LastVisible = 0;
- if (FirstVisible > colView.InternalItemSource.Count - 1) FirstVisible = colView.InternalItemSource.Count -1;
- if (LastVisible > colView.InternalItemSource.Count - 1) LastVisible = colView.InternalItemSource.Count -1;
+ if (FirstVisible > Source.Count - 1) FirstVisible = Source.Count -1;
+ if (LastVisible > Source.Count - 1) LastVisible = Source.Count -1;
- if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
- else colView.ContentContainer.SizeHeight = ScrollContentSize;
+ if (IsHorizontal) collectionView.ContentContainer.SizeWidth = ScrollContentSize;
+ else collectionView.ContentContainer.SizeHeight = ScrollContentSize;
// Position Adjust
float scrollPosition = PrevScrollPosition;
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
{
// Reorder Groups
if (source == null) throw new ArgumentNullException(nameof(source));
- if (colView == null) return;
+ if (collectionView == null) return;
// Will be null if not a group.
float currentSize = StepCandidate;
// FIXME!! Unraelize All and reset First/Last Visible
foreach (RecyclerViewItem item in VisibleItems)
{
- colView.UnrealizeItem(item);
+ collectionView.UnrealizeItem(item);
}
VisibleItems.Clear();
FirstVisible = 0;
scrollPosition = GetItemPosition(topInScreenIndex);
scrollPosition -= offset;
- colView.ScrollTo(scrollPosition);
+ collectionView.ScrollTo(scrollPosition);
}
*/
if (source == null) throw new ArgumentNullException(nameof(source));
IGroupableItemSource gSource = source as IGroupableItemSource;
if (gSource == null)throw new Exception("Source is not group!");
- if (colView == null) return;
+ if (collectionView == null) return;
// Get the first Visible Position to adjust.
/*
if (targetSibling > -1 && targetSibling < Container.Children.Count)
{
RecyclerViewItem candidate = Container.Children[targetSibling] as RecyclerViewItem;
- if (candidate != null && candidate.Index >= 0 && candidate.Index < colView.InternalItemSource.Count)
+ if (candidate != null && candidate.Index >= 0 && candidate.Index < Source.Count)
{
nextFocusedView = candidate;
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override (int start, int end) FindVisibleItems((float X, float Y) visibleArea)
{
- int MaxIndex = colView.InternalItemSource.Count - 1 - (hasFooter? 1 : 0);
+ int MaxIndex = Source.Count - 1 - (hasFooter? 1 : 0);
int adds = 5;
int skipGroup = -2;
(int start, int end) found = (0, 0);
return found;
}
- // Item position excluding margins.
- internal override (float X, float Y) GetItemPosition(int index)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal override (float X, float Y) GetItemPosition(int index)
{
int spaceStartX = Padding.Start;
int spaceStartY = Padding.Top;
- if (colView.InternalItemSource.IsHeader(index))
+ if (Source.IsHeader(index))
{
return (spaceStartX + headerMargin.Start, spaceStartY + headerMargin.Top);
}
- else if (colView.InternalItemSource.IsFooter(index))
+ else if (Source.IsFooter(index))
{
return ((IsHorizontal? ScrollContentSize - footerSize - Padding.End + footerMargin.Start : spaceStartX + footerMargin.Start),
(IsHorizontal? spaceStartY + footerMargin.Top : ScrollContentSize - footerSize - Padding.Bottom + footerMargin.Top));
float current = GetGroupPosition(gInfo, index);
Extents itemMargin = CandidateMargin;
- if (colView.InternalItemSource.IsGroupHeader(index))
+ if (Source.IsGroupHeader(index))
{
itemMargin = groupHeaderMargin;
}
- else if (colView.InternalItemSource.IsGroupFooter(index))
+ else if (Source.IsGroupFooter(index))
{
itemMargin = groupFooterMargin;
}
spaceStartY + itemMargin.Top:
itemMargin.Top + GetGroupPosition(gInfo, index)));
}
- else if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ else if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
//FIXME : CandidateMargin need to be actual itemMargin
return ((IsHorizontal? ItemPosition[index] + CandidateMargin.Start : spaceStartX + CandidateMargin.Start),
}
}
- // Item size excluding margins. this size is approximated size.
- internal override (float Width, float Height) GetItemSize(int index)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal override (float Width, float Height) GetItemSize(int index)
{
- if (colView.InternalItemSource.IsHeader(index))
+ if (Source.IsHeader(index))
{
- return ((IsHorizontal? (int)headerSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+ return ((IsHorizontal? (int)headerSize : (int)(collectionView.Size.Width) - Padding.Start - Padding.End)
- headerMargin.Start - headerMargin.End,
- (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)headerSize)
+ (IsHorizontal? (int)collectionView.Size.Height - Padding.Top - Padding.Bottom: (int)headerSize)
- headerMargin.Top - headerMargin.Bottom);
}
- else if (colView.InternalItemSource.IsFooter(index))
+ else if (Source.IsFooter(index))
{
- return ((IsHorizontal? (int)footerSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+ return ((IsHorizontal? (int)footerSize : (int)(collectionView.Size.Width) - Padding.Start - Padding.End)
- footerMargin.Start - footerMargin.End,
- (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)footerSize)
+ (IsHorizontal? (int)collectionView.Size.Height - Padding.Top - Padding.Bottom: (int)footerSize)
- footerMargin.Top - footerMargin.Bottom);
}
- else if (colView.InternalItemSource.IsGroupHeader(index))
+ else if (Source.IsGroupHeader(index))
{
- return ((IsHorizontal? (int)groupHeaderSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+ return ((IsHorizontal? (int)groupHeaderSize : (int)(collectionView.Size.Width) - Padding.Start - Padding.End)
- groupHeaderMargin.Start - groupHeaderMargin.End,
- (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)groupHeaderSize)
+ (IsHorizontal? (int)collectionView.Size.Height - Padding.Top - Padding.Bottom: (int)groupHeaderSize)
- groupHeaderMargin.Top - groupHeaderMargin.Bottom);
}
- else if (colView.InternalItemSource.IsGroupFooter(index))
+ else if (Source.IsGroupFooter(index))
{
- return ((IsHorizontal? (int)groupFooterSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+ return ((IsHorizontal? (int)groupFooterSize : (int)(collectionView.Size.Width) - Padding.Start - Padding.End)
- groupFooterMargin.Start - groupFooterMargin.End,
- (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)groupFooterSize)
+ (IsHorizontal? (int)collectionView.Size.Height - Padding.Top - Padding.Bottom: (int)groupFooterSize)
- groupFooterMargin.Top - groupFooterMargin.Bottom);
}
else
{
- return ((IsHorizontal? (int)StepCandidate : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+ return ((IsHorizontal? (int)StepCandidate : (int)(collectionView.Size.Width) - Padding.Start - Padding.End)
- CandidateMargin.Start - CandidateMargin.End,
- (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)StepCandidate)
+ (IsHorizontal? (int)collectionView.Size.Height - Padding.Top - Padding.Bottom: (int)StepCandidate)
- CandidateMargin.Top - CandidateMargin.Bottom);
}
}
private float GetItemStepSize(int index)
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
{
return ItemSize[index];
}
else
{
- if (colView.InternalItemSource.IsHeader(index))
+ if (Source.IsHeader(index))
return headerSize;
- else if (colView.InternalItemSource.IsFooter(index))
+ else if (Source.IsFooter(index))
return footerSize;
- else if (colView.InternalItemSource.IsGroupHeader(index))
+ else if (Source.IsGroupHeader(index))
return groupHeaderSize;
- else if (colView.InternalItemSource.IsGroupFooter(index))
+ else if (Source.IsGroupFooter(index))
return groupFooterSize;
else
return StepCandidate;
private void UpdatePosition(int index)
{
- bool IsGroup = (colView.InternalItemSource is IGroupableItemSource);
+ bool IsGroup = (Source is IGroupableItemSource);
if (index <= 0) return;
- if (index >= colView.InternalItemSource.Count)
+ if (index >= Source.Count)
if (IsGroup)
{
- //IsGroupHeader = (colView.InternalItemSource as IGroupableItemSource).IsGroupHeader(index);
- //IsGroupFooter = (colView.InternalItemSource as IGroupableItemSource).IsGroupFooter(index);
+ //IsGroupHeader = (Source as IGroupableItemSource).IsGroupHeader(index);
+ //IsGroupFooter = (Source as IGroupableItemSource).IsGroupFooter(index);
//Do Something
}
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
ItemPosition[index] = ItemPosition[index - 1] + GetItemStepSize(index - 1);
}
- private RecyclerViewItem GetVisibleItem(int index)
- {
- foreach (RecyclerViewItem item in VisibleItems)
- {
- if (item.Index == index) return item;
- }
- return null;
- }
-
private GroupInfo GetGroupInfo(int index)
{
if (Visited != null)
private float GetGroupPosition(GroupInfo groupInfo, int index)
{
- if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+ if (collectionView.SizingStrategy == ItemSizingStrategy.MeasureAll)
return groupInfo.GroupPosition + groupInfo.ItemPosition[index - groupInfo.StartIndex];
else
{
return null;
}
*/
- class GroupInfo
- {
- public object GroupParent;
- public int StartIndex;
- public int Count;
- public float GroupSize;
- public float GroupPosition;
- //Items relative position from the GroupPosition. Only use for MeasureAll.
- public List<float> ItemPosition = new List<float>();
- }
}
}
/// <summary>
/// Internal encapsulated items data source.
/// </summary>
- internal IItemSource InternalItemSource { get; set; }
+ internal IItemSource InternalSource { get; set; }
/// <summary>
/// RecycleCache of ViewItem.
/// Realize indexed item.
/// </summary>
/// <param name="index"> Index position of realizing item </param>
- internal virtual RecyclerViewItem RealizeItem(int index)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal virtual RecyclerViewItem RealizeItem(int index)
{
- object context = InternalItemSource.GetItem(index);
+ object context = InternalSource.GetItem(index);
// Check DataTemplate is Same!
if (ItemTemplate is DataTemplateSelector)
{
/// </summary>
/// <param name="item"> Target item for unrealizing </param>
/// <param name="recycle"> Allow recycle. default is true </param>
- internal virtual void UnrealizeItem(RecyclerViewItem item, bool recycle = true)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal virtual void UnrealizeItem(RecyclerViewItem item, bool recycle = true)
{
if (item == null)
{
InternalItemsLayouter = null;
ItemsSource = null;
ItemTemplate = null;
- if (InternalItemSource != null)
+ if (InternalSource != null)
{
- InternalItemSource.Dispose();
- InternalItemSource = null;
+ InternalSource.Dispose();
+ InternalSource = null;
}
//
}
{
item.Index = index;
item.ParentItemsView = this;
- item.Template = (ItemTemplate as DataTemplateSelector)?.SelectDataTemplate(InternalItemSource.GetItem(index), this) ?? ItemTemplate;
+ item.Template = (ItemTemplate as DataTemplateSelector)?.SelectDataTemplate(InternalSource.GetItem(index), this) ?? ItemTemplate;
item.BindingContext = context;
item.Relayout += OnItemRelayout;
}
--- /dev/null
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using Tizen.NUI;
+using Tizen.NUI.Components;
+
+namespace NUITizenGallery
+{
+ internal class AnimalGrid : IExample
+ {
+ private Window window;
+
+ public void Activate()
+ {
+ Console.WriteLine($"@@@ this.GetType().Name={this.GetType().Name}, Activate()");
+
+ window = NUIApplication.GetDefaultWindow();
+ window.GetDefaultNavigator().Push(new AnimalGridPage());
+ }
+ public void Deactivate()
+ {
+ Console.WriteLine($"@@@ this.GetType().Name={this.GetType().Name}, Deactivate()");
+ window.GetDefaultNavigator().Pop();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.ComponentModel;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Components.Extension;
+
+namespace NUITizenGallery
+{
+ public partial class AnimalGridPage : ContentPage
+ {
+ public AnimalGridPage()
+ {
+ InitializeComponent();
+ BindingContext = new Animals();
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+
+ if (type == DisposeTypes.Explicit)
+ {
+ RemoveAllChildren(true);
+ }
+
+ base.Dispose(type);
+ }
+
+ private void RemoveAllChildren(bool dispose = false)
+ {
+ RecursiveRemoveChildren(this, dispose);
+ }
+
+ private void RecursiveRemoveChildren(View parent, bool dispose)
+ {
+ if (parent == null)
+ {
+ return;
+ }
+
+ int maxChild = (int)parent.ChildCount;
+ for (int i = maxChild - 1; i >= 0; --i)
+ {
+ View child = parent.GetChildAt((uint)i);
+ if (child == null)
+ {
+ continue;
+ }
+
+ RecursiveRemoveChildren(child, dispose);
+ parent.Remove(child);
+ if (dispose)
+ {
+ child.Dispose();
+ }
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<ContentPage x:Class="NUITizenGallery.AnimalGridPage"
+ xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ HeightSpecification="{Static LayoutParamPolicies.MatchParent}" >
+
+ <!-- AppBar is top-side bar with navigation content, title, and action. If you not set any contents, back button is automatically added. -->
+ <ContentPage.AppBar>
+ <AppBar x:Name="appBar" Title="AnimalGridPage"/>
+ </ContentPage.AppBar>
+
+ <!-- Content is main placeholder of ContentPage. Add your content into this view. -->
+ <ContentPage.Content>
+ <View x:Name="ContentView"
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ HeightSpecification="{Static LayoutParamPolicies.MatchParent}">
+
+ <View.Layout>
+ <LinearLayout LinearOrientation="Vertical" LinearAlignment="Top" CellPadding="10,10" />
+ </View.Layout>
+
+ <CollectionView x:Name="ColView"
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ HeightSpecification="{Static LayoutParamPolicies.MatchParent}"
+ ScrollingDirection="Vertical"
+ ItemsSource="{Binding Source}"
+ HideScrollbar="true"
+ SelectionMode="SingleAlways"
+ SelectionChangedCommand="{Binding SelectedAnimalChangedCommand}">
+
+ <CollectionView.ItemsLayouter>
+ <GridLayouter />
+ </CollectionView.ItemsLayouter>
+ <CollectionView.ItemTemplate>
+ <DataTemplate>
+ <DefaultGridItem
+ WidthSpecification="230"
+ HeightSpecification="200"
+ Text="{Binding Path=Name}"
+ ResourceUrl="{Binding Path=ImagePath}">
+ <DefaultGridItem.Badge>
+ <CheckBox />
+ </DefaultGridItem.Badge>
+ </DefaultGridItem>
+ </DataTemplate>
+ </CollectionView.ItemTemplate>
+
+
+ </CollectionView>
+ </View>
+ </ContentPage.Content>
+</ContentPage>
--- /dev/null
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using Tizen.NUI;
+using Tizen.NUI.Components;
+
+namespace NUITizenGallery
+{
+ internal class AnimalList : IExample
+ {
+ private Window window;
+
+ public void Activate()
+ {
+ Console.WriteLine($"@@@ this.GetType().Name={this.GetType().Name}, Activate()");
+
+ window = NUIApplication.GetDefaultWindow();
+ window.GetDefaultNavigator().Push(new AnimalListPage());
+ }
+ public void Deactivate()
+ {
+ Console.WriteLine($"@@@ this.GetType().Name={this.GetType().Name}, Deactivate()");
+ window.GetDefaultNavigator().Pop();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.ComponentModel;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Components.Extension;
+
+namespace NUITizenGallery
+{
+ public partial class AnimalListPage : ContentPage
+ {
+ public AnimalListPage()
+ {
+ InitializeComponent();
+ BindingContext = new Animals();
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+
+ if (type == DisposeTypes.Explicit)
+ {
+ RemoveAllChildren(true);
+ }
+
+ base.Dispose(type);
+ }
+
+ private void RemoveAllChildren(bool dispose = false)
+ {
+ RecursiveRemoveChildren(this, dispose);
+ }
+
+ private void RecursiveRemoveChildren(View parent, bool dispose)
+ {
+ if (parent == null)
+ {
+ return;
+ }
+
+ int maxChild = (int)parent.ChildCount;
+ for (int i = maxChild - 1; i >= 0; --i)
+ {
+ View child = parent.GetChildAt((uint)i);
+ if (child == null)
+ {
+ continue;
+ }
+
+ RecursiveRemoveChildren(child, dispose);
+ parent.Remove(child);
+ if (dispose)
+ {
+ child.Dispose();
+ }
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<ContentPage x:Class="NUITizenGallery.AnimalListPage"
+ xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ HeightSpecification="{Static LayoutParamPolicies.MatchParent}" >
+
+ <!-- AppBar is top-side bar with navigation content, title, and action. If you not set any contents, back button is automatically added. -->
+ <ContentPage.AppBar>
+ <AppBar x:Name="appBar" Title="AnimalListPage"/>
+ </ContentPage.AppBar>
+
+ <!-- Content is main placeholder of ContentPage. Add your content into this view. -->
+ <ContentPage.Content>
+ <View x:Name="ContentView"
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ HeightSpecification="{Static LayoutParamPolicies.MatchParent}">
+
+ <View.Layout>
+ <LinearLayout LinearOrientation="Vertical" LinearAlignment="Top" CellPadding="10,10" />
+ </View.Layout>
+
+ <CollectionView x:Name="ColView"
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ HeightSpecification="{Static LayoutParamPolicies.MatchParent}"
+ ScrollingDirection="Vertical"
+ ItemsSource="{Binding Source}"
+ HideScrollbar="true"
+ SelectionMode="Single"
+ SelectionChangedCommand="{Binding SelectedAnimalChangedCommand}">
+
+ <CollectionView.ItemsLayouter>
+ <LinearLayouter />
+ </CollectionView.ItemsLayouter>
+ <CollectionView.ItemTemplate>
+ <DataTemplate>
+ <DefaultLinearItem
+ WidthSpecification="{Static LayoutParamPolicies.MatchParent}"
+ Text="{Binding Path=Name}"
+ SubText="{Binding Path=ScientificName}">
+ <DefaultLinearItem.Icon>
+ <ImageView
+ WidthSpecification="70"
+ HeightSpecification="50"
+ ResourceUrl="{Binding Path=ImagePath}" />
+ </DefaultLinearItem.Icon>
+ <DefaultLinearItem.Extra>
+ <CheckBox />
+ </DefaultLinearItem.Extra>
+ </DefaultLinearItem>
+ </DataTemplate>
+ </CollectionView.ItemTemplate>
+
+
+ </CollectionView>
+ </View>
+ </ContentPage.Content>
+</ContentPage>
--- /dev/null
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using Tizen.NUI;
+using Tizen.NUI.Components;
+using Tizen.NUI.Binding;
+
+public class Animal : INotifyPropertyChanged
+{
+ private string _name;
+ private string _scientificName;
+ private string _imageUrl = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "/images/animals/";
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void OnPropertyChanged([CallerMemberName] string propertyName="") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
+
+
+ public Animal(string name, string scientificName)
+ {
+ _name = name;
+ _scientificName = scientificName;
+ }
+
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ _name = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public string ScientificName
+ {
+ get => _scientificName;
+ set
+ {
+ _scientificName = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public string ImagePath
+ {
+ get
+ {
+ string filename = _name.Replace(" ", "");
+ filename = filename.ToLower() + ".jpg";
+ return _imageUrl + filename;
+ }
+ }
+}
+
+
+public class Animals : INotifyPropertyChanged
+{
+ (string Name,string ScientificName)[] namePool = {
+ ("Bald Eagle", "Haliaeetus leucocephalus"),
+ ("Bear", "Ursidae"),
+ ("Cat", "Felis catus"),
+ ("Chicken", "Gallus gallus domesticus"),
+ ("Cow", "Bos taurus"),
+ ("Deer", "Cervidae"),
+ ("Dog", "Canis lupus familiaris"),
+ ("Duck", "Anatidae"),
+ ("Elephant", "Elephantidae"),
+ ("Emperor Penguin", "Aptenodytes forsteri"),
+ ("Giraffe", "Giraffa"),
+ ("Horse", "Equus ferus"),
+ ("Leopard", "Panthera pardus"),
+ ("Lion", "Panthera leo"),
+ ("Panda", "Ailuropoda melanoleuca"),
+ ("Peacock", "Pavo cristatus"),
+ ("Pig", "Sus scrofa domesticus"),
+ ("Pigeon", "Columba livia"),
+ ("Red Fox", "Vulpes vulpes"),
+ ("Seagull", "Larus canus"),
+ ("Squirrel", "Sciurus vulgaris"),
+ ("Tiger", "Panthera tigris"),
+ ("Wolf", "Canis lupus"),
+ ("Zebra", "Hippotigris"),
+ };
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void OnPropertyChanged([CallerMemberName] string propertyName="") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
+
+ public ObservableCollection<Animal> Source {get; private set; } = new ObservableCollection<Animal>();
+
+ public Animals()
+ {
+ for (int i = 0; i < namePool.Length; i++)
+ Source.Add(new Animal(namePool[i].Name, namePool[i].ScientificName));
+
+ SelectedAnimalChangedCommand = new Command<SelectionChangedEventArgs>((param) =>
+ {
+ if (param == null) return;
+
+ Animal animal = null;
+ // Single Selection Only have 1 or nil object in the list.
+ foreach (object item in param.PreviousSelection)
+ {
+ animal = item as Animal;
+ if (animal == null) break;
+
+ Console.WriteLine($"Previous selected item {animal.Name}");
+ }
+ foreach (object item in param.CurrentSelection)
+ {
+ animal = item as Animal;
+ if (animal == null) break;
+
+ Console.WriteLine($"Current selected item {animal.Name}");
+ } });
+ }
+
+ public Command<SelectionChangedEventArgs> SelectedAnimalChangedCommand { get; }
+}
</ItemGroup>
<PropertyGroup>
- <XamlOptimization>2</XamlOptimization>
+ <XamlOptimization>1</XamlOptimization>
</PropertyGroup>
<ImportGroup>