Created
March 29, 2017 05:56
-
-
Save rc1021/e3b8fa6641d2e5d358a9963a8f201df4 to your computer and use it in GitHub Desktop.
Custom layouts with Xamarin.Forms: auto arrangement cells (not finish)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | |
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |
xmlns:local="clr-namespace:App1" | |
x:Class="App1.AutoArrangement" | |
Title="Auto-Arrangement"> | |
<ContentPage.Content> | |
<local:GridListView | |
ItemHeight="100" | |
RowSpacing="10" | |
ColumnSpacing="5" | |
MaxItemsPerRow="3" | |
ItemsSource="{Binding Source}"> | |
<local:GridListView.ItemTemplate> | |
<DataTemplate> | |
<TextCell Text="{Binding .}" /> | |
</DataTemplate> | |
</local:GridListView.ItemTemplate> | |
</local:GridListView> | |
</ContentPage.Content> | |
</ContentPage> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Threading.Tasks; | |
using System.Collections.ObjectModel; | |
using Xamarin.Forms; | |
using CarouselView.FormsPlugin.Abstractions; | |
using Cowell.App.WebService.Near; | |
namespace App1.Pages | |
{ | |
using Cowell.App.Extensions; | |
public partial class AutoArrangement : ContentPage | |
{ | |
public ObservableCollection<string> Sources { set; get; } | |
public NearInfoPage() | |
{ | |
Source = new ObservableCollection<string> | |
{ | |
"Row 1.", | |
"Row 2.", | |
"Row 3.", | |
"Row 4.", | |
"Row 5.", | |
}; | |
InitializeComponent(); | |
BindingContext = this; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Refference: http://xfcomplete.net/xamarin.forms/2016/01/13/creating-custom-layouts-with-xamarinforms/ | |
*/ | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Xamarin.Forms; | |
namespace App1 | |
{ | |
public class GridListView : Layout<View> | |
{ | |
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create<GridListView, IEnumerable>(o => o.ItemsSource, default(IEnumerable), propertyChanged: OnItemsSourceChanged); | |
public IEnumerable ItemsSource | |
{ | |
get { return (IEnumerable)GetValue(ItemsSourceProperty); } | |
set { SetValue(ItemsSourceProperty, value); } | |
} | |
private static void OnItemsSourceChanged(BindableObject bindable, IEnumerable oldvalue, IEnumerable newvalue) | |
{ | |
var view = (GridListView)bindable; | |
view.ReCreateChildrens(); | |
} | |
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create<GridListView, DataTemplate>(o => o.ItemTemplate, default(DataTemplate), propertyChanged: OnItemsTemplateChanged); | |
public DataTemplate ItemTemplate | |
{ | |
get { return (DataTemplate)GetValue(ItemTemplateProperty); } | |
set { SetValue(ItemTemplateProperty, value); } | |
} | |
private static void OnItemsTemplateChanged(BindableObject bindable, DataTemplate oldvalue, DataTemplate newvalue) | |
{ | |
var view = (GridListView)bindable; | |
view.ReCreateChildrens(); | |
} | |
public int MaxItemsPerRow { get; set; } | |
public int ItemHeight { get; set; } | |
public double RowSpacing { get; set; } | |
public double ColumnSpacing { get; set; } | |
public GridListView() | |
{ | |
} | |
private void ReCreateChildrens() | |
{ | |
if (ItemsSource == null || ItemTemplate == null) | |
return; | |
foreach (var item in ItemsSource) | |
{ | |
var view = ItemTemplate.CreateContent() as View; | |
view.BindingContext = item; | |
Children.Add(view); | |
} | |
} | |
protected override void LayoutChildren(double x, double y, double width, double height) | |
{ | |
var colWidth = width / MaxItemsPerRow; | |
for (int i = 0; i < Children.Count; i++) | |
{ | |
var child = Children[i]; | |
if (!child.IsVisible) | |
continue; | |
var virtualColumn = i % MaxItemsPerRow; | |
var virtualRow = i / MaxItemsPerRow; | |
var rowSpacing = (virtualRow != 0) ? RowSpacing : 0; | |
var colSpacing = (virtualColumn != 0) ? ColumnSpacing : 0; | |
var childX = x + (colWidth + colSpacing) * virtualColumn; | |
var childY = y + (ItemHeight + rowSpacing) * virtualRow; | |
LayoutChildIntoBoundingRegion(child, new Rectangle(childX, childY, colWidth, ItemHeight)); | |
} | |
} | |
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint) | |
{ | |
// Check our cache for existing results | |
SizeRequest cachedResult; | |
var constraintSize = new Size(widthConstraint, heightConstraint); | |
if (_measureCache.TryGetValue(constraintSize, out cachedResult)) | |
{ | |
return cachedResult; | |
} | |
var height = 0.0; | |
var minHeight = 0.0; | |
var width = 0.0; | |
var minWidth = 0.0; | |
var visibleChildrensCount = (double)Children.Count(c => c.IsVisible); | |
var rowsCount = Math.Ceiling(visibleChildrensCount / MaxItemsPerRow); | |
height = minHeight = (ItemHeight + RowSpacing) * rowsCount - RowSpacing; | |
width = minWidth = widthConstraint; | |
// store our result in the cache for next time | |
var result = new SizeRequest(new Size(width, height), new Size(minWidth, minHeight)); | |
_measureCache[constraintSize] = result; | |
return result; | |
} | |
protected override void InvalidateMeasure() | |
{ | |
_measureCache.Clear(); | |
base.InvalidateMeasure(); | |
} | |
readonly Dictionary<Size, SizeRequest> _measureCache = new Dictionary<Size, SizeRequest>(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment