├── .gitignore ├── AiForms.CollectionView.sln ├── CollectionView.Droid ├── Cells │ ├── ContentCellContainer.cs │ └── ContentCellRenderer.cs ├── CollectionView.Droid.csproj ├── CollectionViewAdapter.cs ├── CollectionViewRenderer.cs ├── CollectionViewScrollListener.cs ├── DrawableUtility.cs ├── GridCollectionViewRenderer.cs ├── HCollectionViewAdapter.cs ├── HCollectionViewRenderer.cs ├── ICollectionViewRenderer.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ └── values │ │ └── Strings.xml ├── SelectableSmoothScroller.cs └── ViewHolder.cs ├── CollectionView.iOS ├── Cells │ ├── ContentCellContainer.cs │ └── ContentCellRenderer.cs ├── CollectionView.iOS.csproj ├── CollectionViewInit.cs ├── CollectionViewRenderer.cs ├── CollectionViewSource.cs ├── GridCollectionViewRenderer.cs ├── GridCollectionViewSource.cs ├── GridViewLayout.cs ├── HCollectionViewRenderer.cs ├── HCollectionViewSource.cs ├── KeyboardInsetTracker.cs └── Properties │ └── AssemblyInfo.cs ├── CollectionView ├── Cells │ └── ContentCell.cs ├── CollectionView.cs ├── CollectionView.csproj ├── GridCollectionView.cs ├── HCollectionView.cs ├── Properties │ └── AssemblyInfo.cs └── ScrollController.cs ├── LICENSE.txt ├── README-ja.md ├── README.md ├── Sample ├── Sample.Droid │ ├── Assets │ │ └── AboutAssets.txt │ ├── MainActivity.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── drawable-hdpi │ │ │ └── icon.png │ │ ├── drawable-xhdpi │ │ │ └── icon.png │ │ ├── drawable-xxhdpi │ │ │ └── icon.png │ │ ├── drawable │ │ │ └── icon.png │ │ ├── layout │ │ │ ├── Tabbar.axml │ │ │ └── Toolbar.axml │ │ └── values │ │ │ └── styles.xml │ ├── Sample.Droid.csproj │ └── monoEnv.txt ├── Sample.iOS │ ├── AppDelegate.cs │ ├── Entitlements.plist │ ├── Info.plist │ ├── Main.cs │ ├── Resources │ │ ├── Images.xcassets │ │ │ └── AppIcons.appiconset │ │ │ │ └── Contents.json │ │ ├── LaunchScreen.xib │ │ ├── icon4@3x.png │ │ └── icon@3x.png │ └── Sample.iOS.csproj ├── Sample.sln └── Sample │ ├── App.xaml │ ├── App.xaml.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Resources │ ├── android-cloud-circle.svg │ ├── android-color-palette.svg │ ├── android-contact.svg │ ├── android-favorite-outline.svg │ ├── android-favorite.svg │ ├── android-globe.svg │ ├── android-happy.svg │ ├── android-locate.svg │ ├── android-lock.svg │ ├── android-microphone.svg │ ├── android-notifications-none.svg │ ├── android-notifications.svg │ ├── android-pin.svg │ ├── android-plane.svg │ ├── android-radio-button-on.svg │ ├── android-remove-circle.svg │ ├── android-restaurant.svg │ ├── android-sad.svg │ ├── android-star.svg │ ├── android-time.svg │ ├── android-volume-up.svg │ ├── aperture.svg │ ├── arrow-expand.svg │ ├── asterisk.svg │ ├── bag.svg │ ├── battery-charging.svg │ ├── battery-half.svg │ ├── beaker.svg │ ├── bonfire.svg │ ├── bowtie.svg │ ├── bug.svg │ ├── cloud.svg │ ├── coffee.svg │ ├── contrast.svg │ ├── flag.svg │ ├── flash-off.svg │ ├── fork-repo.svg │ ├── funnel.svg │ ├── hammer.svg │ ├── happy-outline.svg │ ├── help-circled.svg │ ├── icon1.svg │ ├── icon10.svg │ ├── icon11.svg │ ├── icon12.svg │ ├── icon13.svg │ ├── icon14.svg │ ├── icon15.svg │ ├── icon16.svg │ ├── icon17.svg │ ├── icon18.svg │ ├── icon19.svg │ ├── icon2.svg │ ├── icon20.svg │ ├── icon3.svg │ ├── icon4.svg │ ├── icon5.svg │ ├── icon6.svg │ ├── icon7.svg │ ├── icon8.svg │ ├── icon9.svg │ ├── images.svg │ ├── information-circled.svg │ ├── ios-alarm-outline.svg │ ├── ios-americanfootball-outline.svg │ ├── ios-americanfootball.svg │ ├── ios-analytics-outline.svg │ ├── ios-analytics.svg │ ├── ios-body-outline.svg │ ├── ios-body.svg │ ├── ios-book-outline.svg │ ├── ios-calendar.svg │ ├── ios-clock-outline.svg │ ├── ios-cloud-download-outline.svg │ ├── ios-cloud-download.svg │ ├── ios-cog.svg │ ├── ios-color-wand-outline.svg │ ├── ios-color-wand.svg │ ├── ios-flower-outline.svg │ ├── ios-flower.svg │ ├── ios-tennisball.svg │ ├── ios-unlocked-outline.svg │ ├── ios-unlocked.svg │ ├── ios-wineglass-outline.svg │ ├── ios-wineglass.svg │ ├── ios-world-outline.svg │ ├── mouse.svg │ ├── music-note.svg │ ├── navicon-round.svg │ ├── navicon.svg │ ├── playstation.svg │ ├── social-googleplus-outline.svg │ ├── social-instagram.svg │ ├── social-octocat.svg │ ├── social-twitter-outline.svg │ ├── social-vimeo-outline.svg │ ├── social-windows-outline.svg │ ├── social-windows.svg │ ├── soup-can-outline.svg │ └── umbrella.svg │ ├── Sample.csproj │ ├── ViewModels │ ├── CollectionViewGroupTestViewModel.cs │ ├── CollectionViewTestViewModel.cs │ ├── DataTemplateTestViewModel.cs │ ├── DefaultValueTestViewModel.cs │ ├── DemoPageViewModel.cs │ ├── GridGroupTestIndexViewModel.cs │ ├── GridTestIndexViewModel.cs │ ├── HCollectionViewTestViewModel.cs │ ├── MainPageViewModel.cs │ ├── PhotoItem.cs │ ├── SurveyPageViewModel.cs │ ├── TestFormViewModel.cs │ └── Tests │ │ ├── AutoSpacingTest.cs │ │ ├── ColorTest.cs │ │ ├── GridGroupManipulationTest.cs │ │ ├── GridManipulationTest.cs │ │ ├── LoadMoreGroupTest.cs │ │ ├── LoadMoreTest.cs │ │ ├── PullToRefreshTest.cs │ │ ├── RowSpacingAndHeightTest.cs │ │ └── UniformGridTest.cs │ ├── Views │ ├── CollectionVIewTest.xaml │ ├── CollectionVIewTest.xaml.cs │ ├── CollectionViewGroupTest.xaml │ ├── CollectionViewGroupTest.xaml.cs │ ├── DataTemplateTest.xaml │ ├── DataTemplateTest.xaml.cs │ ├── DefaultValueTest.xaml │ ├── DefaultValueTest.xaml.cs │ ├── DemoPage.xaml │ ├── DemoPage.xaml.cs │ ├── GridGroupTestIndex.xaml │ ├── GridGroupTestIndex.xaml.cs │ ├── GridTestIndex.xaml │ ├── GridTestIndex.xaml.cs │ ├── HCollectionViewTest.xaml │ ├── HCollectionViewTest.xaml.cs │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── MyNavigationPage.cs │ ├── MyToastView.xaml │ ├── MyToastView.xaml.cs │ ├── SurveyPage.xaml │ ├── SurveyPage.xaml.cs │ ├── TestForm.xaml │ ├── TestForm.xaml.cs │ └── TestSelector.cs │ └── image.png ├── images ├── SS_android.jpg └── SS_ios.jpg └── nuget ├── AzurePipelines.nuspec ├── CollectionView_mac.nuspec ├── nuget.exe └── pack.sh /AiForms.CollectionView.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CollectionView", "CollectionView\CollectionView.csproj", "{6E8E8AAC-E482-4E9C-9759-27B03E4DC309}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CollectionView.Droid", "CollectionView.Droid\CollectionView.Droid.csproj", "{32BC5FF4-81FB-46DD-98ED-3D33C5318933}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CollectionView.iOS", "CollectionView.iOS\CollectionView.iOS.csproj", "{56F75955-E569-43D2-B6C7-5C2BB4E72FD3}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Release|Any CPU = Release|Any CPU 13 | Debug|Any CPU = Debug|Any CPU 14 | Release|iPhoneSimulator = Release|iPhoneSimulator 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {6E8E8AAC-E482-4E9C-9759-27B03E4DC309}.Release|Any CPU.ActiveCfg = Release|Any CPU 18 | {6E8E8AAC-E482-4E9C-9759-27B03E4DC309}.Release|Any CPU.Build.0 = Release|Any CPU 19 | {6E8E8AAC-E482-4E9C-9759-27B03E4DC309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {6E8E8AAC-E482-4E9C-9759-27B03E4DC309}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {32BC5FF4-81FB-46DD-98ED-3D33C5318933}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {32BC5FF4-81FB-46DD-98ED-3D33C5318933}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {32BC5FF4-81FB-46DD-98ED-3D33C5318933}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {32BC5FF4-81FB-46DD-98ED-3D33C5318933}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 30 | {56F75955-E569-43D2-B6C7-5C2BB4E72FD3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /CollectionView.Droid/Cells/ContentCellRenderer.cs: -------------------------------------------------------------------------------- 1 | using AiForms.Renderers; 2 | using AiForms.Renderers.Droid.Cells; 3 | using Android.Content; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Internals; 6 | using AView = Android.Views.View; 7 | 8 | [assembly: ExportRenderer(typeof(ContentCell), typeof(ContentCellRenderer))] 9 | namespace AiForms.Renderers.Droid.Cells 10 | { 11 | [Android.Runtime.Preserve(AllMembers = true)] 12 | public class ContentCellRenderer : IRegisterable 13 | { 14 | static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(ContentCellRenderer), typeof(ContentCell), null); 15 | 16 | public AView GetCell(ContentCell formsCell, ContentCellContainer nativeCell, Android.Views.ViewGroup parent, Context context) 17 | { 18 | Performance.Start(out string reference); 19 | 20 | if (nativeCell.ContentCell != null) 21 | { 22 | ClearPropertyChanged(nativeCell); 23 | } 24 | 25 | nativeCell.ContentCell = formsCell; 26 | 27 | SetUpPropertyChanged(nativeCell); 28 | 29 | nativeCell.UpdateNativeCell(); 30 | 31 | Performance.Stop(reference); 32 | 33 | return nativeCell; 34 | } 35 | 36 | protected virtual void SetUpPropertyChanged(ContentCellContainer nativeCell) 37 | { 38 | var formsCell = nativeCell.ContentCell as ContentCell; 39 | var parentElement = formsCell?.Parent as CollectionView; 40 | 41 | formsCell.PropertyChanged += nativeCell.CellPropertyChanged; 42 | 43 | if (parentElement != null) 44 | { 45 | parentElement.PropertyChanged += nativeCell.ParentPropertyChanged; 46 | } 47 | } 48 | 49 | protected virtual void ClearPropertyChanged(ContentCellContainer nativeCell) 50 | { 51 | var formsCell = nativeCell.ContentCell as ContentCell; 52 | var parentElement = formsCell.Parent as CollectionView; 53 | 54 | formsCell.PropertyChanged -= nativeCell.CellPropertyChanged; 55 | if (parentElement != null) 56 | { 57 | parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged; 58 | } 59 | } 60 | 61 | internal static ContentCellRenderer GetRenderer(BindableObject cell) 62 | { 63 | return (ContentCellRenderer)cell.GetValue(RendererProperty); 64 | } 65 | 66 | internal static void SetRenderer(BindableObject cell, ContentCellRenderer renderer) 67 | { 68 | cell.SetValue(RendererProperty, renderer); 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /CollectionView.Droid/CollectionViewScrollListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AiForms.Renderers; 3 | using AndroidX.RecyclerView.Widget; 4 | 5 | namespace AiForms.Renderers.Droid 6 | { 7 | public class CollectionViewScrollListener:RecyclerView.OnScrollListener 8 | { 9 | public bool IsReachedBottom { get; set; } 10 | 11 | CollectionView _collectionView; 12 | 13 | 14 | public CollectionViewScrollListener(CollectionView collectionView) 15 | { 16 | _collectionView = collectionView; 17 | } 18 | 19 | protected override void Dispose(bool disposing) 20 | { 21 | if(disposing) 22 | { 23 | _collectionView = null; 24 | } 25 | base.Dispose(disposing); 26 | } 27 | 28 | public override void OnScrolled(RecyclerView recyclerView, int dx, int dy) 29 | { 30 | base.OnScrolled(recyclerView, dx, dy); 31 | 32 | if(dx < 0 || dy < 0 || IsReachedBottom || _collectionView.LoadMoreCommand == null) 33 | { 34 | return; 35 | } 36 | 37 | var layoutManager = recyclerView.GetLayoutManager() as LinearLayoutManager; 38 | 39 | var visibleItemCount = recyclerView.ChildCount; 40 | var totalItemCount = layoutManager.ItemCount; 41 | var firstVisibleItem = layoutManager.FindFirstVisibleItemPosition(); 42 | 43 | if(totalItemCount - visibleItemCount - _collectionView.LoadMoreMargin <= firstVisibleItem) 44 | { 45 | IsReachedBottom = true; 46 | _collectionView.LoadMoreCommand?.Execute(null); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CollectionView.Droid/DrawableUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.Content.Res; 3 | using Android.Graphics.Drawables; 4 | 5 | namespace AiForms.Renderers.Droid 6 | { 7 | /// 8 | /// Drawable utility. 9 | /// 10 | [Android.Runtime.Preserve(AllMembers = true)] 11 | public static class DrawableUtility 12 | { 13 | /// 14 | /// Creates the ripple. 15 | /// 16 | /// The ripple. 17 | /// Color. 18 | /// Background. 19 | public static RippleDrawable CreateRipple(Android.Graphics.Color color, Drawable background = null) 20 | { 21 | if (background == null) { 22 | var mask = new ColorDrawable(Android.Graphics.Color.White); 23 | return new RippleDrawable(GetPressedColorSelector(color), null, mask); 24 | } 25 | 26 | return new RippleDrawable(GetPressedColorSelector(color), background, null); 27 | } 28 | 29 | /// 30 | /// Gets the pressed color selector. 31 | /// 32 | /// The pressed color selector. 33 | /// Pressed color. 34 | public static ColorStateList GetPressedColorSelector(int pressedColor) 35 | { 36 | return new ColorStateList( 37 | new int[][] 38 | { 39 | new int[]{} 40 | }, 41 | new int[] 42 | { 43 | pressedColor, 44 | }); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CollectionView.Droid/HCollectionViewAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Specialized; 2 | using Android.Content; 3 | using AndroidX.RecyclerView.Widget; 4 | 5 | namespace AiForms.Renderers.Droid 6 | { 7 | [Android.Runtime.Preserve(AllMembers = true)] 8 | public class HCollectionViewAdapter : CollectionViewAdapter 9 | { 10 | public readonly int InfiniteCount = 50000; 11 | HCollectionView _hCollectionView => _collectionView as HCollectionView; 12 | 13 | public HCollectionViewAdapter(Context context, CollectionView collectionView, RecyclerView recyclerView, ICollectionViewRenderer renderer) 14 | : base(context, collectionView, recyclerView, renderer) 15 | { 16 | } 17 | 18 | public override int ItemCount 19 | { 20 | get 21 | { 22 | if (_hCollectionView.IsInfinite) 23 | { 24 | if (_listCount == -1) 25 | { 26 | InvalidateCount(); 27 | } 28 | return InfiniteCount; 29 | } 30 | return base.ItemCount; 31 | } 32 | } 33 | 34 | protected override void OnGroupedCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 35 | { 36 | if (_hCollectionView.IsInfinite) 37 | { 38 | UpdateItems(e, 0, true); 39 | return; 40 | } 41 | base.OnGroupedCollectionChanged(sender, e); 42 | } 43 | 44 | protected override void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 45 | { 46 | if (_hCollectionView.IsInfinite) 47 | { 48 | UpdateItems(e, 0, true, true); 49 | return; 50 | } 51 | base.OnCollectionChanged(sender, e); 52 | } 53 | 54 | 55 | public override int GetRealPosition(int position) 56 | { 57 | if (_listCount == 0) 58 | { 59 | return position; 60 | } 61 | return _hCollectionView.IsInfinite ? position % _listCount : position; 62 | } 63 | 64 | public virtual int GetInitialPosition() 65 | { 66 | if (_listCount == -1) 67 | { 68 | InvalidateCount(); 69 | } 70 | return InfiniteCount / 2 / _listCount * _listCount; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /CollectionView.Droid/ICollectionViewRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AiForms.Renderers.Droid 4 | { 5 | [Android.Runtime.Preserve(AllMembers = true)] 6 | public interface ICollectionViewRenderer 7 | { 8 | int GroupHeaderHeight { get; set; } 9 | int GroupHeaderWidth { get; set; } 10 | int CellHeight { get; set; } 11 | int CellWidth { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CollectionView.Droid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("CollectionView.Droid")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.0")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /CollectionView.Droid/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /CollectionView.Droid/Resources/values/Strings.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | CollectionView.Droid 4 | 5 | -------------------------------------------------------------------------------- /CollectionView.Droid/SelectableSmoothScroller.cs: -------------------------------------------------------------------------------- 1 | using Android.Content; 2 | using AndroidX.RecyclerView.Widget; 3 | using Xamarin.Forms; 4 | 5 | namespace AiForms.Renderers.Droid 6 | { 7 | public class SelectableSmoothScroller : LinearSmoothScroller 8 | { 9 | public ScrollToPosition SnapPosition { get; set; } = ScrollToPosition.Start; 10 | 11 | public SelectableSmoothScroller(Context context) : base(context) 12 | { 13 | } 14 | 15 | protected override int VerticalSnapPreference => ToSnapPreference(); 16 | protected override int HorizontalSnapPreference => ToSnapPreference(); 17 | 18 | public override int CalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) 19 | { 20 | if (SnapPosition == ScrollToPosition.Center) 21 | { 22 | return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2); 23 | } 24 | 25 | return base.CalculateDtToFit(viewStart, viewEnd, boxStart, boxEnd, snapPreference); 26 | } 27 | 28 | int ToSnapPreference() 29 | { 30 | switch (SnapPosition) 31 | { 32 | case ScrollToPosition.Start: 33 | return SnapToStart; 34 | case ScrollToPosition.End: 35 | return SnapToEnd; 36 | default: 37 | return SnapToAny; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /CollectionView.Droid/ViewHolder.cs: -------------------------------------------------------------------------------- 1 | using AiForms.Renderers.Droid.Cells; 2 | using Android.Views; 3 | using AndroidX.RecyclerView.Widget; 4 | using AView = Android.Views.View; 5 | 6 | namespace AiForms.Renderers.Droid 7 | { 8 | [Android.Runtime.Preserve(AllMembers = true)] 9 | public class CollectionViewHolder : RecyclerView.ViewHolder 10 | { 11 | public CollectionViewHolder(AView view) : base(view) { } 12 | 13 | protected override void Dispose(bool disposing) 14 | { 15 | if (disposing) 16 | { 17 | ItemView?.Dispose(); 18 | ItemView = null; 19 | } 20 | base.Dispose(disposing); 21 | } 22 | } 23 | 24 | [Android.Runtime.Preserve(AllMembers = true)] 25 | public class ContentViewHolder : CollectionViewHolder 26 | { 27 | ICollectionViewRenderer _renderer; 28 | public bool IsHeader => ItemViewType >= CollectionViewAdapter.DefaultGroupHeaderTemplateId; 29 | public int CellHeight => IsHeader ? _renderer.GroupHeaderHeight : _renderer.CellHeight; 30 | public int CellWidth => IsHeader ? _renderer.GroupHeaderWidth : _renderer.CellWidth; 31 | 32 | public ContentViewHolder(ICollectionViewRenderer renderer, ContentCellContainer view) : base(view) 33 | { 34 | _renderer = renderer; 35 | 36 | view.LayoutParameters = new ViewGroup.LayoutParams(CellWidth, CellHeight); 37 | view.ViewHolder = this; 38 | } 39 | 40 | protected override void Dispose(bool disposing) 41 | { 42 | if (disposing) 43 | { 44 | ItemView?.SetOnClickListener(null); 45 | ItemView?.SetOnLongClickListener(null); 46 | _renderer = null; 47 | } 48 | base.Dispose(disposing); 49 | } 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /CollectionView.iOS/Cells/ContentCellRenderer.cs: -------------------------------------------------------------------------------- 1 | using AiForms.Renderers; 2 | using AiForms.Renderers.iOS.Cells; 3 | using UIKit; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Internals; 6 | 7 | [assembly: ExportRenderer(typeof(ContentCell), typeof(ContentCellRenderer))] 8 | namespace AiForms.Renderers.iOS.Cells 9 | { 10 | [Foundation.Preserve(AllMembers = true)] 11 | public class ContentCellRenderer : IRegisterable 12 | { 13 | public virtual UICollectionViewCell GetCell(ContentCell item, ContentCellContainer reusableCell, UICollectionView cv) 14 | { 15 | Performance.Start(out string reference); 16 | 17 | if (reusableCell.ContentCell != null) 18 | { 19 | ClearPropertyChanged(reusableCell); 20 | } 21 | 22 | reusableCell.ContentCell = item; 23 | 24 | SetUpPropertyChanged(reusableCell); 25 | 26 | reusableCell.UpdateNativeCell(); 27 | 28 | Performance.Stop(reference); 29 | 30 | return reusableCell; 31 | } 32 | 33 | protected virtual void SetUpPropertyChanged(ContentCellContainer nativeCell) 34 | { 35 | var formsCell = nativeCell.ContentCell as ContentCell; 36 | var parentElement = formsCell?.Parent as CollectionView; 37 | 38 | formsCell.PropertyChanged += nativeCell.CellPropertyChanged; 39 | 40 | if (parentElement != null) 41 | { 42 | parentElement.PropertyChanged += nativeCell.ParentPropertyChanged; 43 | } 44 | } 45 | 46 | protected virtual void ClearPropertyChanged(ContentCellContainer nativeCell) 47 | { 48 | var formsCell = nativeCell.ContentCell as ContentCell; 49 | var parentElement = formsCell.Parent as CollectionView; 50 | 51 | formsCell.PropertyChanged -= nativeCell.CellPropertyChanged; 52 | 53 | if (parentElement != null) 54 | { 55 | parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged; 56 | } 57 | } 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /CollectionView.iOS/CollectionViewInit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace AiForms.Renderers.iOS 3 | { 4 | [Foundation.Preserve(AllMembers = true)] 5 | public static class CollectionViewInit 6 | { 7 | public static void Init(){} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CollectionView.iOS/GridCollectionViewSource.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CoreGraphics; 3 | using Foundation; 4 | using UIKit; 5 | 6 | namespace AiForms.Renderers.iOS 7 | { 8 | [Foundation.Preserve(AllMembers = true)] 9 | public class GridCollectionViewSource:CollectionViewSource 10 | { 11 | public int SurplusPixel { get; set; } = 0; 12 | public List AdjustCellSizeList { get; set; } = new List(); 13 | GridCollectionView _gridCollectionView => CollectionView as GridCollectionView; 14 | 15 | public GridCollectionViewSource(CollectionView collectionView, UICollectionView uiCollectionView) 16 | :base(collectionView,uiCollectionView) 17 | { 18 | } 19 | 20 | public override CGSize GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath) 21 | { 22 | if(_gridCollectionView.GridType != GridType.UniformGrid){ 23 | return base.GetSizeForItem(collectionView, layout, indexPath); 24 | } 25 | 26 | var totalColumns = 0; 27 | 28 | switch (UIApplication.SharedApplication.StatusBarOrientation) 29 | { 30 | case UIInterfaceOrientation.Portrait: 31 | case UIInterfaceOrientation.PortraitUpsideDown: 32 | case UIInterfaceOrientation.Unknown: 33 | totalColumns = _gridCollectionView.PortraitColumns; 34 | 35 | break; 36 | case UIInterfaceOrientation.LandscapeLeft: 37 | case UIInterfaceOrientation.LandscapeRight: 38 | totalColumns = _gridCollectionView.LandscapeColumns; 39 | break; 40 | } 41 | 42 | var column = indexPath.Row % totalColumns; 43 | 44 | if(column >= totalColumns - SurplusPixel) { 45 | // assign 1px to the cell width in order from the last cell until the surplus is gone. 46 | // if assigning from the first cell, the layout is sometimes broken when items is a few. 47 | return new CGSize(CellSize.Width + 1, CellSize.Height); 48 | } 49 | 50 | return CellSize; 51 | } 52 | 53 | public override void Scrolled(UIScrollView scrollView) 54 | { 55 | base.Scrolled(scrollView); 56 | 57 | if (IsReachedBottom || CollectionView.LoadMoreCommand == null) 58 | { 59 | return; 60 | } 61 | 62 | if (scrollView.ContentSize.Height <= scrollView.ContentOffset.Y + scrollView.Bounds.Height + LoadMoreMargin) 63 | { 64 | RaiseReachedBottom(); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /CollectionView.iOS/GridViewLayout.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Foundation; 3 | using UIKit; 4 | using CoreGraphics; 5 | using System.Linq; 6 | namespace AiForms.Renderers.iOS 7 | { 8 | public class GridViewLayout:UICollectionViewFlowLayout 9 | { 10 | public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect) 11 | { 12 | var attributes = base.LayoutAttributesForElementsInRect(rect); 13 | attributes.Where(x => x.RepresentedElementCategory == UICollectionElementCategory.Cell); 14 | for (var i = 0; i < attributes.Length;i++) 15 | { 16 | if(attributes[i].RepresentedElementCategory == UICollectionElementCategory.Cell && attributes[i].IndexPath.Row == 0) 17 | { 18 | attributes[i] = LayoutAttributesForItem(attributes[i].IndexPath); 19 | } 20 | } 21 | 22 | return attributes; 23 | } 24 | 25 | public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath indexPath) 26 | { 27 | var curAttributes = base.LayoutAttributesForItem(indexPath); 28 | if(indexPath.Row == 0) 29 | { 30 | var rect = curAttributes.Frame; 31 | curAttributes.Frame = new CGRect(SectionInset.Left, rect.Y, rect.Width, rect.Height); 32 | return curAttributes; 33 | } 34 | 35 | return curAttributes; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CollectionView.iOS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("CollectionView.iOS")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /CollectionView/Cells/ContentCell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | namespace AiForms.Renderers 4 | { 5 | /// 6 | /// Content cell. 7 | /// 8 | public class ContentCell:ViewCell{} 9 | } 10 | -------------------------------------------------------------------------------- /CollectionView/CollectionView.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | AiForms.Renderers 6 | 7 | 8 | 9 | true 10 | pdbonly 11 | bin\Release\netstandard2.0\CollectionView.xml 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | README.md 26 | 27 | 28 | README-ja.md 29 | 30 | 31 | AzurePipelines.nuspec 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /CollectionView/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: InternalsVisibleTo("CollectionView.iOS")] 5 | [assembly: InternalsVisibleTo("CollectionView.Droid")] -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 kamu 4 | Portions Copyright (c) .NET Foundation Contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /Sample/Sample.Droid/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | using CarouselView.FormsPlugin.Android; 5 | using Prism; 6 | using Prism.Ioc; 7 | 8 | namespace Sample.Droid 9 | { 10 | [Activity(Label = "Sample.Droid", Icon = "@drawable/icon",Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 11 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 12 | { 13 | protected override void OnCreate(Bundle bundle) 14 | { 15 | TabLayoutResource = Resource.Layout.Tabbar; 16 | ToolbarResource = Resource.Layout.Toolbar; 17 | 18 | base.OnCreate(bundle); 19 | 20 | global::Xamarin.Forms.Forms.SetFlags("FastRenderers_Experimental"); 21 | global::Xamarin.Forms.Forms.Init(this, bundle); 22 | Xamarin.Forms.Svg.Droid.SvgImage.Init(this); 23 | FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true); 24 | CarouselViewRenderer.Init(); 25 | AiForms.Dialogs.Dialogs.Init(this); 26 | 27 | 28 | LoadApplication(new App(new AndroidInitializer())); 29 | } 30 | } 31 | 32 | public class AndroidInitializer : IPlatformInitializer 33 | { 34 | public void RegisterTypes(IContainerRegistry containerRegistry) 35 | { 36 | containerRegistry.RegisterInstance(AiForms.Dialogs.Toast.Instance); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using Android.App; 4 | 5 | // Information about this assembly is defined by the following attributes. 6 | // Change them to the values specific to your project. 7 | 8 | [assembly: AssemblyTitle("Sample.Droid")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("kamusoft")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 18 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 19 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 20 | 21 | [assembly: AssemblyVersion("1.0.0")] 22 | 23 | // The following attributes are used to specify the signing key for the assembly, 24 | // if desired. See the Mono documentation for more information about signing. 25 | 26 | //[assembly: AssemblyDelaySign(false)] 27 | //[assembly: AssemblyKeyFile("")] 28 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muak/AiForms.CollectionView/201a299b473a0757905a99247504187977c171c6/Sample/Sample.Droid/Resources/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muak/AiForms.CollectionView/201a299b473a0757905a99247504187977c171c6/Sample/Sample.Droid/Resources/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muak/AiForms.CollectionView/201a299b473a0757905a99247504187977c171c6/Sample/Sample.Droid/Resources/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muak/AiForms.CollectionView/201a299b473a0757905a99247504187977c171c6/Sample/Sample.Droid/Resources/drawable/icon.png -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/layout/Tabbar.axml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/layout/Toolbar.axml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 5 | 6 | 28 | 31 | 32 | 33 | 34 | 35 | 47 | 48 | -------------------------------------------------------------------------------- /Sample/Sample.Droid/monoEnv.txt: -------------------------------------------------------------------------------- 1 | MONO_LOG_LEVEL=message -------------------------------------------------------------------------------- /Sample/Sample.iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using Prism; 3 | using Prism.Ioc; 4 | using UIKit; 5 | using FFImageLoading.Forms; 6 | using FFImageLoading.Forms.Touch; 7 | using CarouselView.FormsPlugin.iOS; 8 | using AiForms.Dialogs; 9 | 10 | namespace Sample.iOS 11 | { 12 | // The UIApplicationDelegate for the application. This class is responsible for launching the 13 | // User Interface of the application, as well as listening (and optionally responding) to 14 | // application events from iOS. 15 | [Register("AppDelegate")] 16 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 17 | { 18 | // 19 | // This method is invoked when the application has loaded and is ready to run. In this 20 | // method you should instantiate the window, load the UI into it and then make the window 21 | // visible. 22 | // 23 | // You have 17 seconds to return from this method, or iOS will terminate your application. 24 | // 25 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 26 | { 27 | global::Xamarin.Forms.Forms.Init(); 28 | 29 | AiForms.Effects.iOS.Effects.Init(); 30 | AiForms.Renderers.iOS.CollectionViewInit.Init(); 31 | AiForms.Renderers.iOS.SettingsViewInit.Init(); 32 | Xamarin.Forms.Svg.iOS.SvgImage.Init(); 33 | FFImageLoading.Forms.Platform.CachedImageRenderer.Init(); 34 | CarouselViewRenderer.Init(); 35 | AiForms.Dialogs.Dialogs.Init(); 36 | 37 | LoadApplication(new App(new iOSInitializer())); 38 | 39 | return base.FinishedLaunching(app, options); 40 | } 41 | } 42 | 43 | public class iOSInitializer : IPlatformInitializer 44 | { 45 | public void RegisterTypes(IContainerRegistry containerRegistry) 46 | { 47 | containerRegistry.RegisterInstance(Toast.Instance); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sample/Sample.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sample/Sample.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | CollectionView 7 | CFBundleIdentifier 8 | jp.kamusoft.collectionview 9 | CFBundleShortVersionString 10 | 1.0 11 | CFBundleVersion 12 | 1.0 13 | LSRequiresIPhoneOS 14 | 15 | MinimumOSVersion 16 | 11.0 17 | UIDeviceFamily 18 | 19 | 1 20 | 2 21 | 22 | UILaunchStoryboardName 23 | LaunchScreen 24 | UIRequiredDeviceCapabilities 25 | 26 | armv7 27 | 28 | UISupportedInterfaceOrientations 29 | 30 | UIInterfaceOrientationPortrait 31 | UIInterfaceOrientationLandscapeLeft 32 | UIInterfaceOrientationLandscapeRight 33 | 34 | UISupportedInterfaceOrientations~ipad 35 | 36 | UIInterfaceOrientationPortrait 37 | UIInterfaceOrientationPortraitUpsideDown 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | XSAppIconAssets 42 | Resources/Images.xcassets/AppIcons.appiconset 43 | CFBundleName 44 | collectionview 45 | CFBundleAllowMixedLocalizations 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Sample/Sample.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace Sample.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "AppDelegate"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sample/Sample.iOS/Resources/Images.xcassets/AppIcons.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "size": "29x29", 5 | "scale": "1x", 6 | "idiom": "iphone" 7 | }, 8 | { 9 | "size": "29x29", 10 | "scale": "2x", 11 | "idiom": "iphone" 12 | }, 13 | { 14 | "size": "29x29", 15 | "scale": "3x", 16 | "idiom": "iphone" 17 | }, 18 | { 19 | "size": "40x40", 20 | "scale": "2x", 21 | "idiom": "iphone" 22 | }, 23 | { 24 | "size": "40x40", 25 | "scale": "3x", 26 | "idiom": "iphone" 27 | }, 28 | { 29 | "size": "57x57", 30 | "scale": "1x", 31 | "idiom": "iphone" 32 | }, 33 | { 34 | "size": "57x57", 35 | "scale": "2x", 36 | "idiom": "iphone" 37 | }, 38 | { 39 | "size": "60x60", 40 | "scale": "2x", 41 | "idiom": "iphone" 42 | }, 43 | { 44 | "size": "60x60", 45 | "scale": "3x", 46 | "idiom": "iphone" 47 | }, 48 | { 49 | "size": "29x29", 50 | "scale": "1x", 51 | "idiom": "ipad" 52 | }, 53 | { 54 | "size": "29x29", 55 | "scale": "2x", 56 | "idiom": "ipad" 57 | }, 58 | { 59 | "size": "40x40", 60 | "scale": "1x", 61 | "idiom": "ipad" 62 | }, 63 | { 64 | "size": "40x40", 65 | "scale": "2x", 66 | "idiom": "ipad" 67 | }, 68 | { 69 | "size": "50x50", 70 | "scale": "1x", 71 | "idiom": "ipad" 72 | }, 73 | { 74 | "size": "50x50", 75 | "scale": "2x", 76 | "idiom": "ipad" 77 | }, 78 | { 79 | "size": "72x72", 80 | "scale": "1x", 81 | "idiom": "ipad" 82 | }, 83 | { 84 | "size": "72x72", 85 | "scale": "2x", 86 | "idiom": "ipad" 87 | }, 88 | { 89 | "size": "76x76", 90 | "scale": "1x", 91 | "idiom": "ipad" 92 | }, 93 | { 94 | "size": "76x76", 95 | "scale": "2x", 96 | "idiom": "ipad" 97 | }, 98 | { 99 | "size": "120x120", 100 | "scale": "1x", 101 | "idiom": "car" 102 | } 103 | ], 104 | "info": { 105 | "version": 1, 106 | "author": "xcode" 107 | } 108 | } -------------------------------------------------------------------------------- /Sample/Sample.iOS/Resources/icon4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muak/AiForms.CollectionView/201a299b473a0757905a99247504187977c171c6/Sample/Sample.iOS/Resources/icon4@3x.png -------------------------------------------------------------------------------- /Sample/Sample.iOS/Resources/icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muak/AiForms.CollectionView/201a299b473a0757905a99247504187977c171c6/Sample/Sample.iOS/Resources/icon@3x.png -------------------------------------------------------------------------------- /Sample/Sample/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sample/Sample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Reflection; 3 | using Prism; 4 | using Prism.Ioc; 5 | using Prism.Unity; 6 | using Xamarin.Forms; 7 | using Xamarin.Forms.Internals; 8 | 9 | [assembly: Xamarin.Forms.Xaml.XamlCompilation(Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)] 10 | namespace Sample 11 | { 12 | public partial class App : PrismApplication 13 | { 14 | public App(IPlatformInitializer initializer = null) : base(initializer) { } 15 | 16 | protected override void OnInitialized() 17 | { 18 | InitializeComponent(); 19 | 20 | Xamarin.Forms.Svg.SvgImageSource.RegisterAssembly(); 21 | 22 | NavigationService.NavigateAsync("MyNavigationPage/MainPage"); 23 | } 24 | 25 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 26 | { 27 | containerRegistry.RegisterForNavigation(); 28 | containerRegistry.RegisterForNavigation(); 29 | 30 | this.GetType().GetTypeInfo().Assembly 31 | .DefinedTypes 32 | .Where(t => t.Namespace?.EndsWith(".Views", System.StringComparison.Ordinal) ?? false) 33 | .ForEach(t => { 34 | containerRegistry.RegisterForNavigation(t.AsType(), t.Name); 35 | }); 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Sample/Sample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-cloud-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-color-palette.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-contact.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-favorite-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-favorite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-globe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 24 | 25 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-happy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-locate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-microphone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-notifications-none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-notifications.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-plane.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-radio-button-on.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-remove-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-restaurant.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-sad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-time.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/android-volume-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/aperture.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/arrow-expand.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/asterisk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/bag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/battery-charging.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/battery-half.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/beaker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/bonfire.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 14 | 15 | 18 | 19 | 22 | 25 | 27 | 29 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/bowtie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | 15 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/cloud.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/coffee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/contrast.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/flash-off.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/fork-repo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | 13 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/funnel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/hammer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/happy-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 11 | 15 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/help-circled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon10.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon12.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon13.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon14.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon15.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon16.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon17.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon18.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon19.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon20.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/icon9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/images.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/information-circled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-alarm-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-americanfootball-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 17 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-americanfootball.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-analytics-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 14 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-analytics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-body-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-body.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-book-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-clock-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-cloud-download-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-cloud-download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-cog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-color-wand-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-color-wand.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-tennisball.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-unlocked-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-unlocked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-wineglass-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 15 | 16 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-wineglass.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/ios-world-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 22 | 23 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/mouse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 16 | 17 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/music-note.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/navicon-round.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/navicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/playstation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | 16 | 21 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/social-googleplus-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/social-instagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/social-twitter-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 19 | 20 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/social-vimeo-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 23 | 24 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/social-windows-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/social-windows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/soup-can-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 19 | 20 | 21 | 23 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sample/Sample/Resources/umbrella.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sample/Sample/Sample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/CollectionViewGroupTestViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using Reactive.Bindings; 5 | using Prism.Services; 6 | using System.Threading.Tasks; 7 | using Xamarin.Forms; 8 | using Prism.Navigation; 9 | using System.Linq; 10 | using System.Diagnostics; 11 | 12 | namespace Sample.ViewModels 13 | { 14 | public class CollectionViewGroupTestViewModel:CollectionViewTestViewModel 15 | { 16 | 17 | public ReactiveCommand AddSecCommand { get; set; } = new ReactiveCommand(); 18 | public ReactiveCommand DelSecCommand { get; set; } = new ReactiveCommand(); 19 | 20 | IPageDialogService _pageDlg; 21 | 22 | public CollectionViewGroupTestViewModel(IPageDialogService pageDialog):base(pageDialog) 23 | { 24 | _pageDlg = pageDialog; 25 | InitializeProperties(); 26 | 27 | } 28 | 29 | void InitializeProperties() { 30 | ItemsGroupSource = new ObservableCollection(); 31 | 32 | var list1 = new List(); 33 | for (var i = 0; i < 20; i++) 34 | { 35 | list1.Add(new PhotoItem 36 | { 37 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 38 | Title = $"Title {i + 1}", 39 | Category = "AAA", 40 | }); 41 | } 42 | var list2 = new List(); 43 | for (var i = 0; i < 20; i++) 44 | { 45 | list2.Add(new PhotoItem 46 | { 47 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 48 | Title = $"Title {i + 1}", 49 | Category = "BBB", 50 | }); 51 | } 52 | var list3 = new List(); 53 | for (var i = 10; i < 20; i++) 54 | { 55 | list3.Add(new PhotoItem 56 | { 57 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 58 | Title = $"Title {i + 1}", 59 | Category = "CCC", 60 | }); 61 | } 62 | 63 | var group1 = new PhotoGroup(list1) { Head = "SectionA" }; 64 | var group2 = new PhotoGroup(list2) { Head = "SectionB" }; 65 | var group3 = new PhotoGroup(list3) { Head = "SectionC" }; 66 | 67 | ItemsGroupSource.Add(group1); 68 | ItemsGroupSource.Add(group2); 69 | ItemsGroupSource.Add(group3); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/DataTemplateTestViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | 5 | namespace Sample.ViewModels 6 | { 7 | public class DataTemplateTestViewModel 8 | { 9 | public ObservableCollection ItemsSource { get; set; } = new ObservableCollection(); 10 | 11 | public DataTemplateTestViewModel() 12 | { 13 | var list1 = new List(); 14 | for (var i = 0; i < 20; i++) 15 | { 16 | list1.Add(new PhotoItem 17 | { 18 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 19 | Title = $"Title {i + 1}", 20 | Category = "AAA", 21 | }); 22 | } 23 | var list2 = new List(); 24 | for (var i = 10; i < 15; i++) 25 | { 26 | list2.Add(new PhotoItem 27 | { 28 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 29 | Title = $"Title {i + 1}", 30 | Category = "BBB", 31 | }); 32 | } 33 | var list3 = new List(); 34 | for (var i = 5; i < 20; i++) 35 | { 36 | list3.Add(new PhotoItem 37 | { 38 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 39 | Title = $"Title {i + 1}", 40 | Category = "CCC", 41 | }); 42 | } 43 | 44 | var group1 = new PhotoGroup(list1) { Head = "SecA" }; 45 | var group2 = new PhotoGroup(list2) { Head = "SecB" }; 46 | var group3 = new PhotoGroup(list3) { Head = "SecC" }; 47 | ItemsSource.Add(group1); 48 | ItemsSource.Add(group2); 49 | ItemsSource.Add(group3); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/DefaultValueTestViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Prism.Mvvm; 4 | using Prism.Navigation; 5 | using Reactive.Bindings; 6 | using System.Threading.Tasks; 7 | 8 | 9 | namespace Sample.ViewModels 10 | { 11 | public class DefaultValueTestViewModel:BindableBase,INavigatedAware 12 | { 13 | public ReactiveCollection ItemsSource { get; set; } = new ReactiveCollection(); 14 | 15 | public DefaultValueTestViewModel() 16 | { 17 | } 18 | 19 | void InitializeProperties() 20 | { 21 | 22 | var list = new List(); 23 | for (var i = 0; i < 20; i++) 24 | { 25 | list.Add(new PhotoItem 26 | { 27 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 28 | Title = $"Title {i + 1}", 29 | Category = "AAA", 30 | }); 31 | } 32 | 33 | 34 | ItemsSource.AddRangeOnScheduler(list); 35 | } 36 | 37 | public void OnNavigatingTo(NavigationParameters parameters) 38 | { 39 | } 40 | 41 | public void OnNavigatedFrom(NavigationParameters parameters) 42 | { 43 | } 44 | 45 | public async void OnNavigatedTo(NavigationParameters parameters) 46 | { 47 | await Load(); 48 | } 49 | 50 | internal async Task Load() 51 | { 52 | try 53 | { 54 | InitializeProperties(); 55 | } 56 | finally {; } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/MainPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Commands; 2 | using Prism.Mvvm; 3 | using Prism.Navigation; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using Reactive.Bindings; 8 | 9 | namespace Sample.ViewModels 10 | { 11 | public class MainPageViewModel : BindableBase, INavigationAware 12 | { 13 | public ReactiveCommand GoToPage { get; set; } = new ReactiveCommand(); 14 | public ReactiveCommand GoToTest { get; set; } = new ReactiveCommand(); 15 | 16 | public MainPageViewModel(INavigationService navigationService) 17 | { 18 | GoToPage.Subscribe(async p=>{ 19 | await navigationService.NavigateAsync(p + "Page"); 20 | }); 21 | GoToTest.Subscribe(async p=>{ 22 | await navigationService.NavigateAsync(p); 23 | }); 24 | 25 | } 26 | 27 | public void OnNavigatedFrom(NavigationParameters parameters) 28 | { 29 | 30 | } 31 | 32 | public void OnNavigatedTo(NavigationParameters parameters) 33 | { 34 | 35 | } 36 | 37 | public void OnNavigatingTo(NavigationParameters parameters) 38 | { 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/PhotoItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | 5 | namespace Sample.ViewModels 6 | { 7 | public class PhotoGroup : ObservableCollection 8 | { 9 | public string Head { get; set; } 10 | public PhotoGroup(IEnumerable list) : base(list) { } 11 | } 12 | 13 | public class PhotoItem 14 | { 15 | public string PhotoUrl { get; set; } 16 | public string Title { get; set; } 17 | public string Category { get; set; } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/SurveyPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | 5 | namespace Sample.ViewModels 6 | { 7 | public class SurveyPageViewModel 8 | { 9 | public ObservableCollection ItemsSource { get; } 10 | 11 | public SurveyPageViewModel() 12 | { 13 | var list1 = new List(); 14 | for (var i = 0; i < 20; i++) 15 | { 16 | list1.Add(new PhotoItem 17 | { 18 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 19 | Title = $"Title {i + 1}", 20 | Category = "AAA", 21 | }); 22 | } 23 | 24 | ItemsSource = new ObservableCollection(list1); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/Tests/ColorTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Xamarin.Forms; 4 | 5 | namespace Sample.ViewModels.Tests 6 | { 7 | public class ColorTest:TestGroup 8 | { 9 | public ColorTest():base("Color") 10 | { 11 | } 12 | 13 | public override void SetUp() 14 | { 15 | base.SetUp(); 16 | VM.Background.Value = Color.White; 17 | VM.FeedbackColor.Value = Color.Yellow; 18 | } 19 | 20 | [Test(Message = "Has Background turned from Yellow to White to Green to transparent?")] 21 | public async void BackgroundColor() 22 | { 23 | VM.Background.Value = Color.Yellow; 24 | await Task.Delay(1000); 25 | VM.Background.Value = Color.White; 26 | await Task.Delay(1000); 27 | VM.Background.Value = Color.Green; 28 | await Task.Delay(1000); 29 | VM.Background.Value = Color.Transparent; 30 | } 31 | 32 | [Test(Message = "Tap some cells. Has FeedBack color turned Red?")] 33 | public void FeedbackColor() 34 | { 35 | VM.FeedbackColor.Value = Color.Red; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/Tests/LoadMoreGroupTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using AiForms.Renderers; 5 | 6 | namespace Sample.ViewModels.Tests 7 | { 8 | public class LoadMoreGroupTest:TestGroup 9 | { 10 | IScrollController ScrollController => VM.ScrollController; 11 | IDisposable loadMoreSub; 12 | 13 | 14 | public LoadMoreGroupTest():base("LoadMore") 15 | { 16 | } 17 | 18 | public override void SetUp() 19 | { 20 | base.SetUp(); 21 | loadMoreSub?.Dispose(); 22 | } 23 | 24 | void CommandLoadMoreItems() 25 | { 26 | 27 | for (var i = 0; i < 10; i++) 28 | { 29 | VM.ItemsGroupSource[2].Add(new PhotoItem 30 | { 31 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 32 | Title = $"P1 {i + 1}", 33 | Category = "AAA", 34 | }); 35 | } 36 | } 37 | 38 | void CommandLoadMoreGroup() 39 | { 40 | var list = new List(); 41 | for (var i = 5; i < 15; i++) 42 | { 43 | list.Add(new PhotoItem 44 | { 45 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 46 | Title = $"P2 {i + 1}", 47 | Category = "DDD", 48 | }); 49 | } 50 | 51 | VM.ItemsGroupSource.Add(new PhotoGroup(list) { Head = "MoreSection" }); 52 | } 53 | 54 | [Test(Message = "LoadMore 10 Items And Complete LoadMore.")] 55 | public async void LoadMoreItems() 56 | { 57 | loadMoreSub = VM.LoadMoreCommand.Subscribe(CommandLoadMoreItems); 58 | 59 | 60 | ScrollController.ScrollToEnd(true); 61 | await Task.Delay(500); 62 | ScrollController.ScrollToEnd(true); 63 | } 64 | 65 | [Test(Message = "LoadMoreCompletion reset And LoadMore 1 Group")] 66 | public async void LoadMoreGroup() 67 | { 68 | ScrollController.ScrollToStart(true); 69 | await Task.Delay(500); 70 | 71 | VM.SetEndLoadMore(false); 72 | loadMoreSub.Dispose(); 73 | loadMoreSub = VM.LoadMoreCommand.Subscribe(CommandLoadMoreGroup); 74 | 75 | ScrollController.ScrollToEnd(true); 76 | await Task.Delay(500); 77 | ScrollController.ScrollToEnd(true); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/Tests/LoadMoreTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AiForms.Renderers; 3 | using System.Threading.Tasks; 4 | 5 | namespace Sample.ViewModels.Tests 6 | { 7 | public class LoadMoreTest:TestGroup 8 | { 9 | IScrollController ScrollController => VM.ScrollController; 10 | int _pageCount = 1; 11 | public LoadMoreTest():base("LoadMore"){} 12 | 13 | public override void SetUp() 14 | { 15 | base.SetUp(); 16 | _pageCount = 1; 17 | 18 | VM.LoadMoreCommand.Subscribe(_ => 19 | { 20 | if(_pageCount == 3) 21 | { 22 | VM.SetEndLoadMore(true); 23 | return; 24 | } 25 | 26 | for (var i = 0; i < 10; i++) 27 | { 28 | VM.ItemsSource.Add(new PhotoItem 29 | { 30 | PhotoUrl = $"https://kamusoft.jp/openimage/nativecell/{i + 1}.jpg", 31 | Title = $"P{_pageCount} {i + 1}", 32 | Category = "AAA", 33 | }); 34 | } 35 | VM.SetEndLoadMore(false); 36 | _pageCount++; 37 | }); 38 | } 39 | 40 | [Test(Message = "LoadMore 20 Items And LoadMore Complete")] 41 | public async void LoadMore() 42 | { 43 | 44 | ScrollController.ScrollToEnd(true); 45 | await Task.Delay(500); 46 | ScrollController.ScrollToEnd(true); 47 | await Task.Delay(500); 48 | ScrollController.ScrollToEnd(true); 49 | } 50 | 51 | [Test(Message = "LoadMoreCompletion reset And LoadMore 20 Items Again.")] 52 | public async void LoadMoreAgain() 53 | { 54 | ScrollController.ScrollToStart(true); 55 | await Task.Delay(500); 56 | _pageCount = 1; 57 | VM.SetEndLoadMore(false); 58 | ScrollController.ScrollToEnd(true); 59 | await Task.Delay(500); 60 | ScrollController.ScrollToEnd(true); 61 | await Task.Delay(500); 62 | ScrollController.ScrollToEnd(true); 63 | } 64 | 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/Tests/PullToRefreshTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Xamarin.Forms; 4 | 5 | namespace Sample.ViewModels.Tests 6 | { 7 | public class PullToRefreshTest:TestGroup 8 | { 9 | public PullToRefreshTest():base("PullToRefresh"){} 10 | 11 | public override void SetUp() 12 | { 13 | base.SetUp(); 14 | VM.EnabledPullToRefresh.Value = true; 15 | VM.RefreshIconColor.Value = Color.DimGray; 16 | } 17 | 18 | [Test(Message = "PullToRefresh can't be work.")] 19 | public void Disabled() 20 | { 21 | VM.EnabledPullToRefresh.Value = false; 22 | } 23 | 24 | [Test(Message = "Can PullToRefresh be work?")] 25 | public void Enabled() 26 | { 27 | VM.EnabledPullToRefresh.Value = true; 28 | } 29 | 30 | [Test(Message = "Has Refresh icon turned red?")] 31 | public void TurnIconColor() 32 | { 33 | VM.RefreshIconColor.Value = Color.Red; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sample/Sample/ViewModels/Tests/RowSpacingAndHeightTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Sample.ViewModels.Tests 3 | { 4 | public class RowSpacingAndHeightTest:TestGroup 5 | { 6 | public RowSpacingAndHeightTest():base("RowSpacingAndHeight") 7 | { 8 | } 9 | 10 | public override void SetUp() 11 | { 12 | base.SetUp(); 13 | VM.RowSpacing.Value = 4.0; 14 | VM.GroupFirstSpacing.Value = 0; 15 | VM.GroupLastSpacing.Value = 0; 16 | VM.ColumnHeight.Value = 1.0; 17 | VM.IsGroupHeaderSticky.Value = true; 18 | VM.AdditionalHeight.Value = 0; 19 | VM.HeaderHeight.Value = 36; 20 | } 21 | 22 | [Test(Message = "Has RowSpacing become much larger?")] 23 | public void RowSpacing() 24 | { 25 | VM.RowSpacing.Value = 25; 26 | } 27 | 28 | [Test(Message = "Has Group First Spacing been 30px in Grouped?")] 29 | public void FirstSpacing() 30 | { 31 | VM.GroupFirstSpacing.Value = 30; 32 | } 33 | 34 | [Test(Message = "Has Group Last Spacing been 30px in Grouped?")] 35 | public void LastSpacing() 36 | { 37 | VM.GroupLastSpacing.Value = 30; 38 | } 39 | 40 | [Test(Message = "Has ColumnHeight been changed to absolute value(250px)?")] 41 | public void ColumnHeightAbsolute() 42 | { 43 | VM.ColumnHeight.Value = 250; 44 | } 45 | 46 | [Test(Message = "Has ColumnHeight been changed to relative value(0.5)?")] 47 | public void ColumnHeightProportional() 48 | { 49 | VM.ColumnHeight.Value = 0.5; 50 | } 51 | 52 | [Test(Message = "Has ColumnHeight been changed to 1.0 + 50px by AdditionalHeight?")] 53 | public void AdditionalHeight() 54 | { 55 | VM.AdditionalHeight.Value = 50; 56 | } 57 | 58 | [Test(Message = "Has GroupHeaderHeight been twice as large as the privious?")] 59 | public void GroupHeaderHeight() 60 | { 61 | VM.HeaderHeight.Value *= 2; 62 | } 63 | 64 | //[Test(Message = "Has HeaderCell position been released from sticky? (iOS)")] 65 | //public void Sticky() 66 | //{ 67 | // VM.IsGroupHeaderSticky.Value = false; 68 | //} 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Sample/Sample/Views/CollectionVIewTest.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sample.ViewModels; 4 | using Xamarin.Forms; 5 | using System.Linq; 6 | 7 | namespace Sample.Views 8 | { 9 | public partial class CollectionViewTest : ContentPage 10 | { 11 | public CollectionViewTest() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e) 17 | { 18 | var photo = e.Item as PhotoItem; 19 | DisplayAlert("", $"ItemTapped {photo.Category} {photo.Title}", "OK"); 20 | } 21 | 22 | ScrollToPosition pos = ScrollToPosition.Start; 23 | void Handle_Clicked(object sender, System.EventArgs e) 24 | { 25 | var vm = BindingContext as CollectionViewTestViewModel; 26 | 27 | collectionView.ScrollTo(vm.ItemsSource[9], pos, false); 28 | 29 | if(pos == ScrollToPosition.End) { 30 | pos = ScrollToPosition.Start; 31 | } 32 | else{ 33 | pos++; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sample/Sample/Views/CollectionViewGroupTest.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | using Sample.ViewModels; 6 | 7 | namespace Sample.Views 8 | { 9 | public partial class CollectionViewGroupTest : ContentPage 10 | { 11 | public CollectionViewGroupTest() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e) 17 | { 18 | var photo = e.Item as PhotoItem; 19 | DisplayAlert("", $"ItemTapped {photo.Category} {photo.Title}", "OK"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sample/Sample/Views/DataTemplateTest.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | 6 | namespace Sample.Views 7 | { 8 | public partial class DataTemplateTest : ContentPage 9 | { 10 | public DataTemplateTest() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sample/Sample/Views/DefaultValueTest.xaml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Sample/Sample/Views/DefaultValueTest.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | using AiForms.Renderers; 6 | 7 | namespace Sample.Views 8 | { 9 | public partial class DefaultValueTest : ContentPage 10 | { 11 | public DefaultValueTest() 12 | { 13 | InitializeComponent(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Sample/Sample/Views/DemoPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | 6 | namespace Sample.Views 7 | { 8 | public partial class DemoPage : ContentPage 9 | { 10 | public DemoPage() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sample/Sample/Views/GridGroupTestIndex.xaml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Sample/Sample/Views/GridGroupTestIndex.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | 6 | namespace Sample.Views 7 | { 8 | public partial class GridGroupTestIndex : ContentPage 9 | { 10 | public GridGroupTestIndex() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sample/Sample/Views/GridTestIndex.xaml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Sample/Sample/Views/GridTestIndex.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | 6 | namespace Sample.Views 7 | { 8 | public partial class GridTestIndex : ContentPage 9 | { 10 | public GridTestIndex() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sample/Sample/Views/HCollectionViewTest.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Xamarin.Forms; 5 | using Sample.ViewModels; 6 | 7 | namespace Sample.Views 8 | { 9 | public partial class HCollectionViewTest : ContentPage 10 | { 11 | public HCollectionViewTest() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | ScrollToPosition pos = ScrollToPosition.Start; 17 | void Handle_Clicked(object sender, System.EventArgs e) 18 | { 19 | var vm = BindingContext as HCollectionViewTestViewModel; 20 | 21 | collectionView.ScrollTo(vm.ItemsSource[1][0],vm.ItemsSource[1], pos, false); 22 | collectionView2.ScrollTo(vm.ItemsSource2[4], pos, false); 23 | 24 | if (pos == ScrollToPosition.End) 25 | { 26 | pos = ScrollToPosition.Start; 27 | } 28 | else 29 | { 30 | pos++; 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sample/Sample/Views/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 |