From f246475920275ed4885360aae82f42a6d8e26526 Mon Sep 17 00:00:00 2001
From: yang zhou <17793881+xtuzy@users.noreply.github.com>
Date: Thu, 14 Sep 2023 21:36:26 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86=E5=92=8C=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E4=BA=86=E4=B8=80=E4=BA=9B=E6=96=B9=E6=B3=95=E5=90=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
DemoTest/Pages/DefaultTestPage.xaml.cs | 2 +-
.../Layouts/CollectionViewFlatListLayout.cs | 136 +++++----
.../Layouts/CollectionViewGridLayout.cs | 271 +++++-------------
.../CollectionViewLayout.LayoutInfor.cs | 24 ++
.../Layouts/CollectionViewLayout.cs | 70 ++---
MauiUICollectionView/MAUICollectionView.cs | 16 +-
6 files changed, 208 insertions(+), 311 deletions(-)
create mode 100644 MauiUICollectionView/Layouts/CollectionViewLayout.LayoutInfor.cs
diff --git a/DemoTest/Pages/DefaultTestPage.xaml.cs b/DemoTest/Pages/DefaultTestPage.xaml.cs
index a2644db..2373de5 100644
--- a/DemoTest/Pages/DefaultTestPage.xaml.cs
+++ b/DemoTest/Pages/DefaultTestPage.xaml.cs
@@ -35,7 +35,7 @@ public DefaultTestPage()
VerticalScrollBarVisibility = ScrollBarVisibility.Always,
HeightExpansionFactor = OperatingSystem.IsIOS()? 0:0,
SelectionMode = SelectionMode.Multiple,
- CanDrag = true,
+ //CanDrag = true,
};
tableView.ItemsLayout = new CollectionViewFlatListLayout(tableView)
{
diff --git a/MauiUICollectionView/Layouts/CollectionViewFlatListLayout.cs b/MauiUICollectionView/Layouts/CollectionViewFlatListLayout.cs
index a03aeb5..47b6b7c 100644
--- a/MauiUICollectionView/Layouts/CollectionViewFlatListLayout.cs
+++ b/MauiUICollectionView/Layouts/CollectionViewFlatListLayout.cs
@@ -28,16 +28,16 @@ protected override double MeasureItems(double top, Rect inRect, Rect visibleRect
isScrollingTo == false &&
!HasOperation)
{
- //MeasureItemsWhenScroll(inRect, availablePreparedItems);
- MeasureItems(top, inRect, availablePreparedItems, false);
+ Fill(inRect, AnalysisBaseline(top), availablePreparedItems, false);
}
else
{
- MeasureItems(top, inRect, availablePreparedItems);
+ Fill(inRect, AnalysisBaseline(top), availablePreparedItems, true);
+
if (isScrollingTo)
isScrollingTo = false;
- if (BaseLineItemUsually != null)
- BaseLineItemUsually = null;
+ if (ItemLayoutBaseline != null)
+ ItemLayoutBaseline = null;
}
// store some bounds
@@ -90,22 +90,20 @@ protected override double MeasureItems(double top, Rect inRect, Rect visibleRect
///
/// When not touch scrolling, we use it to remeasure all prepared items.
///
- ///
///
- ///
- protected virtual void MeasureItems(double top, Rect inRect, Dictionary availablePreparedItems, bool isRemeasureAll = true)
+ protected virtual LayoutInfor AnalysisBaseline(double top)
{
- if (BaseLineItemUsually != null)// use specify baseline to layout
+ if (ItemLayoutBaseline != null)// use specify baseline to layout
{
- OnLayoutChildren(inRect, BaseLineItemUsually.Copy(), availablePreparedItems, isRemeasureAll);
+ return ItemLayoutBaseline.Copy();
}
else if (OldPreparedItems.StartItem != null)// use last layout item as baseline to layout
{
- OnLayoutChildren(inRect, new LayoutInfor()
+ return new LayoutInfor()
{
StartItem = OldPreparedItems.StartItem,
StartBounds = OldPreparedItems.StartBounds
- }, availablePreparedItems, isRemeasureAll);
+ };
}
else //use header's bottom as baseline to layout, this will be called when start a new collectionview or error(because fast scroll, scrollto, drag scrollbar)
{
@@ -118,31 +116,30 @@ protected virtual void MeasureItems(double top, Rect inRect, Dictionary
- /// Estimate the item displayed when scrolling to a certain position.
- ///
- ///
- ///
- protected virtual NSIndexPath EstimateItem(double x, double y)
- {
- var firstItemBounds = StartBoundsCache.First();
- double averageHeight = EstimateAverageHeight();
-
- var numberOfSections = CollectionView.NumberOfSections();
- double allHeight = 0;
- for (var section = 0; section < numberOfSections; section++)
- {
- var rowsInSection = CollectionView.NumberOfItemsInSection(section);
- if (y - firstItemBounds.Top < allHeight + rowsInSection * averageHeight)
- {
- return NSIndexPath.FromRowSection((int)((y - firstItemBounds.Top - allHeight) / averageHeight), section);
- }
- else
- {
- allHeight += rowsInSection * averageHeight;
- }
- }
- //maybe scrolly is very big
- return NSIndexPath.FromRowSection(CollectionView.NumberOfItemsInSection(numberOfSections - 1), numberOfSections - 1);
- }
-
///
/// Arrange items from above or below to fill a given rectangle.
///
@@ -190,7 +159,7 @@ protected virtual NSIndexPath EstimateItem(double x, double y)
/// according to it to layout other items
///
///
- protected virtual void OnLayoutChildren(Rect inRect, LayoutInfor baselineInfor, Dictionary availableCells, bool isRemeasureAll = true)
+ protected virtual void Fill(Rect inRect, LayoutInfor baselineInfor, Dictionary availableCells, bool isRemeasureAll = true)
{
/*
* from top to bottom, means we have a top value of item, we base on it to calculate bounds of items below.
@@ -393,7 +362,7 @@ protected virtual void ScrollToItem(NSIndexPath targetIndexPath)
if (targetIndexPath > lastPreparedItem.Key)//The target item is at the bottom of the visible area, laid out from the bottom up.
{
itemsOffset += CollectionView.ItemCountInRange(lastPreparedItem.Key, targetIndexPath) * lastPreparedItem.Value.ItemBounds.Height;
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
EndBounds = new Rect(0, 0, 0, CollectionView.ScrollY + itemsOffset + CollectionView.Bounds.Height), //set this item at bottom of visible area.
EndItem = targetIndexPath
@@ -406,7 +375,7 @@ protected virtual void ScrollToItem(NSIndexPath targetIndexPath)
var itemsCountFromTargetToFirstPrepared = CollectionView.ItemCountInRange(targetIndexPath, firstPreparedItem.Key) + 1;
var itemsCountFromFirstToFirstPrepared = CollectionView.ItemCountInRange(NSIndexPath.FromRowSection(0, 0), firstPreparedItem.Key) + 1;
var distanceFromTargetToFirstPrepared = (firstPreparedItem.Value.ItemBounds.Top - StartBoundsCache[0].Top) * itemsCountFromTargetToFirstPrepared / itemsCountFromFirstToFirstPrepared + (CollectionView.ScrollY - firstPreparedItem.Value.ItemBounds.Top);
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
StartBounds = new Rect(0, CollectionView.ScrollY - distanceFromTargetToFirstPrepared, 0, 0),
StartItem = targetIndexPath
@@ -476,7 +445,7 @@ void FitBoundsWhenCloseHeader(LayoutInfor visibleItems)
var targetBounds = StartBoundsCache[visibleFirst.Row];
if (CollectionView.PreparedItems[visibleFirst].ItemBounds != targetBounds)
{
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
StartBounds = new Rect(0, targetBounds.Top, 0, 0),
StartItem = visibleFirst
@@ -489,7 +458,7 @@ void FitBoundsWhenCloseHeader(LayoutInfor visibleItems)
{
var targetTop = CollectionView.PreparedItems[visibleFirst].ItemBounds.Bottom + CollectionView.ItemCountInRange(lastCache, visibleFirst) * EstimateAverageHeight();
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
StartBounds = new Rect(0, targetTop, 0, 0),
StartItem = visibleFirst
@@ -508,7 +477,7 @@ void FitBoundsWhenCloseHeader(LayoutInfor visibleItems)
if (firstItemRect.Top > StartBoundsCache[0].Top && //There is space
CollectionView.ScrollY < (firstItemRect.Bottom - firstItemRect.Height * 4 / 5))//when close to first item top
{
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
StartBounds = new Rect(0, StartBoundsCache[0].Top, 0, 0),
StartItem = firstItem
@@ -594,6 +563,57 @@ public override Rect RectForItem(NSIndexPath indexPath)
return rect;
}
+ #region ItemAtPoint
+
+ public override NSIndexPath ItemAtPoint(Point point, bool baseOnContent = true)
+ {
+ if (!baseOnContent)
+ {
+ var contentOffset = CollectionView.ScrollY;
+ point.Y = point.Y + contentOffset;//convert to base on content
+ }
+
+ foreach (var item in CollectionView.PreparedItems)
+ {
+ if (item.Value.ItemBounds.Contains(point))
+ {
+ return item.Key;
+ }
+ }
+
+ return EstimateItem(point.X, point.Y);
+ }
+
+ ///
+ /// Estimate the item displayed when scrolling to a certain position.
+ ///
+ ///
+ ///
+ NSIndexPath EstimateItem(double x, double y)
+ {
+ var firstItemBounds = StartBoundsCache.First();
+ double averageHeight = EstimateAverageHeight();
+
+ var numberOfSections = CollectionView.NumberOfSections();
+ double allHeight = 0;
+ for (var section = 0; section < numberOfSections; section++)
+ {
+ var rowsInSection = CollectionView.NumberOfItemsInSection(section);
+ if (y - firstItemBounds.Top < allHeight + rowsInSection * averageHeight)
+ {
+ return NSIndexPath.FromRowSection((int)((y - firstItemBounds.Top - allHeight) / averageHeight), section);
+ }
+ else
+ {
+ allHeight += rowsInSection * averageHeight;
+ }
+ }
+ //maybe scrolly is very big
+ return NSIndexPath.FromRowSection(CollectionView.NumberOfItemsInSection(numberOfSections - 1), numberOfSections - 1);
+ }
+
+ #endregion
+
#endregion
}
}
diff --git a/MauiUICollectionView/Layouts/CollectionViewGridLayout.cs b/MauiUICollectionView/Layouts/CollectionViewGridLayout.cs
index 3f6453a..b775725 100644
--- a/MauiUICollectionView/Layouts/CollectionViewGridLayout.cs
+++ b/MauiUICollectionView/Layouts/CollectionViewGridLayout.cs
@@ -14,100 +14,11 @@ public CollectionViewGridLayout(MAUICollectionView collectionView) : base(collec
///
public int ColumnCount { get; set; } = 2;
- ///
- /// The default height to apply to all items
- ///
- public Size AspectRatio { get; set; } = new Size(1, 1);
-
protected override double MeasureItems(double top, Rect inRect, Rect visibleRect, Dictionary availablePreparedItems)
{
- double measureItem(NSIndexPath indexPath, Rect itemRect, bool unknowItemHeight)
- {
- //如果在可见区域, 就详细测量
- if (itemRect.IntersectsWith(inRect))
- {
- //获取Cell, 优先获取之前已经被显示的, 这里假定已显示的数据没有变化
- MAUICollectionViewViewHolder cell = null;
- if (availablePreparedItems.ContainsKey(indexPath))
- {
- cell = availablePreparedItems[indexPath];
- availablePreparedItems.Remove(indexPath);
- if (CollectionView.IsScrolling && !HasOperation)
- {
- //return cell.BoundsInLayout.Height;
- }
- }
- cell = CollectionView.Source.ViewHolderForItem(CollectionView, indexPath, cell, inRect.Width);
-
- if (cell != null)
- {
- //将Cell添加到正在显示的Cell字典
- CollectionView.PreparedItems.Add(indexPath, cell);
-
- //添加到ScrollView, 必须先添加才有测量值
- if (!CollectionView.ContentView.Children.Contains(cell))
- CollectionView.AddSubview(cell);
- //测量高度
- cell.WidthRequest = itemRect.Width;
- cell.HeightRequest = unknowItemHeight ? -1 : itemRect.Height;
- var measureSize = cell.MeasureSelf(itemRect.Width, unknowItemHeight ? double.PositiveInfinity : itemRect.Height).Request;
- var bounds = new Rect(itemRect.X, itemRect.Y, measureSize.Width, measureSize.Height);
-
- if (cell.Operation == (int)OperateItem.OperateType.Move && // move
- HasOperation && // anim
- bounds != cell.ItemBounds) // diff bounds
- {
- cell.OldItemBounds = cell.ItemBounds;
- cell.ItemBounds = bounds;
- }
- else
- {
- if (cell.Operation == (int)OperateItem.OperateType.Move &&
- HasOperation)
- cell.OldItemBounds = Rect.Zero;
- cell.ItemBounds = bounds;
- }
-
- //here have a chance to change appearance of this item
- CollectionView.Source?.DidPrepareItem?.Invoke(CollectionView, indexPath, cell, Edge.Top | Edge.Left);
-
- cell.IndexPath = indexPath;
-
- return cell.ItemBounds.Height;
- }
- else
- {
- throw new NotImplementedException($"Get ViewHolder is null of {indexPath} from {nameof(MAUICollectionViewSource.ViewHolderForItem)}.");
- }
- }
- else// if don't in prepared rect
- {
- if (availablePreparedItems.ContainsKey(indexPath))//we want store bounds info for invisible item, because maybe we need it to make animation
- {
- var cell = availablePreparedItems[indexPath];
-
- if (cell.Operation == (int)OperateItem.OperateType.Move
- && HasOperation
- && itemRect != cell.ItemBounds)//move + anim + diff bounds
- {
- cell.OldItemBounds = cell.ItemBounds;//move operate need old position to make animation
- cell.ItemBounds = itemRect;
- }
- else
- {
- cell.ItemBounds = itemRect;
- }
- }
-
- return itemRect.Height;
- }
- }
-
base.MeasureItems(top, inRect, visibleRect, availablePreparedItems);
double itemsHeight = 0;
- var itemWidth = inRect.Width / ColumnCount;
- var itemHeight = itemWidth * AspectRatio.Height / AspectRatio.Width;
int numberOfSections = CollectionView.NumberOfSections();
//根据已知的最后一个Item来估计总高度
@@ -178,74 +89,7 @@ protected override double EstimateAverageHeight()
return totalH / StartBoundsCache.Count;
}
- protected override NSIndexPath EstimateItem(double x, double y)
- {
- var firstItemBounds = StartBoundsCache.First();
- double averageHeight = EstimateAverageHeight();
-
- var numberOfSections = CollectionView.NumberOfSections();
- double allHeight = 0;
- for (var section = 0; section < numberOfSections; section++)
- {
- double headerH = 0;
- var firstItem = NSIndexPath.FromRowSection(0, section);
- var firstItemRowColumn = GetRowAndColumnOfItem(firstItem);
- if (firstItemRowColumn.row == -1)// is header
- {
- var wantH = CollectionView.Source.HeightForItem(CollectionView, firstItem);
- if (wantH == MAUICollectionViewViewHolder.AutoSize)
- headerH = averageHeight;
- else
- headerH = wantH;
- // in header item
- if (y - firstItemBounds.Top < allHeight + headerH)
- {
- return NSIndexPath.FromRowSection(0, section);
- }
- }
- var indexCountInSection = CollectionView.NumberOfItemsInSection(section);
- int rowOfLastDataItem = 0;
- var lastItem = NSIndexPath.FromRowSection(indexCountInSection - 1, section);
- var lastItemRowColumn = GetRowAndColumnOfItem(lastItem);
- if (lastItemRowColumn.row == -2)
- {
- rowOfLastDataItem = GetRowAndColumnOfItem(NSIndexPath.FromRowSection(indexCountInSection - 1, section)).row;
- }
- else
- {
- rowOfLastDataItem = lastItemRowColumn.row;
- }
-
- // in data items
- if (y - firstItemBounds.Top < allHeight + headerH + rowOfLastDataItem * averageHeight)
- {
- var firstItemIndexAtTargetRow = (int)((y - firstItemBounds.Top - allHeight - headerH) / averageHeight) * ColumnCount;
- var column = (int)( x / (CollectionView.ContentSize.Width / ColumnCount));
- return NSIndexPath.FromRowSection(firstItemIndexAtTargetRow + column, section);
- }
-
- double footerH = 0;
- if (lastItemRowColumn.row == -2)
- {
- var wantH = CollectionView.Source.HeightForItem(CollectionView, lastItem);
- if (wantH == MAUICollectionViewViewHolder.AutoSize)
- footerH = averageHeight;
- else
- footerH = wantH;
- // in footer item
- if (y - firstItemBounds.Top < allHeight + headerH + rowOfLastDataItem * averageHeight + footerH)
- {
- return NSIndexPath.FromRowSection(indexCountInSection - 1, section);
- }
- }
-
- allHeight += headerH + rowOfLastDataItem * averageHeight + footerH;
- }
- //maybe scrolly is very big
- return NSIndexPath.FromRowSection(CollectionView.NumberOfItemsInSection(numberOfSections - 1), numberOfSections - 1);
- }
-
- protected override void OnLayoutChildren(Rect inRect, LayoutInfor baselineInfor, Dictionary availableCells, bool isRemeasureAll = true)
+ protected override void Fill(Rect inRect, LayoutInfor baselineInfor, Dictionary availableCells, bool isRemeasureAll = true)
{
void LayoutFromTopToBottom(LayoutInfor topBaselineInfor)
{
@@ -387,55 +231,96 @@ void LayoutFromBottomToTop(LayoutInfor bottomBaselineInfor)
}
}
- ///
- /// ViewHolder分成几列时, 判断下一个分在哪一列, header或者footer返回-1, 其它基于0递增.
- ///
- ///
- ///
- ///
- ///
- int NextItemColumn(bool front, double singleColumnWidth, Rect currentBounds, NSIndexPath nextItem)
+ #region ItemAtPoint
+
+ public override NSIndexPath ItemAtPoint(Point point, bool baseOnContent = true)
{
- if (CollectionView.Source.IsSectionItem(CollectionView, nextItem))
+ if (!baseOnContent)
{
- return -1;
+ var contentOffset = CollectionView.ScrollY;
+ point.Y = point.Y + contentOffset;//convert to base on content
}
- else
+
+ foreach (var item in CollectionView.PreparedItems)
{
- //判断当前在哪一列
- var currentColumn = (int)(currentBounds.Center.X / singleColumnWidth);
- if (front)
- {
- if (currentColumn == 0)
- return ColumnCount - 1;
- else
- return currentColumn - 1;
- }
- else
+ if (item.Value.ItemBounds.Contains(point))
{
- if (currentColumn == (ColumnCount - 1))
- return 0;
- else
- return currentColumn + 1;
+ return item.Key;
}
}
+
+ return EstimateItem(point.X, point.Y);
}
- public override NSIndexPath ItemAtPoint(Point point, bool baseOnContent = true)
+ NSIndexPath EstimateItem(double x, double y)
{
- var visibleIndexPath = base.ItemAtPoint(point, baseOnContent);
- if (visibleIndexPath != null)
- return visibleIndexPath;
+ var firstItemBounds = StartBoundsCache.First();
+ double averageHeight = EstimateAverageHeight();
- if (!baseOnContent)
+ var numberOfSections = CollectionView.NumberOfSections();
+ double allHeight = 0;
+ for (var section = 0; section < numberOfSections; section++)
{
- var contentOffset = CollectionView.ScrollY;
- point.Y = point.Y + contentOffset;//convert to base on content
- }
+ double headerH = 0;
+ var firstItem = NSIndexPath.FromRowSection(0, section);
+ var firstItemRowColumn = GetRowAndColumnOfItem(firstItem);
+ if (firstItemRowColumn.row == -1)// is header
+ {
+ var wantH = CollectionView.Source.HeightForItem(CollectionView, firstItem);
+ if (wantH == MAUICollectionViewViewHolder.AutoSize)
+ headerH = averageHeight;
+ else
+ headerH = wantH;
+ // in header item
+ if (y - firstItemBounds.Top < allHeight + headerH)
+ {
+ return NSIndexPath.FromRowSection(0, section);
+ }
+ }
+ var indexCountInSection = CollectionView.NumberOfItemsInSection(section);
+ int rowOfLastDataItem = 0;
+ var lastItem = NSIndexPath.FromRowSection(indexCountInSection - 1, section);
+ var lastItemRowColumn = GetRowAndColumnOfItem(lastItem);
+ if (lastItemRowColumn.row == -2)
+ {
+ rowOfLastDataItem = GetRowAndColumnOfItem(NSIndexPath.FromRowSection(indexCountInSection - 1, section)).row;
+ }
+ else
+ {
+ rowOfLastDataItem = lastItemRowColumn.row;
+ }
- return EstimateItem(point.X, point.Y);
+ // in data items
+ if (y - firstItemBounds.Top < allHeight + headerH + rowOfLastDataItem * averageHeight)
+ {
+ var firstItemIndexAtTargetRow = (int)((y - firstItemBounds.Top - allHeight - headerH) / averageHeight) * ColumnCount;
+ var column = (int)(x / (CollectionView.ContentSize.Width / ColumnCount));
+ return NSIndexPath.FromRowSection(firstItemIndexAtTargetRow + column, section);
+ }
+
+ double footerH = 0;
+ if (lastItemRowColumn.row == -2)
+ {
+ var wantH = CollectionView.Source.HeightForItem(CollectionView, lastItem);
+ if (wantH == MAUICollectionViewViewHolder.AutoSize)
+ footerH = averageHeight;
+ else
+ footerH = wantH;
+ // in footer item
+ if (y - firstItemBounds.Top < allHeight + headerH + rowOfLastDataItem * averageHeight + footerH)
+ {
+ return NSIndexPath.FromRowSection(indexCountInSection - 1, section);
+ }
+ }
+
+ allHeight += headerH + rowOfLastDataItem * averageHeight + footerH;
+ }
+ //maybe scrolly is very big
+ return NSIndexPath.FromRowSection(CollectionView.NumberOfItemsInSection(numberOfSections - 1), numberOfSections - 1);
}
+ #endregion
+
public override Rect RectForItem(NSIndexPath indexPath)
{
if (CollectionView.PreparedItems.ContainsKey(indexPath))
@@ -488,7 +373,7 @@ protected override void ScrollToItem(NSIndexPath targetIndexPath)
{
itemsOffset += CollectionView.ItemCountInRange(lastPreparedItem.Key, targetIndexPath) / ColumnCount * EstimateAverageHeight();
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
EndBounds = new Rect(0, 0, 0, lastPreparedItem.Value.ItemBounds.Bottom + itemsOffset + CollectionView.Bounds.Height),
EndItem = targetIndexPath
@@ -501,7 +386,7 @@ protected override void ScrollToItem(NSIndexPath targetIndexPath)
var rowCountFromTargetToFirstPrepared = (CollectionView.ItemCountInRange(targetIndexPath, firstPreparedItem.Key) + 1) / ColumnCount;
var rowCountFromFirstToFirstPrepared = (CollectionView.ItemCountInRange(NSIndexPath.FromRowSection(0, 0), firstPreparedItem.Key) + 1) / ColumnCount;
var distanceFromTargetToFirstPrepared = (firstPreparedItem.Value.ItemBounds.Top - StartBoundsCache[0].Top) * rowCountFromTargetToFirstPrepared / rowCountFromFirstToFirstPrepared + (CollectionView.ScrollY - firstPreparedItem.Value.ItemBounds.Top);
- BaseLineItemUsually = new LayoutInfor()
+ ItemLayoutBaseline = new LayoutInfor()
{
StartBounds = new Rect(0, CollectionView.ScrollY - distanceFromTargetToFirstPrepared, 0, 0),
StartItem = targetIndexPath
diff --git a/MauiUICollectionView/Layouts/CollectionViewLayout.LayoutInfor.cs b/MauiUICollectionView/Layouts/CollectionViewLayout.LayoutInfor.cs
new file mode 100644
index 0000000..0cbd03e
--- /dev/null
+++ b/MauiUICollectionView/Layouts/CollectionViewLayout.LayoutInfor.cs
@@ -0,0 +1,24 @@
+namespace MauiUICollectionView.Layouts
+{
+ public abstract partial class CollectionViewLayout
+ {
+ public class LayoutInfor
+ {
+ public NSIndexPath StartItem;
+ public NSIndexPath EndItem;
+ public Rect StartBounds;
+ public Rect EndBounds;
+
+ public LayoutInfor Copy()
+ {
+ return new LayoutInfor()
+ {
+ StartItem = this.StartItem,
+ EndItem = this.EndItem,
+ StartBounds = this.StartBounds,
+ EndBounds = this.EndBounds
+ };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MauiUICollectionView/Layouts/CollectionViewLayout.cs b/MauiUICollectionView/Layouts/CollectionViewLayout.cs
index c33d66f..b99b250 100644
--- a/MauiUICollectionView/Layouts/CollectionViewLayout.cs
+++ b/MauiUICollectionView/Layouts/CollectionViewLayout.cs
@@ -6,7 +6,7 @@ namespace MauiUICollectionView.Layouts
///
/// layout content.
///
- public abstract class CollectionViewLayout : IDisposable
+ public abstract partial class CollectionViewLayout : IDisposable
{
public CollectionViewLayout(MAUICollectionView collectionView)
{
@@ -45,7 +45,23 @@ public ItemsLayoutOrientation ScrollDirection
///
protected bool HasOperation = false;
- public bool RunOperateAnimation = false;
+ ///
+ /// it start equal to true when equal to, but it be false after start operation animation.
+ ///
+ protected bool RunOperateAnimation = false;
+
+ ///
+ /// it contain information about item and bounds, we layout item according to it. it's IndexPath is latest.
+ ///
+ public LayoutInfor ItemLayoutBaseline;
+
+ ///
+ /// current Visible items, it is different with
+ ///
+ public LayoutInfor VisibleIndexPath { get; protected set; }
+ public LayoutInfor LastVisibleIndexPath { get; protected set; }
+
+ public LayoutInfor OldPreparedItems;
///
/// Arrange Header, Items and Footer. They will be arranged according to
@@ -91,32 +107,6 @@ public virtual void ArrangeContents()
}
}
- public LayoutInfor OldPreparedItems;
-
- public class LayoutInfor
- {
- public NSIndexPath StartItem;
- public NSIndexPath EndItem;
- public Rect StartBounds;
- public Rect EndBounds;
-
- public LayoutInfor Copy()
- {
- return new LayoutInfor()
- {
- StartItem = this.StartItem,
- EndItem = this.EndItem,
- StartBounds = this.StartBounds,
- EndBounds = this.EndBounds
- };
- }
- }
-
- ///
- /// it contain information about item and bounds, we layout item according to it. it's IndexPath is latest.
- ///
- public LayoutInfor BaseLineItemUsually;
-
///
/// Measure size of Header, Items and Footer. It will load , , .
///
@@ -402,12 +392,6 @@ protected virtual double MeasureHeader(double top, double widthConstraint)
return 0;
}
- ///
- /// current Visible items, it is different with
- ///
- public LayoutInfor VisibleIndexPath { get; protected set; }
- public LayoutInfor LastVisibleIndexPath { get; protected set; }
-
///
/// Measure items to fill target rect.
///
@@ -439,23 +423,7 @@ protected virtual double MeasureFooter(double top, double widthConstraint)
/// the point in Content or CollectionView
/// specify point is base on Content or CollectionView
///
- public virtual NSIndexPath ItemAtPoint(Point point, bool baseOnContent = true)
- {
- if (!baseOnContent)
- {
- var contentOffset = CollectionView.ScrollY;
- point.Y = point.Y + contentOffset;//convert to base on content
- }
-
- foreach (var item in CollectionView.PreparedItems)
- {
- if (item.Value.ItemBounds.Contains(point))
- {
- return item.Key;
- }
- }
- return null;
- }
+ public abstract NSIndexPath ItemAtPoint(Point point, bool baseOnContent = true);
///
/// Get of item. If it in , will return bounds, if not, return .
diff --git a/MauiUICollectionView/MAUICollectionView.cs b/MauiUICollectionView/MAUICollectionView.cs
index 4770073..1069805 100644
--- a/MauiUICollectionView/MAUICollectionView.cs
+++ b/MauiUICollectionView/MAUICollectionView.cs
@@ -630,7 +630,7 @@ public void NotifyItemRangeRemoved(NSIndexPath indexPath, int count = 1)
baselineCurrentIndexPath = firstVisibleItem.Section == indexPath.Section ?
NSIndexPath.FromRowSection(firstVisibleItem.Row - count, firstVisibleItem.Section) ://row will change when same section
firstVisibleItem;
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
//indexpath maybe change
StartItem = baselineCurrentIndexPath,
@@ -645,7 +645,7 @@ public void NotifyItemRangeRemoved(NSIndexPath indexPath, int count = 1)
baselineLastIndexPath = firstVisibleItem;
baselineCurrentIndexPath = firstVisibleItem;
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = baselineCurrentIndexPath,
StartBounds = firstVisibleItemBounds
@@ -659,7 +659,7 @@ public void NotifyItemRangeRemoved(NSIndexPath indexPath, int count = 1)
NSIndexPath.FromRowSection(lastVisibleItem.Row - count, lastVisibleItem.Section) ://row will change when same section
lastVisibleItem;
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = baselineCurrentIndexPath,
StartBounds = lastVisibleItemBounds
@@ -668,7 +668,7 @@ public void NotifyItemRangeRemoved(NSIndexPath indexPath, int count = 1)
//fix move first item will measure multiple times when remove top item
if (ItemCountInRange(NSIndexPath.FromRowSection(0, 0), baselineCurrentIndexPath) <= count)
{
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = baselineCurrentIndexPath,
StartBounds = new Rect(0, ScrollY, 0, 0)
@@ -686,7 +686,7 @@ public void NotifyItemRangeRemoved(NSIndexPath indexPath, int count = 1)
baselineCurrentIndexPath = next.Section == indexPath.Section ?
NSIndexPath.FromRowSection(next.Row - count, next.Section) ://row will change when same section
next;
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = baselineCurrentIndexPath,
StartBounds = new Rect(0, ScrollY, 0, 0)
@@ -759,7 +759,7 @@ public void NotifyItemRangeInserted(NSIndexPath indexPath, int count = 1)
{
baselineCurrentIndexPath = firstVisibleItem;
}
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = baselineCurrentIndexPath,
StartBounds = firstVisibleItemBounds
@@ -802,7 +802,7 @@ public void MoveItem(NSIndexPath indexPath, NSIndexPath toIndexPath)
NSIndexPath baselineLastIndexPath = firstVisibleItem;
NSIndexPath baselineCurrentIndexPath = firstVisibleItem;
bool moved = false;
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = baselineCurrentIndexPath,
StartBounds = firstVisibleItemBounds
@@ -830,7 +830,7 @@ public void NotifyItemRangeChanged(NSIndexPath indexPath)
if (layout != null)
{
var firstVisibleItem = PreparedItems.FirstOrDefault();
- layout.BaseLineItemUsually = new CollectionViewLayout.LayoutInfor()
+ layout.ItemLayoutBaseline = new CollectionViewLayout.LayoutInfor()
{
StartItem = firstVisibleItem.Key,
StartBounds = firstVisibleItem.Value.ItemBounds