diff --git a/AiForms.CollectionView.sln b/AiForms.CollectionView.sln
index fc570f5..08a0197 100644
--- a/AiForms.CollectionView.sln
+++ b/AiForms.CollectionView.sln
@@ -11,6 +11,7 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|Any CPU = Release|Any CPU
Debug|Any CPU = Debug|Any CPU
+ Release|iPhoneSimulator = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6E8E8AAC-E482-4E9C-9759-27B03E4DC309}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -25,5 +26,7 @@ Global
{56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|Any CPU.Build.0 = Release|Any CPU
{56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/CollectionView.Droid/CollectionView.Droid.csproj b/CollectionView.Droid/CollectionView.Droid.csproj
index 0b5a0c5..d24092c 100644
--- a/CollectionView.Droid/CollectionView.Droid.csproj
+++ b/CollectionView.Droid/CollectionView.Droid.csproj
@@ -142,7 +142,7 @@
- {6E8E8AAC-E482-4E9C-9759-27B03E4DC309}
+ {D5C93D88-A5D6-4843-935B-CC72F073B54E}
CollectionView
diff --git a/CollectionView.Droid/CollectionViewAdapter.cs b/CollectionView.Droid/CollectionViewAdapter.cs
index 8dd830e..baede21 100644
--- a/CollectionView.Droid/CollectionViewAdapter.cs
+++ b/CollectionView.Droid/CollectionViewAdapter.cs
@@ -399,8 +399,10 @@ public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int positi
var group = 0;
var templatedItems = TemplatedItemsView.TemplatedItems;
if (_collectionView.IsGroupingEnabled)
+ {
group = templatedItems.GetGroupIndexFromGlobal(realPosition, out row);
-
+ if (group < 0) return;
+ }
var templatedList = templatedItems.GetGroup(group);
if (_collectionView.IsGroupingEnabled)
@@ -423,6 +425,8 @@ public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int positi
return;
}
+ if (cell == null) return;
+
AView view = GetCell(cell, container, _recyclerView, _context, _collectionView);
diff --git a/CollectionView.Droid/GridCollectionViewRenderer.cs b/CollectionView.Droid/GridCollectionViewRenderer.cs
index b016a69..30b5cd4 100644
--- a/CollectionView.Droid/GridCollectionViewRenderer.cs
+++ b/CollectionView.Droid/GridCollectionViewRenderer.cs
@@ -19,6 +19,10 @@ public class GridCollectionViewRenderer : CollectionViewRenderer, SwipeRefreshLa
public int RowSpacing { get; set; }
public int ColumnSpacing { get; set; }
+ int _bothSidesMargin;
+ int _firstSpacing;
+ int _lastSpacing;
+
SwipeRefreshLayout _refresh;
GridLayoutManager _gridLayoutManager => LayoutManager as GridLayoutManager;
CollectionViewSpanSizeLookup _spanSizeLookup;
@@ -43,6 +47,7 @@ protected override void Dispose(bool disposing)
if (disposing)
{
+ RecyclerView?.StopScroll();
RecyclerView?.SetAdapter(null);
RecyclerView?.RemoveItemDecoration(_itemDecoration);
_gridLayoutManager?.SetSpanSizeLookup(null);
@@ -126,7 +131,10 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
e.PropertyName == GridCollectionView.ColumnHeightProperty.PropertyName ||
e.PropertyName == GridCollectionView.ColumnWidthProperty.PropertyName ||
e.PropertyName == GridCollectionView.SpacingTypeProperty.PropertyName ||
- e.PropertyName == GridCollectionView.AdditionalHeightProperty.PropertyName)
+ e.PropertyName == GridCollectionView.AdditionalHeightProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupFirstSpacingProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupLastSpacingProperty.PropertyName ||
+ e.PropertyName == GridCollectionView.BothSidesMarginProperty.PropertyName)
{
UpdateGridType();
RefreshAll();
@@ -250,6 +258,9 @@ protected virtual void UpdateGridType(int containerWidth = 0)
RecyclerView.SetPadding(0, 0, 0, 0);
RowSpacing = (int)Context.ToPixels(_gridCollectionView.RowSpacing);
+ _firstSpacing = (int)Context.ToPixels(_gridCollectionView.GroupFirstSpacing);
+ _lastSpacing = (int)Context.ToPixels(_gridCollectionView.GroupLastSpacing);
+
int spanCount = 0;
if (_gridCollectionView.GridType == GridType.UniformGrid)
{
@@ -265,6 +276,7 @@ protected virtual void UpdateGridType(int containerWidth = 0)
spanCount = _gridCollectionView.LandscapeColumns;
break;
}
+ _bothSidesMargin = (int)Context.ToPixels(_gridCollectionView.BothSidesMargin);
ColumnSpacing = (int)(Context.ToPixels(_gridCollectionView.ColumnSpacing));
CellHeight = GetUniformItemHeight(containerWidth, spanCount);
System.Diagnostics.Debug.WriteLine($"Decided RowHeight {CellHeight}");
@@ -295,7 +307,8 @@ protected virtual double CalcurateColumnHeight(double itemWidth)
protected virtual int GetUniformItemHeight(int containerWidth, int columns)
{
- float actualWidth = containerWidth - (float)ColumnSpacing * (float)(columns - 1.0f);
+ RecyclerView.SetPadding(_bothSidesMargin, 0, _bothSidesMargin, 0);
+ float actualWidth = containerWidth - _bothSidesMargin * 2f - (float)ColumnSpacing * (float)(columns - 1.0f);
var itemWidth = (float)(actualWidth / (float)columns);
_gridCollectionView.SetValue(GridCollectionView.ComputedWidthProperty, Context.FromPixels(itemWidth));
return (int)CalcurateColumnHeight(itemWidth);
@@ -413,13 +426,14 @@ public override void GetItemOffsets(Android.Graphics.Rect outRect, Android.Views
var param = view.LayoutParameters as GridLayoutManager.LayoutParams;
var spanIndex = param.SpanIndex;
var spanSize = param.SpanSize;
+ var position = parent.GetChildAdapterPosition(view);
if (spanSize == _spanCount)
{
var headparams = view.LayoutParameters as ViewGroup.MarginLayoutParams;
var margin = 0;
- if (_gridCollectionView.GridType == GridType.AutoSpacingGrid &&
- _gridCollectionView.SpacingType == SpacingType.Center)
+ if (_gridCollectionView.GridType == GridType.AutoSpacingGrid && _gridCollectionView.SpacingType == SpacingType.Center ||
+ _gridCollectionView.GridType == GridType.UniformGrid && _gridCollectionView.BothSidesMargin > 0)
{
margin = _parentRenderer.RecyclerView.PaddingLeft * -1;
headparams.SetMargins(margin, headparams.TopMargin, margin, headparams.BottomMargin);
@@ -430,6 +444,11 @@ public override void GetItemOffsets(Android.Graphics.Rect outRect, Android.Views
headparams.SetMargins(margin, headparams.TopMargin, margin, headparams.BottomMargin);
view.LayoutParameters = headparams;
}
+
+ outRect.Bottom = _parentRenderer._firstSpacing;
+ if(position != 0) {
+ outRect.Top = _parentRenderer._lastSpacing;
+ }
return;
}
@@ -447,9 +466,13 @@ public override void GetItemOffsets(Android.Graphics.Rect outRect, Android.Views
{
outRect.Left = spanIndex * _parentRenderer.ColumnSpacing / _spanCount; // column * ((1f / spanCount) * spacing)
outRect.Right = _parentRenderer.ColumnSpacing - (spanIndex + 1) * _parentRenderer.ColumnSpacing / _spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)
+ }
+
+ if(position < _spanCount || _parentRenderer.Adapter.FirstSectionItems.Contains(position - spanIndex)) {
+ return;
}
- outRect.Bottom = _parentRenderer.RowSpacing;
+ outRect.Top = _parentRenderer.RowSpacing;
}
}
}
diff --git a/CollectionView.Droid/HCollectionViewAdapter.cs b/CollectionView.Droid/HCollectionViewAdapter.cs
index 0d91fad..f6fcfec 100644
--- a/CollectionView.Droid/HCollectionViewAdapter.cs
+++ b/CollectionView.Droid/HCollectionViewAdapter.cs
@@ -54,6 +54,10 @@ protected override void OnCollectionChanged(object sender, NotifyCollectionChang
public override int GetRealPosition(int position)
{
+ if (_listCount == 0)
+ {
+ return position;
+ }
return _hCollectionView.IsInfinite ? position % _listCount : position;
}
diff --git a/CollectionView.Droid/HCollectionViewRenderer.cs b/CollectionView.Droid/HCollectionViewRenderer.cs
index 78dd72d..8bf48e6 100644
--- a/CollectionView.Droid/HCollectionViewRenderer.cs
+++ b/CollectionView.Droid/HCollectionViewRenderer.cs
@@ -18,6 +18,8 @@ public class HCollectionViewRenderer : CollectionViewRenderer, ICollectionViewRe
HCollectionViewAdapter _hAdapter => Adapter as HCollectionViewAdapter;
int _spacing;
bool _disposed;
+ int _firstSpacing;
+ int _lastSpacing;
public HCollectionViewRenderer(Context context) : base(context)
{
@@ -31,6 +33,7 @@ protected override void Dispose(bool disposing)
}
if (disposing)
{
+ RecyclerView?.StopScroll();
RecyclerView?.SetAdapter(null);
RecyclerView?.RemoveItemDecoration(_itemDecoration);
@@ -89,7 +92,9 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
UpdateGroupHeaderWidth();
RefreshAll();
}
- else if (e.PropertyName == HCollectionView.SpacingProperty.PropertyName)
+ else if (e.PropertyName == HCollectionView.SpacingProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupFirstSpacingProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupLastSpacingProperty.PropertyName)
{
UpdateSpacing();
RefreshAll();
@@ -164,6 +169,8 @@ protected virtual void UpdateCellSize()
protected virtual void UpdateSpacing()
{
_spacing = (int)Context.ToPixels(_hCollectionView.Spacing);
+ _firstSpacing = (int)Context.ToPixels(_hCollectionView.GroupFirstSpacing);
+ _lastSpacing = (int)Context.ToPixels(_hCollectionView.GroupLastSpacing);
}
protected virtual void UpdateGroupHeaderWidth()
@@ -202,7 +209,19 @@ public override void GetItemOffsets(Rect outRect, Android.Views.View view, Recyc
{
realPosition = _renderer.Adapter.GetRealPosition(position);
}
- if (position == 0 || holder.IsHeader || _renderer.Adapter.FirstSectionItems.Contains(realPosition))
+
+ if(holder.IsHeader)
+ {
+ outRect.Right = _renderer._firstSpacing;
+ if (position != 0)
+ {
+ outRect.Left = _renderer._lastSpacing;
+ }
+
+ return;
+ }
+
+ if (position == 0 || _renderer.Adapter.FirstSectionItems.Contains(realPosition))
{
return;
}
diff --git a/CollectionView.iOS/CollectionView.iOS.csproj b/CollectionView.iOS/CollectionView.iOS.csproj
index e972443..7c26e5b 100644
--- a/CollectionView.iOS/CollectionView.iOS.csproj
+++ b/CollectionView.iOS/CollectionView.iOS.csproj
@@ -9,7 +9,6 @@
AiForms.Renderers.iOS
CollectionView.iOS
Resources
- 1.1.2
true
@@ -79,10 +78,17 @@
+
+
+
+ {D5C93D88-A5D6-4843-935B-CC72F073B54E}
+ CollectionView
+
+
\ No newline at end of file
diff --git a/CollectionView.iOS/CollectionViewRenderer.cs b/CollectionView.iOS/CollectionViewRenderer.cs
index bae2a17..9d6ab95 100644
--- a/CollectionView.iOS/CollectionViewRenderer.cs
+++ b/CollectionView.iOS/CollectionViewRenderer.cs
@@ -247,10 +247,10 @@ protected virtual void UpdateItems(NotifyCollectionChangedEventArgs e, int secti
// HACK: When an item is added for the first time, UICollectionView is sometimes crashed for some reason.
// So, in that case, ReloadData is called.
- if (!Control.IndexPathsForVisibleItems.Any())
- {
- groupReset = true;
- }
+ //if (!Control.IndexPathsForVisibleItems.Any())
+ //{
+ // groupReset = true;
+ //}
// We can't do this check on grouped lists because the index doesn't match the number of rows in a section.
// Likewise, we can't do this check on lists using RecycleElement because the number of rows in a section will remain constant because they are reused.
diff --git a/CollectionView.iOS/CollectionViewSource.cs b/CollectionView.iOS/CollectionViewSource.cs
index c5206d6..3eabfa4 100644
--- a/CollectionView.iOS/CollectionViewSource.cs
+++ b/CollectionView.iOS/CollectionViewSource.cs
@@ -59,6 +59,11 @@ protected override void Dispose(bool disposing)
public override nint NumberOfSections(UICollectionView collectionView)
{
+ if (TemplatedItemsView.TemplatedItems.Count == 0)
+ {
+ return 0;
+ }
+
if (CollectionView.IsGroupingEnabled)
{
return TemplatedItemsView.TemplatedItems.Count;
@@ -168,6 +173,7 @@ public override UICollectionReusableView GetViewForSupplementaryElement(UICollec
Performance.Start(out string reference);
+
var cachingStrategy = CollectionView.CachingStrategy;
if (cachingStrategy == ListViewCachingStrategy.RetainElement)
{
@@ -175,8 +181,6 @@ public override UICollectionReusableView GetViewForSupplementaryElement(UICollec
}
else if ((cachingStrategy & ListViewCachingStrategy.RecycleElement) != 0)
{
- var id = TemplateIdForPath(realIndexPath);
-
// Here is used the argument indexPath as it is because header cell will be got not to displayed when IsInfinite.
nativeCell = collectionView.DequeueReusableSupplementaryView(
UICollectionElementKindSection.Header,
@@ -278,6 +282,17 @@ protected virtual ContentCellContainer GetNativeHeaderCell(NSIndexPath indexPath
var nativeCell = renderer.GetCell(cell, reusableCell, _uiCollectionView) as ContentCellContainer;
+ var cellWithContent = nativeCell;
+
+ // Sometimes iOS for returns a dequeued cell whose Layer is hidden.
+ // This prevents it from showing up, so lets turn it back on!
+ if (cellWithContent.Layer.Hidden)
+ cellWithContent.Layer.Hidden = false;
+
+ // Because the layer was hidden we need to layout the cell by hand
+ if (cellWithContent != null)
+ cellWithContent.LayoutSubviews();
+
return nativeCell;
}
diff --git a/CollectionView.iOS/GridCollectionViewRenderer.cs b/CollectionView.iOS/GridCollectionViewRenderer.cs
index 663522f..0d6a457 100644
--- a/CollectionView.iOS/GridCollectionViewRenderer.cs
+++ b/CollectionView.iOS/GridCollectionViewRenderer.cs
@@ -8,6 +8,9 @@
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using RectangleF = CoreGraphics.CGRect;
+using Foundation;
+using System.Collections.Generic;
+using CoreFoundation;
[assembly: ExportRenderer(typeof(GridCollectionView), typeof(GridCollectionViewRenderer))]
namespace AiForms.Renderers.iOS
@@ -22,20 +25,20 @@ public class GridCollectionViewRenderer : CollectionViewRenderer
bool _disposed;
GridCollectionView _gridCollectionView => (GridCollectionView)Element;
GridCollectionViewSource _gridSource => DataSource as GridCollectionViewSource;
+ float _firstSpacing => _gridCollectionView.IsGroupingEnabled ? (float)_gridCollectionView.GroupFirstSpacing : 0;
+ float _lastSpacing => _gridCollectionView.IsGroupingEnabled ? (float)_gridCollectionView.GroupLastSpacing : 0;
bool _isRatioHeight => _gridCollectionView.ColumnHeight <= 5.0;
protected override void OnElementChanged(ElementChangedEventArgs e)
{
if (e.NewElement != null)
{
- ViewLayout = new UICollectionViewFlowLayout();
+ ViewLayout = new GridViewLayout();
ViewLayout.ScrollDirection = UICollectionViewScrollDirection.Vertical;
ViewLayout.SectionInset = new UIEdgeInsets(0, 0, 0, 0);
ViewLayout.MinimumLineSpacing = 0.0f;
ViewLayout.MinimumInteritemSpacing = 0.0f;
ViewLayout.EstimatedItemSize = UICollectionViewFlowLayout.AutomaticSize;
- ViewLayout.SectionHeadersPinToVisibleBounds = true; // fix header cell
-
_refreshControl = new UIRefreshControl();
_refreshControl.ValueChanged += RefreshControl_ValueChanged;
@@ -59,6 +62,7 @@ protected override void OnElementChanged(ElementChangedEventArgs
DataSource = new GridCollectionViewSource(e.NewElement, _collectionView);
_collectionView.Source = DataSource;
+ UpdateIsSticky();
UpdateRowSpacing();
UpdatePullToRefreshEnabled();
UpdatePullToRefreshColor();
@@ -129,10 +133,13 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
e.PropertyName == GridCollectionView.ColumnSpacingProperty.PropertyName ||
e.PropertyName == GridCollectionView.ColumnHeightProperty.PropertyName ||
e.PropertyName == GridCollectionView.SpacingTypeProperty.PropertyName ||
- e.PropertyName == GridCollectionView.AdditionalHeightProperty.PropertyName)
+ e.PropertyName == GridCollectionView.AdditionalHeightProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupFirstSpacingProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupLastSpacingProperty.PropertyName ||
+ e.PropertyName == GridCollectionView.BothSidesMarginProperty.PropertyName)
{
UpdateGridType();
- ViewLayout.InvalidateLayout();
+ InvalidateLayout();
}
else if (e.PropertyName == GridCollectionView.RowSpacingProperty.PropertyName)
{
@@ -144,7 +151,7 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
if (_gridCollectionView.GridType != GridType.UniformGrid)
{
UpdateGridType();
- ViewLayout.InvalidateLayout();
+ InvalidateLayout();
}
}
else if (e.PropertyName == ListView.IsPullToRefreshEnabledProperty.PropertyName)
@@ -159,6 +166,11 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
{
UpdateIsRefreshing();
}
+ else if (e.PropertyName == GridCollectionView.IsGroupHeaderStickyProperty.PropertyName)
+ {
+ UpdateIsSticky();
+ InvalidateLayout();
+ }
}
protected override UICollectionViewScrollPosition GetScrollPosition(ScrollToPosition position)
@@ -241,9 +253,15 @@ protected virtual void UpdateGroupHeaderHeight()
}
}
+ protected virtual void UpdateIsSticky()
+ {
+ ViewLayout.SectionHeadersPinToVisibleBounds = _gridCollectionView.IsGroupHeaderSticky;
+ }
+
protected virtual void UpdateGridType()
{
- ViewLayout.SectionInset = new UIEdgeInsets(0, 0, 0, 0); // Reset insets
+ // Reset insets
+ ViewLayout.SectionInset = new UIEdgeInsets(_firstSpacing, 0,_lastSpacing, 0);
ViewLayout.MinimumInteritemSpacing = 0;
CGSize itemSize = CGSize.Empty;
@@ -273,6 +291,7 @@ protected virtual void UpdateGridType()
_gridCollectionView.SetValue(GridCollectionView.ComputedHeightProperty, itemSize.Height);
DataSource.CellSize = itemSize;
+ ViewLayout.EstimatedItemSize = itemSize;
}
protected virtual double CalcurateColumnHeight(double itemWidth)
@@ -287,7 +306,10 @@ protected virtual double CalcurateColumnHeight(double itemWidth)
protected virtual CGSize GetUniformItemSize(int columns)
{
- float width = (float)Frame.Width - (float)_gridCollectionView.ColumnSpacing * (float)(columns - 1.0f);
+ var margin = (float)_gridCollectionView.BothSidesMargin;
+ ViewLayout.SectionInset = new UIEdgeInsets(_firstSpacing,margin, _lastSpacing, margin);
+
+ float width = (float)Frame.Width - margin * 2f - (float)_gridCollectionView.ColumnSpacing * (float)(columns - 1.0f);
_gridSource.SurplusPixel = (int)width % columns;
@@ -330,9 +352,28 @@ protected virtual CGSize GetAutoSpacingItemSize()
var insetSurplus = (int)insetSum % 2;
var inset = (float)Math.Floor(insetSum / 2.0f);
- ViewLayout.SectionInset = new UIEdgeInsets(0, inset + (float)insetSurplus, 0, inset);
+ ViewLayout.SectionInset = new UIEdgeInsets(_firstSpacing, inset + (float)insetSurplus, _lastSpacing, inset);
return new CGSize(itemWidth, itemHeight);
}
+
+ void InvalidateLayout()
+ {
+ if (!_gridCollectionView.IsGroupingEnabled)
+ {
+ ViewLayout.InvalidateLayout();
+ return;
+ }
+
+ // HACK: When IsGroupingEnabled is true and changing such layout size as the item size and the spacing size,
+ // a header cell content is sometimes not reflected or broken layout.
+ // By reloading with a bit delay after scrolling to Top, this issue can be avoided.
+ Control.SetContentOffset(CGPoint.Empty, false);
+ DispatchQueue.MainQueue.DispatchAfter(new DispatchTime(DispatchTime.Now, TimeSpan.FromMilliseconds(150)), () =>
+ {
+ Control.ReloadData();
+ ViewLayout.InvalidateLayout();
+ });
+ }
}
}
diff --git a/CollectionView.iOS/GridViewLayout.cs b/CollectionView.iOS/GridViewLayout.cs
new file mode 100644
index 0000000..cb517b5
--- /dev/null
+++ b/CollectionView.iOS/GridViewLayout.cs
@@ -0,0 +1,38 @@
+using System;
+using Foundation;
+using UIKit;
+using CoreGraphics;
+using System.Linq;
+namespace AiForms.Renderers.iOS
+{
+ public class GridViewLayout:UICollectionViewFlowLayout
+ {
+ public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect)
+ {
+ var attributes = base.LayoutAttributesForElementsInRect(rect);
+ attributes.Where(x => x.RepresentedElementCategory == UICollectionElementCategory.Cell);
+ for (var i = 0; i < attributes.Length;i++)
+ {
+ if(attributes[i].RepresentedElementCategory == UICollectionElementCategory.Cell && attributes[i].IndexPath.Row == 0)
+ {
+ attributes[i] = LayoutAttributesForItem(attributes[i].IndexPath);
+ }
+ }
+
+ return attributes;
+ }
+
+ public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath indexPath)
+ {
+ var curAttributes = base.LayoutAttributesForItem(indexPath);
+ if(indexPath.Row == 0)
+ {
+ var rect = curAttributes.Frame;
+ curAttributes.Frame = new CGRect(SectionInset.Left, rect.Y, rect.Width, rect.Height);
+ return curAttributes;
+ }
+
+ return curAttributes;
+ }
+ }
+}
diff --git a/CollectionView.iOS/HCollectionViewRenderer.cs b/CollectionView.iOS/HCollectionViewRenderer.cs
index 51490ab..59bc22c 100644
--- a/CollectionView.iOS/HCollectionViewRenderer.cs
+++ b/CollectionView.iOS/HCollectionViewRenderer.cs
@@ -19,6 +19,8 @@ public class HCollectionViewRenderer : CollectionViewRenderer
CGRect _previousFrame = CGRect.Empty;
bool _disposed;
HCollectionView _hCollectionView => Element as HCollectionView;
+ float _firstSpacing => _hCollectionView.IsGroupingEnabled ? (float)_hCollectionView.GroupFirstSpacing : 0;
+ float _lastSpacing => _hCollectionView.IsGroupingEnabled ? (float)_hCollectionView.GroupLastSpacing : 0;
protected override void OnElementChanged(ElementChangedEventArgs e)
{
@@ -89,14 +91,15 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
{
UpdateCellSize();
ViewLayout.InvalidateLayout();
-
}
else if (e.PropertyName == HCollectionView.GroupHeaderWidthProperty.PropertyName)
{
UpdateGroupHeaderWidth();
ViewLayout.InvalidateLayout();
}
- else if (e.PropertyName == HCollectionView.SpacingProperty.PropertyName)
+ else if (e.PropertyName == HCollectionView.SpacingProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupFirstSpacingProperty.PropertyName ||
+ e.PropertyName == CollectionView.GroupLastSpacingProperty.PropertyName)
{
UpdateSpacing();
ViewLayout.InvalidateLayout();
@@ -166,6 +169,7 @@ protected virtual void UpdateCellSize()
protected virtual void UpdateSpacing()
{
ViewLayout.MinimumLineSpacing = (System.nfloat)_hCollectionView.Spacing;
+ ViewLayout.SectionInset = new UIEdgeInsets(0, _firstSpacing, 0, _lastSpacing);
}
protected virtual void UpdateGroupHeaderWidth()
diff --git a/CollectionView/CollectionView.cs b/CollectionView/CollectionView.cs
index ef56b0d..5c1c126 100644
--- a/CollectionView/CollectionView.cs
+++ b/CollectionView/CollectionView.cs
@@ -85,6 +85,50 @@ public Color TouchFeedbackColor {
set { SetValue(TouchFeedbackColorProperty, value); }
}
+ ///
+ /// The group first spacing property.
+ ///
+ public static BindableProperty GroupFirstSpacingProperty =
+ BindableProperty.Create(
+ nameof(GroupFirstSpacing),
+ typeof(double),
+ typeof(CollectionView),
+ default(double),
+ defaultBindingMode: BindingMode.OneWay
+ );
+
+ ///
+ /// Gets or sets the group first spacing.
+ ///
+ /// The group first spacing.
+ public double GroupFirstSpacing
+ {
+ get { return (double)GetValue(GroupFirstSpacingProperty); }
+ set { SetValue(GroupFirstSpacingProperty, value); }
+ }
+
+ ///
+ /// The group last spacing property.
+ ///
+ public static BindableProperty GroupLastSpacingProperty =
+ BindableProperty.Create(
+ nameof(GroupLastSpacing),
+ typeof(double),
+ typeof(CollectionView),
+ default(double),
+ defaultBindingMode: BindingMode.OneWay
+ );
+
+ ///
+ /// Gets or sets the group last spacing.
+ ///
+ /// The group last spacing.
+ public double GroupLastSpacing
+ {
+ get { return (double)GetValue(GroupLastSpacingProperty); }
+ set { SetValue(GroupLastSpacingProperty, value); }
+ }
+
///
/// The scroll controller property.
///
diff --git a/CollectionView/GridCollectionView.cs b/CollectionView/GridCollectionView.cs
index c4c5f93..8369612 100644
--- a/CollectionView/GridCollectionView.cs
+++ b/CollectionView/GridCollectionView.cs
@@ -332,5 +332,51 @@ public Color PullToRefreshColor
set { SetValue(PullToRefreshColorProperty, value); }
}
+ ///
+ /// The both sides margin property.
+ ///
+ public static BindableProperty BothSidesMarginProperty =
+ BindableProperty.Create(
+ nameof(BothSidesMargin),
+ typeof(double),
+ typeof(GridCollectionView),
+ default(double),
+ defaultBindingMode: BindingMode.OneWay
+ );
+
+ ///
+ /// Gets or sets the both sides margin.
+ ///
+ /// The both sides margin.
+ public double BothSidesMargin
+ {
+ get { return (double)GetValue(BothSidesMarginProperty); }
+ set { SetValue(BothSidesMarginProperty, value); }
+ }
+
+
+ ///
+ /// The is group header sticky property.
+ ///
+ public static BindableProperty IsGroupHeaderStickyProperty =
+ BindableProperty.Create(
+ nameof(IsGroupHeaderSticky),
+ typeof(bool),
+ typeof(GridCollectionView),
+ true,
+ defaultBindingMode: BindingMode.OneWay
+ );
+
+ ///
+ /// Gets or sets a value indicating whether this is group
+ /// header sticky.
+ ///
+ /// true if is group header sticky; otherwise, false.
+ public bool IsGroupHeaderSticky
+ {
+ get { return (bool)GetValue(IsGroupHeaderStickyProperty); }
+ set { SetValue(IsGroupHeaderStickyProperty, value); }
+ }
+
}
}
diff --git a/README-ja.md b/README-ja.md
index 4ef339e..c66e089 100644
--- a/README-ja.md
+++ b/README-ja.md
@@ -2,6 +2,8 @@
CollectionViewは、Xamarin.Formsで使用できるGridや水平方向レイアウトに対応した柔軟なListViewです。AndroidとiOSに対応しています。
+[![Build status](https://kamusoft.visualstudio.com/NugetCI/_apis/build/status/AiForms.CollectionView)](https://kamusoft.visualstudio.com/NugetCI/_build/latest?definitionId=4)
+
## コントロール
* [GridCollectionView](#gridcollectionview)
@@ -246,6 +248,12 @@ Grid状に各要素を配置するListViewです。これは [WrapLayout](https:
* グループヘッダーのセルの高さ。
* [SpacingType](#spacingtype-enumeration)
* 列間の間隔の決め方を、Between と Center から選択します。GridType が AutoSpacingGrid のときのみ有効です。(Default: Between)
+* GroupFirstSpacing
+ * グループ内の最初のアイテムの上の間隔。
+* GroupLastSpacing
+ * グループ内の最後のアイテムの下の間隔。
+* BothSidesMargin
+ * グループヘッダーセル以外のコンテンツ領域の左右の余白。GridType が UniformGrid のときのみ有効です。 (Default: 0)
* PullToRefreshColor
* PullToRefreshのインジケータに使用する色。
* ItemTapCommand
@@ -256,6 +264,8 @@ Grid状に各要素を配置するListViewです。これは [WrapLayout](https:
* アイテムをタッチした時に表示するエフェクト色。
* [ScrollController](#scrollcontroller)
* ViewModelなどでCollectionViewのスクロールを制御する場合に使用するオブジェクト。
+* IsGroupHeaderSticky
+ * グループヘッダーを上に固定するかどうか (iOS のみ) (default: true)
### Special Properties
@@ -307,6 +317,10 @@ Grid状に各要素を配置するListViewです。これは [WrapLayout](https:
* アイテムをタッチした時に表示するエフェクト色。
* [ScrollController](#scrollcontroller)
* ViewModelなどでCollectionViewのスクロールを制御する場合に使用するオブジェクト。
+* GroupFirstSpacing
+ * グループ内の最初のアイテムの左の間隔。
+* GroupLastSpacing
+ * グループ内の最後のアイテムの右の間隔。
### 行の高さについて
diff --git a/README.md b/README.md
index 7796347..883ccfc 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ This is a flexible ListView that has a grid and horizontal layout with reusable
[Japanese](./README-ja.md)
+[![Build status](https://kamusoft.visualstudio.com/NugetCI/_apis/build/status/AiForms.CollectionView)](https://kamusoft.visualstudio.com/NugetCI/_build/latest?definitionId=4)
+
## Available controls
* [GridCollectionView](#gridcollectionview)
@@ -248,6 +250,12 @@ This is the ListView that lays out each item in a grid pattern. Though this is s
* The height of a group header cell.
* [SpacingType](#spacingtype-enumeration)
* Select the spacing type using an enumeration value either Between or Center. This is used only when GridType is AutoSpacingGrid. (Default: Between)
+* GroupFirstSpacing
+ * The spacing of the first item's top in a group.
+* GroupLastSpacing
+ * The spacing of the last item's bottom in a group.
+* BothSidesMargin
+ * The margin of the right and left sides in the content area except for a group header cell. This is used only when GridType is UniformGrid. (Default: 0)
* PullToRefreshColor
* The color of the PullToRefresh indicator icon.
* ItemTapCommand
@@ -258,6 +266,8 @@ This is the ListView that lays out each item in a grid pattern. Though this is s
* The color rendered when an item is touched.
* [ScrollController](#scrollcontroller)
* The object for manipulating the scroll from such as ViewModel.
+* IsGroupHeaderSticky
+ * Whether a group header is fixed at the top. (iOS only) (default: true)
### Special Properties
@@ -309,6 +319,10 @@ This is the ListView that lays out each item horizontally. This can make the scr
* The color rendered when an item is touched.
* [ScrollController](#scrollcontroller)
* The object for manipulating the scroll from such as ViewModel.
+* GroupFirstSpacing
+ * The spacing of the first item's left in a group.
+* GroupLastSpacing
+ * The spacing of the last item's right in a group.
### About Row Height
diff --git a/Sample/Sample.Droid/MainActivity.cs b/Sample/Sample.Droid/MainActivity.cs
index 4e42ed6..526a16e 100644
--- a/Sample/Sample.Droid/MainActivity.cs
+++ b/Sample/Sample.Droid/MainActivity.cs
@@ -1,5 +1,4 @@
-using AiForms.Extras;
-using Android.App;
+using Android.App;
using Android.Content.PM;
using Android.OS;
using CarouselView.FormsPlugin.Android;
@@ -23,7 +22,7 @@ protected override void OnCreate(Bundle bundle)
Xamarin.Forms.Svg.Droid.SvgImage.Init();
FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true);
CarouselViewRenderer.Init();
- AiForms.Extras.Extras.Init(this);
+ AiForms.Dialogs.Dialogs.Init(this);
LoadApplication(new App(new AndroidInitializer()));
@@ -34,7 +33,7 @@ public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
- containerRegistry.RegisterInstance(Toast.Instance);
+ containerRegistry.RegisterInstance(AiForms.Dialogs.Toast.Instance);
}
}
}
diff --git a/Sample/Sample.Droid/Sample.Droid.csproj b/Sample/Sample.Droid/Sample.Droid.csproj
index 717ef02..4104bb3 100644
--- a/Sample/Sample.Droid/Sample.Droid.csproj
+++ b/Sample/Sample.Droid/Sample.Droid.csproj
@@ -208,11 +208,17 @@
..\packages\Xamarin.Forms.3.2.0.839982\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
-
- ..\packages\AiForms.Extras.0.1.0-pre1\lib\MonoAndroid\AiForms.Extras.Abstractions.dll
+
+ ..\packages\AiForms.SettingsView.0.3.2\lib\MonoAndroid\SettingsView.dll
-
- ..\packages\AiForms.Extras.0.1.0-pre1\lib\MonoAndroid\AiForms.Extras.dll
+
+ ..\packages\AiForms.SettingsView.0.3.2\lib\MonoAndroid\SettingsView.Droid.dll
+
+
+ ..\packages\AiForms.Dialogs.0.3.2-pre\lib\MonoAndroid\AiForms.Dialogs.Abstractions.dll
+
+
+ ..\packages\AiForms.Dialogs.0.3.2-pre\lib\MonoAndroid\AiForms.Dialogs.dll
diff --git a/Sample/Sample.Droid/packages.config b/Sample/Sample.Droid/packages.config
index 4090463..0f58cd3 100644
--- a/Sample/Sample.Droid/packages.config
+++ b/Sample/Sample.Droid/packages.config
@@ -1,8 +1,9 @@
+
-
+
diff --git a/Sample/Sample.iOS/AppDelegate.cs b/Sample/Sample.iOS/AppDelegate.cs
index a475f65..d9eb375 100644
--- a/Sample/Sample.iOS/AppDelegate.cs
+++ b/Sample/Sample.iOS/AppDelegate.cs
@@ -5,8 +5,7 @@
using FFImageLoading.Forms;
using FFImageLoading.Forms.Touch;
using CarouselView.FormsPlugin.iOS;
-using AiForms.Extras.Abstractions;
-using AiForms.Extras;
+using AiForms.Dialogs;
namespace Sample.iOS
{
@@ -29,9 +28,11 @@ public override bool FinishedLaunching(UIApplication app, NSDictionary options)
AiForms.Effects.iOS.Effects.Init();
AiForms.Renderers.iOS.CollectionViewInit.Init();
+ AiForms.Renderers.iOS.SettingsViewInit.Init();
Xamarin.Forms.Svg.iOS.SvgImage.Init();
FFImageLoading.Forms.Platform.CachedImageRenderer.Init();
CarouselViewRenderer.Init();
+ AiForms.Dialogs.Dialogs.Init();
LoadApplication(new App(new iOSInitializer()));
diff --git a/Sample/Sample.iOS/Sample.iOS.csproj b/Sample/Sample.iOS/Sample.iOS.csproj
index dc952de..d9f6f33 100644
--- a/Sample/Sample.iOS/Sample.iOS.csproj
+++ b/Sample/Sample.iOS/Sample.iOS.csproj
@@ -181,11 +181,17 @@
..\packages\Xamarin.Forms.3.2.0.839982\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
-
- ..\packages\AiForms.Extras.0.1.0-pre1\lib\Xamarin.iOS10\AiForms.Extras.Abstractions.dll
+
+ ..\packages\AiForms.SettingsView.0.3.2\lib\Xamarin.iOS10\SettingsView.dll
-
- ..\packages\AiForms.Extras.0.1.0-pre1\lib\Xamarin.iOS10\AiForms.Extras.dll
+
+ ..\packages\AiForms.SettingsView.0.3.2\lib\Xamarin.iOS10\SettingsView.iOS.dll
+
+
+ ..\packages\AiForms.Dialogs.0.3.2-pre\lib\Xamarin.iOS10\AiForms.Dialogs.Abstractions.dll
+
+
+ ..\packages\AiForms.Dialogs.0.3.2-pre\lib\Xamarin.iOS10\AiForms.Dialogs.dll
diff --git a/Sample/Sample.iOS/packages.config b/Sample/Sample.iOS/packages.config
index 950b220..1e1521f 100644
--- a/Sample/Sample.iOS/packages.config
+++ b/Sample/Sample.iOS/packages.config
@@ -1,8 +1,9 @@
+
-
+
diff --git a/Sample/Sample/Sample.csproj b/Sample/Sample/Sample.csproj
index df12cf4..3e5461a 100644
--- a/Sample/Sample/Sample.csproj
+++ b/Sample/Sample/Sample.csproj
@@ -14,7 +14,8 @@
-
+
+
@@ -22,4 +23,7 @@
+
+
+
\ No newline at end of file
diff --git a/Sample/Sample/ViewModels/CollectionViewGroupTestViewModel.cs b/Sample/Sample/ViewModels/CollectionViewGroupTestViewModel.cs
index 0eee5e0..8b9a50f 100644
--- a/Sample/Sample/ViewModels/CollectionViewGroupTestViewModel.cs
+++ b/Sample/Sample/ViewModels/CollectionViewGroupTestViewModel.cs
@@ -13,13 +13,10 @@ namespace Sample.ViewModels
{
public class CollectionViewGroupTestViewModel:CollectionViewTestViewModel
{
- public ObservableCollection ItemsGroupSource { get; set; }
+
public ReactiveCommand AddSecCommand { get; set; } = new ReactiveCommand();
public ReactiveCommand DelSecCommand { get; set; } = new ReactiveCommand();
- public ReactivePropertySlim HeaderHeight { get; } = new ReactivePropertySlim(36);
-
- PhotoGroup _additionalGroup;
IPageDialogService _pageDlg;
public CollectionViewGroupTestViewModel(IPageDialogService pageDialog):base(pageDialog)
@@ -29,153 +26,6 @@ public CollectionViewGroupTestViewModel(IPageDialogService pageDialog):base(page
}
- public override void IndividualTest()
- {
- TestList.Add("Test Start").Add(
- "Manipulation Test1. Has SectionB been scrolled to Top to Bottom To Center?",
- async () =>
- {
- ScrollController.ScrollToStart();
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Start, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.End, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Center, false);
- }
- ).Add(
- "Manipulation Test2. Has SectionB been scrolled to Top to Bottom To Center with animation?",
- async () =>
- {
-
- ScrollController.ScrollToStart(true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.End, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Center, true);
-
- }
- ).Add(
- "Manipulation Test3. Has SectionC - Title14 been scrolled to Top to Bottom To Center?",
- async () =>
- {
- ScrollController.ScrollToStart(false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Start, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.End, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Center, false);
- }
- ).Add(
- "Manipulation Test4. Has SectionC - Title14 been scrolled to Top to Bottom To Center with animation?",
- async () =>
- {
- ScrollController.ScrollToStart(true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.End, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Center, true);
- }
- ).Add(
- "Manipulation Test5. Has new cell been inserted before Title1?",
- async () =>
- {
- ScrollController.ScrollToStart(true);
- await Task.Delay(2000);
- ItemsGroupSource[0].Insert(0, GetAdditionalItem());
- }
- ).Add(
- "Manipulation Test6. Has new cell been inserted after Title20?",
- async () =>
- {
- ScrollController.ScrollTo(ItemsGroupSource[0][20],ItemsGroupSource[0], ScrollToPosition.End, true);
- await Task.Delay(2000);
- ItemsGroupSource[0].Add(GetAdditionalItem());
- }
- ).Add(
- "Manipulation Test7. Has new cell been inserted between Title8 and Title9?",
- async () =>
- {
- ScrollController.ScrollTo(ItemsGroupSource[0][8],ItemsGroupSource[0], ScrollToPosition.Center, true);
- await Task.Delay(2000);
- ItemsGroupSource[0].Insert(9, GetAdditionalItem());
- }
- ).Add(
- "Manipulation Test8. Has the first cell been deleted?",
- async () =>
- {
- ScrollController.ScrollToStart(true);
- await Task.Delay(2000);
- ItemsGroupSource[0].RemoveAt(0);
- }
- ).Add(
- "Manipulation Test9. Has the last cell in SectionA been deleted?",
- async () =>
- {
- ScrollController.ScrollTo(ItemsGroupSource[0][21], ItemsGroupSource[0], ScrollToPosition.End, true);
- await Task.Delay(2000);
- ItemsGroupSource[0].RemoveAt(ItemsGroupSource[0].Count - 1);
- }
- ).Add(
- "Manipulation Test10. Has the cell between Title8 and Title9 in SectionA been deleted?",
- async () =>
- {
- ScrollController.ScrollTo(ItemsGroupSource[0][8], ItemsGroupSource[0], ScrollToPosition.Center, true);
- await Task.Delay(2000);
- ItemsGroupSource[0].RemoveAt(8);
- }
- ).Add(
- "Manipulation Test11. Has the first cell been changed to AddItem?",
- async () =>
- {
- ScrollController.ScrollToStart(true);
- await Task.Delay(2000);
- ItemsGroupSource[0][0] = GetAdditionalItem();
- }
- ).Add(
- "Manipulation Test12. Has the first cell been moved to after Title5?",
- async () =>
- {
- ScrollController.ScrollToStart(true);
- await Task.Delay(2000);
- ItemsGroupSource[0].Move(0, 4);
- }
- ).Add(
- "Manipulation Test13. Has new section been inserted at last?",
- async () =>
- {
- await Task.Delay(2000);
- ItemsGroupSource.Add(_additionalGroup);
- await Task.Delay(2000);
- ScrollController.ScrollToEnd(true);
- }
- ).Add(
- "Manipulation Test14. Has the last section been deleted?",
- async () =>
- {
- await Task.Delay(2000);
- ItemsGroupSource.Remove(_additionalGroup);
- await Task.Delay(2000);
- ScrollController.ScrollToEnd(true);
- }
- ).Add(
- "Has GroupHeaderHeight been twice as large as the privious?",
- async () =>
- {
- await Task.Delay(2000);
- HeaderHeight.Value *= 2;
- },
- () => {
- HeaderHeight.Value /= 2;
- }
- );
- }
-
void InitializeProperties() {
ItemsGroupSource = new ObservableCollection();
@@ -209,101 +59,14 @@ void InitializeProperties() {
Category = "CCC",
});
}
- var list4 = new List();
- for (var i = 5; i < 15; i++)
- {
- list4.Add(new PhotoItem
- {
- PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg",
- Title = $"Title {i + 1}",
- Category = "DDD",
- });
- }
var group1 = new PhotoGroup(list1) { Head = "SectionA" };
var group2 = new PhotoGroup(list2) { Head = "SectionB" };
var group3 = new PhotoGroup(list3) { Head = "SectionC" };
- _additionalGroup = new PhotoGroup(list4) { Head = "SectionD" };
+
ItemsGroupSource.Add(group1);
ItemsGroupSource.Add(group2);
ItemsGroupSource.Add(group3);
-
- }
-
- public override void InitializeCommand()
- {
- var addItem = new PhotoItem
- {
- PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/1.jpg",
- Title = $"AddItem",
- Category = "AAA"
- };
-
- var addPtn = 0;
- AddCommand.Subscribe(_ =>
- {
- switch (addPtn)
- {
- case 0:
- ItemsGroupSource[0].Insert(0, addItem);
- break;
- case 1:
- ItemsGroupSource[0].Add(addItem);
- break;
- case 2:
- ItemsGroupSource[0].Insert(ItemsGroupSource[0].Count / 2, addItem);
- break;
- }
-
- addPtn++;
- if (addPtn > 2)
- {
- addPtn = 0;
- }
- });
-
- var delPtn = 0;
- DelCommand.Subscribe(_ =>
- {
- switch (delPtn)
- {
- case 0:
- ItemsGroupSource[0].RemoveAt(0);
- break;
- case 1:
- ItemsGroupSource[0].RemoveAt(ItemsGroupSource[0].Count - 1);
- break;
- case 2:
- ItemsGroupSource[0].RemoveAt(ItemsGroupSource[0].Count / 2);
- break;
- }
- delPtn++;
- if (delPtn > 2)
- {
- delPtn = 0;
- }
- });
-
- RepCommand.Subscribe(_ =>
- {
- ItemsGroupSource[0][0] = addItem;
- });
-
- MoveCommand.Subscribe(_ =>
- {
- ItemsGroupSource[0].Move(0, 4);
- });
-
-
- AddSecCommand.Subscribe(_ =>
- {
- ItemsGroupSource.Add(_additionalGroup);
- });
-
- DelSecCommand.Subscribe(_ =>
- {
- ItemsGroupSource.RemoveAt(ItemsSource.Count - 1);
- });
}
}
}
diff --git a/Sample/Sample/ViewModels/CollectionViewTestViewModel.cs b/Sample/Sample/ViewModels/CollectionViewTestViewModel.cs
index a11f7f1..f62db08 100644
--- a/Sample/Sample/ViewModels/CollectionViewTestViewModel.cs
+++ b/Sample/Sample/ViewModels/CollectionViewTestViewModel.cs
@@ -8,12 +8,14 @@
using AiForms.Renderers;
using Prism.Navigation;
using System.Linq;
+using Prism.Mvvm;
namespace Sample.ViewModels
{
- public class CollectionViewTestViewModel:INavigatingAware
+ public class CollectionViewTestViewModel:BindableBase, INavigatingAware
{
public PhotoGroup ItemsSource { get; set; }
+ public ObservableCollection ItemsGroupSource { get; set; }
public ReactiveCommand TapCommand { get; } = new ReactiveCommand();
public ReactiveCommand LongTapCommand { get; } = new ReactiveCommand();
public ReactiveProperty IsRefreshing { get; } = new ReactiveProperty(false);
@@ -25,7 +27,10 @@ public class CollectionViewTestViewModel:INavigatingAware
public ReactiveCommand DelCommand { get; set; } = new ReactiveCommand();
public ReactiveCommand RepCommand { get; set; } = new ReactiveCommand();
public ReactiveCommand MoveCommand { get; set; } = new ReactiveCommand();
+ public ReactiveCommand NextCommand { get; set; } = new ReactiveCommand();
+ public ReactiveCommand RepeatCommand { get; set; } = new ReactiveCommand();
+ public ReactivePropertySlim HeaderHeight { get; } = new ReactivePropertySlim(36);
public ReactivePropertySlim Background { get; } = new ReactivePropertySlim(Color.Transparent);
public ReactivePropertySlim FeedbackColor { get; } = new ReactivePropertySlim(Color.Yellow);
public ReactivePropertySlim GridType { get; } = new ReactivePropertySlim(AiForms.Renderers.GridType.UniformGrid);
@@ -40,6 +45,13 @@ public class CollectionViewTestViewModel:INavigatingAware
public ReactivePropertySlim RefreshIconColor { get; } = new ReactivePropertySlim(Color.DimGray);
public ReactivePropertySlim AdditionalHeight { get; } = new ReactivePropertySlim(0);
public IScrollController ScrollController { get; set; }
+ public ReactivePropertySlim GroupFirstSpacing { get; } = new ReactivePropertySlim(0);
+ public ReactivePropertySlim GroupLastSpacing { get; } = new ReactivePropertySlim(0);
+ public ReactivePropertySlim IsGroupHeaderSticky { get; } = new ReactivePropertySlim(true);
+ public ReactivePropertySlim BothSidesMargin { get; } = new ReactivePropertySlim(0);
+
+ public List TestSections { get; set; }
+ IEnumerator _testEnumerator;
IPageDialogService _pageDlg;
@@ -48,223 +60,33 @@ public CollectionViewTestViewModel(IPageDialogService pageDialog)
_pageDlg = pageDialog;
InitializeProperties();
- TestSource = new TestFormViewModel
+ Action currentAction = null;
+ NextCommand.Subscribe(async _ =>
{
- ItemsSource = TestList,
- PageDialog = pageDialog
- };
-
+ if (!_testEnumerator.MoveNext())
+ {
+ await pageDialog.DisplayAlertAsync("", "Finished", "OK");
+ return;
+ }
+ currentAction = _testEnumerator.Current.Run;
+ currentAction?.Invoke();
+ });
+ RepeatCommand.Subscribe(_ =>
+ {
+ currentAction?.Invoke();
+ });
}
- void CommontTest() {
- TestList.Add(
- "PullToRefresh can't be work."
- ).Add(
- "Can PullToRefresh be work?",
- () => {
- EnabledPullToRefresh.Value = true;
- }
- ).Add(
- "Has Refresh icon turned red?",
- () => {
- RefreshIconColor.Value = Color.Red;
- },
- () => {
- RefreshIconColor.Value = Color.DimGray;
- }
- ).Add(
- "Has RowSpacing become much larger?",
- () => {
- RowSpacing.Value = 25;
- },
- () => {
- RowSpacing.Value = 4;
- }
- ).Add(
- "Has ColumnHeight been changed to absolute value(250px)?",
- () => {
- ColumnHeight.Value = 250;
- }
- ).Add(
- "Has ColumnHeight been changed to relative value(0.5)?",
- () => {
- ColumnHeight.Value = 0.5;
- },
- () => {
- ColumnHeight.Value = 1.0;
- }
- ).Add(
- "Has ColumnHeight been changed to 1.0 + 50px by AdditionalHeight?",
- () => {
- AdditionalHeight.Value = 50;
- },
- () => {
- AdditionalHeight.Value = 0;
- }
- ).Add(
- "Has Background turned from Yellow to White to Green to transparent?",
- async () =>
- {
- Background.Value = Color.Yellow;
- await Task.Delay(1000);
- Background.Value = Color.White;
- await Task.Delay(1000);
- Background.Value = Color.Green;
- await Task.Delay(1000);
- Background.Value = Color.Transparent;
- }
- ).Add(
- "Tap some cells. Has FeedBack color turned Red?",
- () =>
- {
- FeedbackColor.Value = Color.Red;
- },
- () =>
- {
- FeedbackColor.Value = Color.Yellow;
- }
- ).Add(
- "UniformGrid Test1. GridType is UniformGrid. PortraitColumns are 2.",
- () => {
- GridType.Value = AiForms.Renderers.GridType.UniformGrid;
- PortraitColumns.Value = 2;
- }
- ).Add(
- "UniformGrid Test2. Has Colums number been changed 2 to 3 to 4 to 5 to 6 on Portrait?",
- async () => {
- PortraitColumns.Value = 3;
- await Task.Delay(1000);
- PortraitColumns.Value = 4;
- await Task.Delay(1000);
- PortraitColumns.Value = 5;
- await Task.Delay(1000);
- PortraitColumns.Value = 6;
- }
- ).Add(
- "UniformGrid Test3. Has ColumnSpacing been changed 0?",
- () => {
- ColumnSpacing.Value = 0;
- }
- ).Add(
- "UniformGrid Test4. Has Colums number been changed 6 to 5 to 4 to 3 to 2 on Portrait?",
- async () => {
- PortraitColumns.Value = 5;
- await Task.Delay(1000);
- PortraitColumns.Value = 4;
- await Task.Delay(1000);
- PortraitColumns.Value = 3;
- await Task.Delay(1000);
- PortraitColumns.Value = 2;
- }
- ).Add(
- "AutoSpacingGrid Test1. Column width is 150px. SpacingType is Between.",
- () => {
- GridType.Value = AiForms.Renderers.GridType.AutoSpacingGrid;
- ColumnWidth.Value = 150;
- SpacingType.Value = AiForms.Renderers.SpacingType.Between;
- ColumnSpacing.Value = 4;
- }
- ).Add(
- "AutoSpacingGrid Test2. Has Colum width been changed 150 to 120 to 90 to 60 with keeping Between?",
- async () => {
- ColumnWidth.Value = 120;
- await Task.Delay(1000);
- ColumnWidth.Value = 90;
- await Task.Delay(1000);
- ColumnWidth.Value = 60;
- }
- ).Add(
- "AutoSpacingGrid Test3. Has SpacingType been changed to Center?",
- () => {
- SpacingType.Value = AiForms.Renderers.SpacingType.Center;
- }
- ).Add(
- "AutoSpacingGrid Test4. Has Colum width been changed 60 to 90 to 120 to 150 with keeping Center?",
- async () => {
- ColumnWidth.Value = 90;
- await Task.Delay(1000);
- ColumnWidth.Value = 120;
- await Task.Delay(1000);
- ColumnWidth.Value = 150;
- }
- ).Add(
- "AutoSpacingGrid Test5. Has ColumnSpacing been changed 0?",
- () => {
- ColumnSpacing.Value = 0;
- }
- ).Add(
- "AutoSpacingGrid Test6. Has Colum width been changed 150 to 120 to 90 to 60 with keeping Center?",
- async () => {
- ColumnWidth.Value = 120;
- await Task.Delay(1000);
- ColumnWidth.Value = 90;
- await Task.Delay(1000);
- ColumnWidth.Value = 60;
- }
- ).Add(
- "UniformGrid Test5. Change Landscape",
- () => {
- GridType.Value = AiForms.Renderers.GridType.UniformGrid;
- ColumnSpacing.Value = 4;
- }
- ).Add(
- "UniformGrid Test6. Has Colums number been changed 5 to 6 to 7 to 8 on Landscape?",
- async () => {
- LandscapeColumns.Value = 6;
- await Task.Delay(1000);
- LandscapeColumns.Value = 7;
- await Task.Delay(1000);
- LandscapeColumns.Value = 8;
- await Task.Delay(1000);
- }
- ).Add(
- "UniformGrid Test7. Has ColumnSpacing been changed 0?",
- () => {
- ColumnSpacing.Value = 0;
- }
- ).Add(
- "UniformGrid Test8. Has Colums number been changed 8 to 7 to 6 to 5 to 4 on Landscape?",
- async () => {
- LandscapeColumns.Value = 7;
- await Task.Delay(1000);
- LandscapeColumns.Value = 6;
- await Task.Delay(1000);
- LandscapeColumns.Value = 5;
- await Task.Delay(1000);
- LandscapeColumns.Value = 4;
- }
- ).Add(
- "AutoSpacingGrid Test7. Landscape Test. SpacingType is Center and ColumnSpacing is 4.",
- () => {
- GridType.Value = AiForms.Renderers.GridType.AutoSpacingGrid;
- SpacingType.Value = AiForms.Renderers.SpacingType.Center;
- ColumnSpacing.Value = 4;
- }
- ).Add(
- "AutoSpacingGrid Test8. Has Colum width been changed 60 to 90 to 120 to 150 with keeping Center?",
- async () => {
- ColumnWidth.Value = 90;
- await Task.Delay(1000);
- ColumnWidth.Value = 120;
- await Task.Delay(1000);
- ColumnWidth.Value = 150;
- }
- ).Add(
- "AutoSpacingGrid Test9. Has SpacingType been changed to Between?",
- () => {
- SpacingType.Value = AiForms.Renderers.SpacingType.Between;
- }
- ).Add(
- "AutoSpacingGrid Test10. Has Colum width been changed 150 to 120 to 90 to 60 with keeping Between?",
- async () => {
- ColumnWidth.Value = 120;
- await Task.Delay(1000);
- ColumnWidth.Value = 90;
- await Task.Delay(1000);
- ColumnWidth.Value = 60;
- }
- );
+ public virtual void OnNavigatingTo(NavigationParameters parameters)
+ {
+ TestSections = parameters.GetValue>("tests");
+
+ _testEnumerator = TestSections.SelectMany(x => x).Where(y => y.Check.Value).SelectMany(z => z).GetEnumerator();
+
+ TestSections.ForEach(x => x.SetViewModel(this));
+
+ RaisePropertyChanged(nameof(TestSections));
}
public PhotoItem GetAdditionalItem()
@@ -277,100 +99,6 @@ public PhotoItem GetAdditionalItem()
};
}
- public virtual void IndividualTest()
- {
-
-
- TestList.Add("Test Start").Add(
- "Manipulation Test1. Has Title10 been scrolled to Top to Bottom To Center?",
- async () => {
- ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Start, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.End, false);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Center, false);
- }
- ).Add(
- "Manipulation Test2. Has Title10 been scrolled to Top to Bottom To Center with animation?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.End, true);
- await Task.Delay(2000);
- ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Center, true);
- }
- ).Add(
- "Manipulation Test3. Has new cell been inserted before Title1?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ItemsSource.Insert(0, GetAdditionalItem());
- }
- ).Add(
- "Manipulation Test4. Click + again. Has new cell been inserted after Title20?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.Last(), ScrollToPosition.End, true);
- await Task.Delay(2000);
- ItemsSource.Add(GetAdditionalItem());
- }
- ).Add(
- "Manipulation Test5. Click + again. Has new cell been inserted between Title8 and Title9?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource[8], ScrollToPosition.Center, true);
- await Task.Delay(2000);
- ItemsSource.Insert(9, GetAdditionalItem());
- }
- ).Add(
- "Manipulation Test4. Click -. Has the first cell been deleted?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ItemsSource.RemoveAt(0);
- }
- ).Add(
- "Manipulation Test6. Click - again. Has the last cell been deleted?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.Last(), ScrollToPosition.End, true);
- await Task.Delay(2000);
- ItemsSource.RemoveAt(ItemsSource.Count - 1);
- }
- ).Add(
- "Manipulation Test7. Click - again. Has the cell between Title8 and Title9 been deleted?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource[8], ScrollToPosition.Center, true);
- await Task.Delay(2000);
- ItemsSource.RemoveAt(8);
- }
- ).Add(
- "Manipulation Test8. Click R. Has the first cell been changed to AddItem?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ItemsSource[0] = GetAdditionalItem();
- }
- ).Add(
- "Manipulation Test9. Click M. Has the first cell been moved to after Title5?",
- async () => {
-
- ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
- await Task.Delay(2000);
- ItemsSource.Move(0, 4);
- }
- );
- }
-
void InitializeProperties()
{
@@ -404,80 +132,5 @@ void InitializeProperties()
IsRefreshing.Value = false;
});
}
-
- public virtual void InitializeCommand()
- {
- var addItem = new PhotoItem
- {
- PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/1.jpg",
- Title = $"AddItem",
- Category = "AAA"
- };
-
- var addPtn = 0;
- AddCommand.Subscribe(_ =>
- {
- switch (addPtn)
- {
- case 0:
- ItemsSource.Insert(0, addItem);
- break;
- case 1:
- ItemsSource.Add(addItem);
- break;
- case 2:
- ItemsSource.Insert(9, addItem);
- break;
-
- }
-
- addPtn++;
- if (addPtn > 2)
- {
- addPtn = 0;
- }
- });
-
- var delPtn = 0;
- DelCommand.Subscribe(_ =>
- {
- switch (delPtn)
- {
- case 0:
- ItemsSource.RemoveAt(0);
- break;
- case 1:
- ItemsSource.RemoveAt(ItemsSource.Count - 1);
- break;
- case 2:
- ItemsSource.RemoveAt(8);
- break;
- }
- delPtn++;
- if (delPtn > 2)
- {
- delPtn = 0;
- }
- });
-
- RepCommand.Subscribe(_ =>
- {
- ItemsSource[0] = addItem;
- });
-
- MoveCommand.Subscribe(_ =>
- {
- ItemsSource.Move(0, 4);
- });
- }
-
-
-
- public virtual void OnNavigatingTo(NavigationParameters parameters)
- {
- InitializeCommand();
- IndividualTest();
- CommontTest();
- }
}
}
diff --git a/Sample/Sample/ViewModels/DemoPageViewModel.cs b/Sample/Sample/ViewModels/DemoPageViewModel.cs
index 98ae1ff..4473112 100644
--- a/Sample/Sample/ViewModels/DemoPageViewModel.cs
+++ b/Sample/Sample/ViewModels/DemoPageViewModel.cs
@@ -2,12 +2,12 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
-using AiForms.Extras.Abstractions;
using Reactive.Bindings;
using Prism.Services;
using Sample.Views;
using Xamarin.Forms;
using AiForms.Renderers;
+using AiForms.Dialogs.Abstractions;
namespace Sample.ViewModels
{
diff --git a/Sample/Sample/ViewModels/GridGroupTestIndexViewModel.cs b/Sample/Sample/ViewModels/GridGroupTestIndexViewModel.cs
new file mode 100644
index 0000000..e329827
--- /dev/null
+++ b/Sample/Sample/ViewModels/GridGroupTestIndexViewModel.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Prism.Navigation;
+using Reactive.Bindings;
+using Sample.ViewModels.Tests;
+using Xamarin.Forms;
+
+namespace Sample.ViewModels
+{
+ public class GridGroupTestIndexViewModel
+ {
+ public ReactiveCommand RunCommand { get; } = new ReactiveCommand();
+ public ReactiveCommand AllCheckCommand { get; } = new ReactiveCommand();
+ public ReactiveCommand NoneCheckCommand { get; } = new ReactiveCommand();
+ public ReactiveCommand SaveCommand { get; } = new ReactiveCommand();
+
+ public List TestSections { get; } = new List();
+
+ public GridGroupTestIndexViewModel(INavigationService navigationService)
+ {
+ var Section = new TestSection { SectionTitle = "Fundamental" };
+ Section.Add(new PullToRefreshTest());
+ Section.Add(new RowSpacingAndHeightTest());
+ Section.Add(new ColorTest());
+
+ TestSections.Add(Section);
+
+ Section = new TestSection { SectionTitle = "GridType" };
+ Section.Add(new UniformGridTest());
+ Section.Add(new AutoSpacingTest());
+
+ TestSections.Add(Section);
+
+ Section = new TestSection { SectionTitle = "Individual" };
+ Section.Add(new GridGroupManipulationTest());
+
+ TestSections.Add(Section);
+
+ var groups = TestSections.SelectMany(x => x).ToList();
+
+
+ void CheckChange(bool turned)
+ {
+ foreach (var grp in groups)
+ {
+ grp.Check.Value = turned;
+ }
+ }
+
+ AllCheckCommand.Subscribe(_ => CheckChange(true));
+ NoneCheckCommand.Subscribe(_ => CheckChange(false));
+
+ SaveCommand.Subscribe(_ =>
+ {
+ for (var i = 0; i < groups.Count; i++)
+ {
+ Application.Current.Properties[$"grid_group_check{i}"] = groups[i].Check.Value;
+ }
+ Application.Current.SavePropertiesAsync();
+ });
+
+ for (var i = 0; i < groups.Count; i++)
+ {
+ if (Application.Current.Properties.TryGetValue($"grid_group_check{i}", out var check))
+ {
+ groups[i].Check.Value = (bool)check;
+ }
+ }
+
+ RunCommand.Subscribe(async _ =>
+ {
+ var param = new NavigationParameters();
+ param.Add("tests", TestSections);
+ await navigationService.NavigateAsync("CollectionViewGroupTest", param);
+ });
+ }
+ }
+}
diff --git a/Sample/Sample/ViewModels/GridTestIndexViewModel.cs b/Sample/Sample/ViewModels/GridTestIndexViewModel.cs
new file mode 100644
index 0000000..90d8c95
--- /dev/null
+++ b/Sample/Sample/ViewModels/GridTestIndexViewModel.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using Sample.ViewModels.Tests;
+using System.Linq;
+using Reactive.Bindings;
+using Xamarin.Forms;
+using Prism.Navigation;
+
+namespace Sample.ViewModels
+{
+ public class GridTestIndexViewModel
+ {
+ public ReactiveCommand RunCommand { get; } = new ReactiveCommand();
+ public ReactiveCommand AllCheckCommand { get; } = new ReactiveCommand();
+ public ReactiveCommand NoneCheckCommand { get; } = new ReactiveCommand();
+ public ReactiveCommand SaveCommand { get; } = new ReactiveCommand();
+
+ public List TestSections { get; } = new List();
+ public GridTestIndexViewModel(INavigationService navigationService)
+ {
+ var Section = new TestSection { SectionTitle = "Fundamental" };
+ Section.Add(new PullToRefreshTest());
+ Section.Add(new RowSpacingAndHeightTest());
+ Section.Add(new ColorTest());
+
+ TestSections.Add(Section);
+
+ Section = new TestSection { SectionTitle = "GridType" };
+ Section.Add(new UniformGridTest());
+ Section.Add(new AutoSpacingTest());
+
+ TestSections.Add(Section);
+
+ Section = new TestSection { SectionTitle = "Individual" };
+ Section.Add(new GridManipulationTest());
+
+ TestSections.Add(Section);
+
+ var groups = TestSections.SelectMany(x => x).ToList();
+
+
+ void CheckChange(bool turned)
+ {
+ foreach (var grp in groups)
+ {
+ grp.Check.Value = turned;
+ }
+ }
+
+ AllCheckCommand.Subscribe(_ => CheckChange(true));
+ NoneCheckCommand.Subscribe(_ => CheckChange(false));
+
+ SaveCommand.Subscribe(_ =>
+ {
+ for (var i = 0; i < groups.Count; i++)
+ {
+ Application.Current.Properties[$"check{i}"] = groups[i].Check.Value;
+ }
+ Application.Current.SavePropertiesAsync();
+ });
+
+ for (var i = 0; i < groups.Count; i++)
+ {
+ if (Application.Current.Properties.TryGetValue($"check{i}", out var check))
+ {
+ groups[i].Check.Value = (bool)check;
+ }
+ }
+
+ RunCommand.Subscribe(async _ =>
+ {
+ var param = new NavigationParameters();
+ param.Add("tests", TestSections);
+ await navigationService.NavigateAsync("CollectionViewTest", param);
+ });
+ }
+ }
+}
diff --git a/Sample/Sample/ViewModels/HCollectionViewTestViewModel.cs b/Sample/Sample/ViewModels/HCollectionViewTestViewModel.cs
index 07055d5..89d9c1f 100644
--- a/Sample/Sample/ViewModels/HCollectionViewTestViewModel.cs
+++ b/Sample/Sample/ViewModels/HCollectionViewTestViewModel.cs
@@ -34,6 +34,8 @@ public class HCollectionViewTestViewModel
public ReactivePropertySlim Spacing { get; } = new ReactivePropertySlim(5);
public ReactivePropertySlim GroupWidth { get; } = new ReactivePropertySlim(50);
public ReactivePropertySlim IsInfinite { get; } = new ReactivePropertySlim(false);
+ public ReactivePropertySlim GroupFirstSpacing { get; } = new ReactivePropertySlim(0);
+ public ReactivePropertySlim GroupLastSpacing { get; } = new ReactivePropertySlim(0);
public IScrollController ScrollController {get;set;}
public IScrollController ScrollController2 { get; set; }
@@ -237,6 +239,18 @@ public HCollectionViewTestViewModel(IPageDialogService pageDialog)
{
Spacing.Value /= 2;
}
+ ).Add(
+ "Has Group First Spacing been 30px in Grouped?",
+ () =>
+ {
+ GroupFirstSpacing.Value = 30;
+ }
+ ).Add(
+ "Has Group Last Spacing been 30px in Grouped?",
+ () =>
+ {
+ GroupLastSpacing.Value = 30;
+ }
).Add(
"Has Column width been twice as large as previous?",
() =>
diff --git a/Sample/Sample/ViewModels/TestFormViewModel.cs b/Sample/Sample/ViewModels/TestFormViewModel.cs
index 026595d..5692fce 100644
--- a/Sample/Sample/ViewModels/TestFormViewModel.cs
+++ b/Sample/Sample/ViewModels/TestFormViewModel.cs
@@ -4,6 +4,12 @@
using Unity.Attributes;
using Prism.Services;
using System.Linq;
+using Xamarin.Forms;
+using System.Reflection;
+using System.Threading.Tasks;
+using Sample.Views;
+using AiForms.Dialogs;
+
namespace Sample.ViewModels
{
public class TestFormViewModel
@@ -71,5 +77,78 @@ public class TestItem
public bool Result { get; set; }
public Action Action { get; set; }
public Action CancelAction { get; set; }
+
+ public bool IsFirstItem { get; set; }
+ public bool IsLastItem { get; set; }
+ public LayoutAlignment VAlign { get; set; } = LayoutAlignment.Center;
+ public TestGroup Parent { get; set; }
+
+ public async void Run()
+ {
+ if(IsFirstItem)
+ {
+ Toast.Instance.Show(new {Message=Parent.GroupTitle,VAlign=LayoutAlignment.Start});
+ Parent?.Initialize();
+ await Task.Delay(500);
+ }
+ Toast.Instance.Show(this);
+ Parent.SetUp();
+ await Task.Delay(500);
+ Action?.Invoke();
+
+ if(IsLastItem)
+ {
+ Parent?.Destroy();
+ }
+ }
+ }
+
+ public class TestAttribute:Attribute{
+ public string Message { get; set; }
+ }
+
+ public class TestGroup:List
+ {
+ public CollectionViewTestViewModel VM { get; set; }
+ public string GroupTitle { get; set; }
+ public ReactivePropertySlim Check { get; } = new ReactivePropertySlim();
+
+
+ public TestGroup(string groupTitle)
+ {
+ GroupTitle = groupTitle;
+ var methods = this.GetType().GetMethods().Where(x => x.GetCustomAttribute() != null);
+
+ foreach (var method in methods)
+ {
+ var methodAction = (Action)method.CreateDelegate(typeof(Action), this);
+ var testAttr = method.GetCustomAttribute();
+
+ Add(new TestItem { Parent = this,Action = methodAction, Message = testAttr.Message });
+ }
+
+ this[0].IsFirstItem = true;
+ this[methods.Count() - 1].IsLastItem = true;
+ }
+
+ public virtual void Initialize(){}
+
+ public virtual void Destroy(){}
+
+ public virtual void SetUp(){}
+
+ }
+
+ public class TestSection:List
+ {
+ public string SectionTitle { get; set; }
+
+ public void SetViewModel(CollectionViewTestViewModel vm)
+ {
+ foreach(var group in this)
+ {
+ group.VM = vm;
+ }
+ }
}
}
diff --git a/Sample/Sample/ViewModels/Tests/AutoSpacingTest.cs b/Sample/Sample/ViewModels/Tests/AutoSpacingTest.cs
new file mode 100644
index 0000000..c9f3991
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/AutoSpacingTest.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Sample.ViewModels.Tests
+{
+ public class AutoSpacingTest:TestGroup
+ {
+ public AutoSpacingTest():base("AutoSpacing")
+ {
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ VM.GridType.Value = AiForms.Renderers.GridType.AutoSpacingGrid;
+ VM.ColumnWidth.Value = 150;
+ VM.SpacingType.Value = AiForms.Renderers.SpacingType.Between;
+ VM.ColumnSpacing.Value = 4;
+ }
+
+ public override void Destroy()
+ {
+ base.Destroy();
+ Initialize();
+ }
+
+ [Test(Message = "Has Colum width been changed 150 to 120 to 90 to 60 with keeping Between?")]
+ public async void ColumnNumberDecrement()
+ {
+ VM.ColumnWidth.Value = 120;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 90;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 60;
+ }
+
+ [Test(Message = "Has SpacingType been changed to Center?")]
+ public void ChangeTypeCenter()
+ {
+ VM.SpacingType.Value = AiForms.Renderers.SpacingType.Center;
+ }
+
+ [Test(Message = "Has Colum width been changed 60 to 90 to 120 to 150 with keeping Center?")]
+ public async void ColumnNumberIncrement()
+ {
+ VM.ColumnWidth.Value = 90;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 120;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 150;
+ }
+
+ [Test(Message = "Has ColumnSpacing been changed 0?")]
+ public void ChangeSpacing0()
+ {
+ VM.ColumnSpacing.Value = 0;
+ }
+
+ [Test(Message = "Has Colum width been changed 150 to 120 to 90 to 60 with keeping Center?")]
+ public async void ColumnNumberDecrement2()
+ {
+ VM.ColumnWidth.Value = 120;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 90;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 60;
+ }
+
+ [Test(Message = "Change Landscape.")]
+ public void ChangeLandscape()
+ {
+ VM.ColumnSpacing.Value = 4;
+ }
+
+ [Test(Message = "Has Colum width been changed 60 to 90 to 120 to 150 with keeping Center?")]
+ public async void ColumnNumberIncrement2()
+ {
+ VM.ColumnWidth.Value = 90;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 120;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 150;
+ }
+
+ [Test(Message = "Has SpacingType been changed to Between?")]
+ public void ChnageBetweeen()
+ {
+ VM.SpacingType.Value = AiForms.Renderers.SpacingType.Between;
+ }
+
+ [Test(Message = "Has Colum width been changed 150 to 120 to 90 to 60 with keeping Between?")]
+ public async void ColumnNumberDecrement3()
+ {
+ VM.ColumnWidth.Value = 120;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 90;
+ await Task.Delay(1000);
+ VM.ColumnWidth.Value = 60;
+ }
+
+ [Test(Message = "Change Portrait")]
+ public void ChangePortrait(){}
+ }
+}
diff --git a/Sample/Sample/ViewModels/Tests/ColorTest.cs b/Sample/Sample/ViewModels/Tests/ColorTest.cs
new file mode 100644
index 0000000..951d500
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/ColorTest.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+
+namespace Sample.ViewModels.Tests
+{
+ public class ColorTest:TestGroup
+ {
+ public ColorTest():base("Color")
+ {
+ }
+
+ public override void SetUp()
+ {
+ base.SetUp();
+ VM.Background.Value = Color.White;
+ VM.FeedbackColor.Value = Color.Yellow;
+ }
+
+ [Test(Message = "Has Background turned from Yellow to White to Green to transparent?")]
+ public async void BackgroundColor()
+ {
+ VM.Background.Value = Color.Yellow;
+ await Task.Delay(1000);
+ VM.Background.Value = Color.White;
+ await Task.Delay(1000);
+ VM.Background.Value = Color.Green;
+ await Task.Delay(1000);
+ VM.Background.Value = Color.Transparent;
+ }
+
+ [Test(Message = "Tap some cells. Has FeedBack color turned Red?")]
+ public void FeedbackColor()
+ {
+ VM.FeedbackColor.Value = Color.Red;
+ }
+ }
+}
diff --git a/Sample/Sample/ViewModels/Tests/GridGroupManipulationTest.cs b/Sample/Sample/ViewModels/Tests/GridGroupManipulationTest.cs
new file mode 100644
index 0000000..6f5efe8
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/GridGroupManipulationTest.cs
@@ -0,0 +1,171 @@
+using System;
+using System.Threading.Tasks;
+using AiForms.Renderers;
+using System.Collections.ObjectModel;
+using Xamarin.Forms;
+using System.Collections.Generic;
+
+namespace Sample.ViewModels.Tests
+{
+ public class GridGroupManipulationTest:TestGroup
+ {
+
+ IScrollController ScrollController => VM.ScrollController;
+ PhotoGroup ItemsSource => VM.ItemsSource;
+ ObservableCollection ItemsGroupSource => VM.ItemsGroupSource;
+ PhotoGroup _additionalGroup;
+
+ public GridGroupManipulationTest():base("GridGroupManipulation")
+ {
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ var list = new List();
+ for (var i = 5; i < 15; i++)
+ {
+ list.Add(new PhotoItem
+ {
+ PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg",
+ Title = $"Title {i + 1}",
+ Category = "DDD",
+ });
+ }
+ _additionalGroup = new PhotoGroup(list) { Head = "SectionD" };
+
+ }
+
+ [Test(Message = "Has SectionB been scrolled to Top to Bottom To Center?")]
+ public async void ScrollTest()
+ {
+ ScrollController.ScrollToStart();
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Start, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.End, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Center, false);
+ }
+
+ [Test(Message = "Has SectionB been scrolled to Top to Bottom To Center with animation?")]
+ public async void ScrollTest2()
+ {
+ ScrollController.ScrollToStart(true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[1][0], ItemsGroupSource[1], ScrollToPosition.Center, true);
+ }
+
+ [Test(Message = "Has SectionC - Title14 been scrolled to Top to Bottom To Center?")]
+ public async void ScrollTest3()
+ {
+ ScrollController.ScrollToStart(false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Start, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.End, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Center, false);
+ }
+
+ [Test(Message = "Has SectionC - Title14 been scrolled to Top to Bottom To Center with animation?")]
+ public async void ScrollTest4()
+ {
+ ScrollController.ScrollToStart(true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsGroupSource[2][3], ItemsGroupSource[2], ScrollToPosition.Center, true);
+ }
+
+ [Test(Message = "Has new cell been inserted before Title1?")]
+ public async void InsertTest()
+ {
+ ScrollController.ScrollToStart(true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].Insert(0, VM.GetAdditionalItem());
+ }
+
+ [Test(Message = "Has new cell been inserted after Title20?")]
+ public async void InsertTest2()
+ {
+ ScrollController.ScrollTo(ItemsGroupSource[0][20], ItemsGroupSource[0], ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].Add(VM.GetAdditionalItem());
+ }
+
+ [Test(Message = "Has new cell been inserted between Title8 and Title9?")]
+ public async void InsertTest3()
+ {
+ ScrollController.ScrollTo(ItemsGroupSource[0][8], ItemsGroupSource[0], ScrollToPosition.Center, true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].Insert(9, VM.GetAdditionalItem());
+ }
+
+ [Test(Message = "Has the first cell been deleted?")]
+ public async void DeleteTest()
+ {
+ ScrollController.ScrollToStart(true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].RemoveAt(0);
+ }
+
+ [Test(Message = "Has the last cell in SectionA been deleted?")]
+ public async void DeleteTest2()
+ {
+ ScrollController.ScrollTo(ItemsGroupSource[0][21], ItemsGroupSource[0], ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].RemoveAt(ItemsGroupSource[0].Count - 1);
+ }
+
+ [Test(Message = "Has the cell between Title8 and Title9 in SectionA been deleted?")]
+ public async void DeleteTest3()
+ {
+ ScrollController.ScrollTo(ItemsGroupSource[0][8], ItemsGroupSource[0], ScrollToPosition.Center, true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].RemoveAt(8);
+ }
+
+ [Test(Message = "Has the first cell been changed to AddItem?")]
+ public async void ReplaceTest()
+ {
+ ScrollController.ScrollToStart(true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0][0] = VM.GetAdditionalItem();
+ }
+
+ [Test(Message = "Has the first cell been moved to after Title5?")]
+ public async void MoveTest()
+ {
+ ScrollController.ScrollToStart(true);
+ await Task.Delay(2000);
+ ItemsGroupSource[0].Move(0, 4);
+ }
+
+ [Test(Message = "Has new section been inserted at last?")]
+ public async void SectionInsertTest()
+ {
+ await Task.Delay(2000);
+ ItemsGroupSource.Add(_additionalGroup);
+ await Task.Delay(2000);
+ ScrollController.ScrollToEnd(true);
+ }
+
+ [Test(Message = "Has the last section been deleted?")]
+ public async void SectionDeleteTest()
+ {
+ await Task.Delay(2000);
+ ItemsGroupSource.Remove(_additionalGroup);
+ await Task.Delay(2000);
+ ScrollController.ScrollToEnd(true);
+ }
+
+
+ }
+}
diff --git a/Sample/Sample/ViewModels/Tests/GridManipulationTest.cs b/Sample/Sample/ViewModels/Tests/GridManipulationTest.cs
new file mode 100644
index 0000000..bc4ccb5
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/GridManipulationTest.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using AiForms.Renderers;
+using Xamarin.Forms;
+
+namespace Sample.ViewModels.Tests
+{
+ public class GridManipulationTest:TestGroup
+ {
+ IScrollController ScrollController => VM.ScrollController;
+ PhotoGroup ItemsSource => VM.ItemsSource;
+
+ public GridManipulationTest():base("GridManipulation")
+ {
+ }
+
+ [Test(Message = "Has Title10 been scrolled to Top to Bottom To Center?")]
+ public async void ScrollTest()
+ {
+ ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Start, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.End, false);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Center, false);
+ }
+
+ [Test(Message = "Has Title10 been scrolled to Top to Bottom To Center with animation?")]
+ public async void ScrollAnimeTest()
+ {
+ ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ScrollController.ScrollTo(ItemsSource[9], ScrollToPosition.Center, true);
+ }
+
+ [Test(Message = "Has new cell been inserted before Title1?")]
+ public async void InsertTest()
+ {
+ ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ItemsSource.Insert(0, VM.GetAdditionalItem());
+ }
+
+ [Test(Message = "Has new cell been inserted after Title20?")]
+ public async void InsertTest2()
+ {
+ ScrollController.ScrollTo(ItemsSource.Last(), ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ItemsSource.Add(VM.GetAdditionalItem());
+ }
+
+ [Test(Message = "Has new cell been inserted between Title8 and Title9?")]
+ public async void InsertTest3()
+ {
+ ScrollController.ScrollTo(ItemsSource[8], ScrollToPosition.Center, true);
+ await Task.Delay(2000);
+ ItemsSource.Insert(9, VM.GetAdditionalItem());
+ }
+
+ [Test(Message = "Has the first cell been deleted?")]
+ public async void DeleteTest()
+ {
+ ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ItemsSource.RemoveAt(0);
+ }
+
+ [Test(Message = "Has the last cell been deleted?")]
+ public async void DeleteTest2()
+ {
+ ScrollController.ScrollTo(ItemsSource.Last(), ScrollToPosition.End, true);
+ await Task.Delay(2000);
+ ItemsSource.RemoveAt(ItemsSource.Count - 1);
+ }
+
+ [Test(Message = "Has the cell between Title8 and Title9 been deleted?")]
+ public async void DeleteTest3()
+ {
+ ScrollController.ScrollTo(ItemsSource[8], ScrollToPosition.Center, true);
+ await Task.Delay(2000);
+ ItemsSource.RemoveAt(8);
+ }
+
+ [Test(Message = "Has the first cell been changed to AddItem?")]
+ public async void ReplaceTest()
+ {
+ ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ItemsSource[0] = VM.GetAdditionalItem();
+ }
+
+ [Test(Message = "Has the first cell been moved to after Title5?")]
+ public async void MoveTest()
+ {
+ ScrollController.ScrollTo(ItemsSource.First(), ScrollToPosition.Start, true);
+ await Task.Delay(2000);
+ ItemsSource.Move(0, 4);
+ }
+ }
+}
diff --git a/Sample/Sample/ViewModels/Tests/PullToRefreshTest.cs b/Sample/Sample/ViewModels/Tests/PullToRefreshTest.cs
new file mode 100644
index 0000000..7fdf179
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/PullToRefreshTest.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+
+namespace Sample.ViewModels.Tests
+{
+ public class PullToRefreshTest:TestGroup
+ {
+ public PullToRefreshTest():base("PullToRefresh"){}
+
+ public override void SetUp()
+ {
+ base.SetUp();
+ VM.EnabledPullToRefresh.Value = true;
+ VM.RefreshIconColor.Value = Color.DimGray;
+ }
+
+ [Test(Message = "PullToRefresh can't be work.")]
+ public void Disabled()
+ {
+ VM.EnabledPullToRefresh.Value = false;
+ }
+
+ [Test(Message = "Can PullToRefresh be work?")]
+ public void Enabled()
+ {
+ VM.EnabledPullToRefresh.Value = true;
+ }
+
+ [Test(Message = "Has Refresh icon turned red?")]
+ public void TurnIconColor()
+ {
+ VM.RefreshIconColor.Value = Color.Red;
+ }
+ }
+}
diff --git a/Sample/Sample/ViewModels/Tests/RowSpacingAndHeightTest.cs b/Sample/Sample/ViewModels/Tests/RowSpacingAndHeightTest.cs
new file mode 100644
index 0000000..8d6c3da
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/RowSpacingAndHeightTest.cs
@@ -0,0 +1,72 @@
+using System;
+namespace Sample.ViewModels.Tests
+{
+ public class RowSpacingAndHeightTest:TestGroup
+ {
+ public RowSpacingAndHeightTest():base("RowSpacingAndHeight")
+ {
+ }
+
+ public override void SetUp()
+ {
+ base.SetUp();
+ VM.RowSpacing.Value = 4.0;
+ VM.GroupFirstSpacing.Value = 0;
+ VM.GroupLastSpacing.Value = 0;
+ VM.ColumnHeight.Value = 1.0;
+ VM.IsGroupHeaderSticky.Value = true;
+ VM.AdditionalHeight.Value = 0;
+ VM.HeaderHeight.Value = 36;
+ }
+
+ [Test(Message = "Has RowSpacing become much larger?")]
+ public void RowSpacing()
+ {
+ VM.RowSpacing.Value = 25;
+ }
+
+ [Test(Message = "Has Group First Spacing been 30px in Grouped?")]
+ public void FirstSpacing()
+ {
+ VM.GroupFirstSpacing.Value = 30;
+ }
+
+ [Test(Message = "Has Group Last Spacing been 30px in Grouped?")]
+ public void LastSpacing()
+ {
+ VM.GroupLastSpacing.Value = 30;
+ }
+
+ [Test(Message = "Has ColumnHeight been changed to absolute value(250px)?")]
+ public void ColumnHeightAbsolute()
+ {
+ VM.ColumnHeight.Value = 250;
+ }
+
+ [Test(Message = "Has ColumnHeight been changed to relative value(0.5)?")]
+ public void ColumnHeightProportional()
+ {
+ VM.ColumnHeight.Value = 0.5;
+ }
+
+ [Test(Message = "Has ColumnHeight been changed to 1.0 + 50px by AdditionalHeight?")]
+ public void AdditionalHeight()
+ {
+ VM.AdditionalHeight.Value = 50;
+ }
+
+ [Test(Message = "Has GroupHeaderHeight been twice as large as the privious?")]
+ public void GroupHeaderHeight()
+ {
+ VM.HeaderHeight.Value *= 2;
+ }
+
+
+ [Test(Message = "Has HeaderCell position been released from sticky? (iOS)")]
+ public void Sticky()
+ {
+ VM.IsGroupHeaderSticky.Value = false;
+ }
+
+ }
+}
diff --git a/Sample/Sample/ViewModels/Tests/UniformGridTest.cs b/Sample/Sample/ViewModels/Tests/UniformGridTest.cs
new file mode 100644
index 0000000..1326772
--- /dev/null
+++ b/Sample/Sample/ViewModels/Tests/UniformGridTest.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Sample.ViewModels.Tests
+{
+ public class UniformGridTest : TestGroup
+ {
+ public UniformGridTest() : base("UniformGrid")
+ {
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ VM.GridType.Value = AiForms.Renderers.GridType.UniformGrid;
+ VM.PortraitColumns.Value = 2;
+ VM.LandscapeColumns.Value = 4;
+ VM.BothSidesMargin.Value = 10;
+ VM.ColumnSpacing.Value = 4;
+ }
+
+ public override void Destroy()
+ {
+ base.Destroy();
+ Initialize();
+ }
+
+ public override void SetUp()
+ {
+ base.SetUp();
+ }
+
+ [Test(Message = "Has Colums number been changed 2 to 3 to 4 to 5 to 6 on Portrait?")]
+ public async void ColumnNumberIncrement()
+ {
+ VM.PortraitColumns.Value = 3;
+ await Task.Delay(1000);
+ VM.PortraitColumns.Value = 4;
+ await Task.Delay(1000);
+ VM.PortraitColumns.Value = 5;
+ await Task.Delay(1000);
+ VM.PortraitColumns.Value = 6;
+ }
+
+ [Test(Message = "Has ColumnSpacing / BothSidesMargin been changed 0?")]
+ public void SpacingAndMargin()
+ {
+ VM.ColumnSpacing.Value = 0;
+ VM.BothSidesMargin.Value = 0;
+ }
+
+ [Test(Message = "Has Colums number been changed 6 to 5 to 4 to 3 to 2 on Portrait?")]
+ public async void ColumnNumberDecrement()
+ {
+ VM.PortraitColumns.Value = 5;
+ await Task.Delay(1000);
+ VM.PortraitColumns.Value = 4;
+ await Task.Delay(1000);
+ VM.PortraitColumns.Value = 3;
+ await Task.Delay(1000);
+ VM.PortraitColumns.Value = 2;
+ }
+
+ [Test(Message = "Change Landscape. Is Columns number 4?")]
+ public void ChangeLandscape() { }
+
+ [Test(Message = "Has Colums number been changed 5 to 6 to 7 to 8 on Landscape?")]
+ public async void LandscapeColumnNumber()
+ {
+ VM.LandscapeColumns.Value = 5;
+ await Task.Delay(1000);
+ VM.LandscapeColumns.Value = 6;
+ await Task.Delay(1000);
+ VM.LandscapeColumns.Value = 7;
+ await Task.Delay(1000);
+ VM.LandscapeColumns.Value = 8;
+ await Task.Delay(1000);
+ }
+
+ [Test(Message = "Have ColumnSpacing and BothSidesMargin been changed 4 and 10?")]
+ public void SpacingAndMargin2()
+ {
+ VM.ColumnSpacing.Value = 4;
+ VM.BothSidesMargin.Value = 10;
+ }
+
+ [Test(Message = "Has Colums number been changed 8 to 7 to 6 to 5 to 4 on Landscape?")]
+ public async void LandscapeColumnNumber2()
+ {
+ VM.LandscapeColumns.Value = 7;
+ await Task.Delay(1000);
+ VM.LandscapeColumns.Value = 6;
+ await Task.Delay(1000);
+ VM.LandscapeColumns.Value = 5;
+ await Task.Delay(1000);
+ VM.LandscapeColumns.Value = 4;
+ }
+
+ [Test(Message = "Change Portrait")]
+ public void ChangePortrait() { }
+ }
+}
diff --git a/Sample/Sample/Views/CollectionVIewTest.xaml b/Sample/Sample/Views/CollectionVIewTest.xaml
index 2b56a27..9f036d5 100644
--- a/Sample/Sample/Views/CollectionVIewTest.xaml
+++ b/Sample/Sample/Views/CollectionVIewTest.xaml
@@ -8,74 +8,67 @@
x:Class="Sample.Views.CollectionViewTest">
-
+
+
+
-
-
-
- RecycleElement
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ RecycleElement
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sample/Sample/Views/CollectionViewGroupTest.xaml b/Sample/Sample/Views/CollectionViewGroupTest.xaml
index 8e8cb16..ed2ec7c 100644
--- a/Sample/Sample/Views/CollectionViewGroupTest.xaml
+++ b/Sample/Sample/Views/CollectionViewGroupTest.xaml
@@ -7,84 +7,74 @@
xmlns:ff="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
x:Class="Sample.Views.CollectionViewGroupTest">
-
-
-
-
-
-
+
+
+
-
-
-
- RecycleElement
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ RecycleElement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
diff --git a/Sample/Sample/Views/GridGroupTestIndex.xaml b/Sample/Sample/Views/GridGroupTestIndex.xaml
new file mode 100644
index 0000000..f12fc87
--- /dev/null
+++ b/Sample/Sample/Views/GridGroupTestIndex.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sample/Sample/Views/GridGroupTestIndex.xaml.cs b/Sample/Sample/Views/GridGroupTestIndex.xaml.cs
new file mode 100644
index 0000000..044498a
--- /dev/null
+++ b/Sample/Sample/Views/GridGroupTestIndex.xaml.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+
+using Xamarin.Forms;
+
+namespace Sample.Views
+{
+ public partial class GridGroupTestIndex : ContentPage
+ {
+ public GridGroupTestIndex()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Sample/Sample/Views/GridTestIndex.xaml b/Sample/Sample/Views/GridTestIndex.xaml
new file mode 100644
index 0000000..48ea251
--- /dev/null
+++ b/Sample/Sample/Views/GridTestIndex.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sample/Sample/Views/GridTestIndex.xaml.cs b/Sample/Sample/Views/GridTestIndex.xaml.cs
new file mode 100644
index 0000000..3772218
--- /dev/null
+++ b/Sample/Sample/Views/GridTestIndex.xaml.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+
+using Xamarin.Forms;
+
+namespace Sample.Views
+{
+ public partial class GridTestIndex : ContentPage
+ {
+ public GridTestIndex()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Sample/Sample/Views/HCollectionViewTest.xaml b/Sample/Sample/Views/HCollectionViewTest.xaml
index c075cfc..e9e70ab 100644
--- a/Sample/Sample/Views/HCollectionViewTest.xaml
+++ b/Sample/Sample/Views/HCollectionViewTest.xaml
@@ -17,6 +17,8 @@
-
-
+
+
+
diff --git a/Sample/Sample/Views/MyToastView.xaml b/Sample/Sample/Views/MyToastView.xaml
index f946dbf..6305987 100644
--- a/Sample/Sample/Views/MyToastView.xaml
+++ b/Sample/Sample/Views/MyToastView.xaml
@@ -2,8 +2,8 @@
+ xmlns:extra="clr-namespace:AiForms.Dialogs.Abstractions;assembly=AiForms.Dialogs.Abstractions"
+ x:Class="Sample.Views.MyToastView" Padding="6" VerticalLayoutAlignment="{Binding VAlign}">
diff --git a/Sample/Sample/Views/MyToastView.xaml.cs b/Sample/Sample/Views/MyToastView.xaml.cs
index 566b721..6ab7d37 100644
--- a/Sample/Sample/Views/MyToastView.xaml.cs
+++ b/Sample/Sample/Views/MyToastView.xaml.cs
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
-using AiForms.Extras.Abstractions;
using Xamarin.Forms;
using System.Threading.Tasks;
+using AiForms.Dialogs.Abstractions;
namespace Sample.Views
{
@@ -11,20 +11,10 @@ public partial class MyToastView : ToastView
public MyToastView()
{
InitializeComponent();
- ToastWidth = 0.9;
- ToastHeight = 30;
- Duration = 2000;
- LayoutAlignment = LayoutAlignment.Center;
+ Duration = 3500;
BackgroundColor = Color.FromRgba(0, 0, 0, 0.8);
- Opacity = 0;
+ OffsetY = 50;
CornerRadius = 5;
- TranslationY = 30;
- }
-
- public override void RunPresentationAnimation()
- {
- Task.WhenAll(
- this.FadeTo(1),this.TranslateTo(0,0));
}
}
}
diff --git a/nuget/AzurePipelines.nuspec b/nuget/AzurePipelines.nuspec
new file mode 100644
index 0000000..7376ad0
--- /dev/null
+++ b/nuget/AzurePipelines.nuspec
@@ -0,0 +1,78 @@
+
+
+
+ AiForms.CollectionView
+ 0.2.1-pre
+ CollectionView for Xamarin.Forms
+ kamu
+ kamu
+ https://github.com/muak/AiForms.CollectionView
+ https://github.com/muak/AiForms.CollectionView/blob/master/LICENSE.txt
+ false
+ This is a flexible ListView that has a grid and horizontal layout with reusable cells for Android / iOS.
+This has two layouts (GridCollectionView, HorizontalCollectonView). HorizontalCollectonView can circulate scroll.
+
+
+
+## Bug fixes
+
+* [iOS][GridCollectionView] When a item just exists in ItemsSource, it is arranged at center.
+* some bug fixes
+
+## New Properties
+
+### GridCollectionView / HCollectionView
+
+* GroupFirstSpacing – The spacing of the first item's top or left in a group.
+* GroupLastSpacing – The spacing of the last item's bottom or right in a group.
+
+### GridCollectionView
+
+* BothSidesMargin – The margin of the right and left sides in the content area except for a group header cell.
+* IsGroupHeaderSticky – Whether a group header is fixed at the top. (iOS only) (default: true)
+
+ Xamarin.Forms ListView CollectionView Grid Infinite Circular Scroll UICollectionView RecyclerView FlowLayout WrapLayout HorizontalListView
+ en-US
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nuget/CollectionView_mac.nuspec b/nuget/CollectionView_mac.nuspec
index 5bf375b..927b6f7 100644
--- a/nuget/CollectionView_mac.nuspec
+++ b/nuget/CollectionView_mac.nuspec
@@ -2,7 +2,7 @@
AiForms.CollectionView
- 0.1.0-pre3
+ 0.2.1-pre
CollectionView for Xamarin.Forms
kamu
kamu
@@ -14,7 +14,22 @@ This has two layouts (GridCollectionView, HorizontalCollectonView). HorizontalCo
-Some bug fixes
+## Bug fixes
+
+* [iOS][GridCollectionView] When a item just exists in ItemsSource, it is arranged at center.
+* some bug fixes
+
+## New Properties
+
+### GridCollectionView / HCollectionView
+
+* GroupFirstSpacing – The spacing of the first item's top or left in a group.
+* GroupLastSpacing – The spacing of the last item's bottom or right in a group.
+
+### GridCollectionView
+
+* BothSidesMargin – The margin of the right and left sides in the content area except for a group header cell.
+* IsGroupHeaderSticky – Whether a group header is fixed at the top. (iOS only) (default: true)
Xamarin.Forms ListView CollectionView Grid Infinite Circular Scroll UICollectionView RecyclerView FlowLayout WrapLayout HorizontalListView
en-US