Remove extra properties from CarouselView API (#7456)
* Remove Header/Footer properties from CarouselView * Limit CarouselView to LinearItemsLayout * Rework inheritance for UWP * Split files by class * Fix up Tizen renderer
This commit is contained in:
Родитель
24fec62cdd
Коммит
a68dd21dc0
|
@ -53,7 +53,7 @@ namespace Xamarin.Forms.Controls.Issues
|
|||
};
|
||||
|
||||
CV.BindingContext = this;
|
||||
CV.ItemsLayout = new ListItemsLayout(ItemsLayoutOrientation.Vertical); // Vertical is default
|
||||
CV.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical); // Vertical is default
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -62,9 +62,9 @@ namespace Xamarin.Forms.Controls
|
|||
return items;
|
||||
}
|
||||
|
||||
internal ListItemsLayout GetCarouselLayout(ItemsLayoutOrientation orientation)
|
||||
internal LinearItemsLayout GetCarouselLayout(ItemsLayoutOrientation orientation)
|
||||
{
|
||||
return new ListItemsLayout(orientation)
|
||||
return new LinearItemsLayout(orientation)
|
||||
{
|
||||
SnapPointsType = SnapPointsType.MandatorySingle,
|
||||
SnapPointsAlignment = SnapPointsAlignment.Center
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Xamarin.Forms.Controls
|
|||
|
||||
element.HeightRequest = 250;
|
||||
|
||||
element.ItemsLayout = ListItemsLayout.Vertical;
|
||||
element.ItemsLayout = LinearItemsLayout.Vertical;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.CarouselVi
|
|||
}
|
||||
};
|
||||
var itemsLayout =
|
||||
new ListItemsLayout(orientation)
|
||||
new LinearItemsLayout(orientation)
|
||||
{
|
||||
SnapPointsType = SnapPointsType.MandatorySingle,
|
||||
SnapPointsAlignment = SnapPointsAlignment.Center
|
||||
|
@ -71,7 +71,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.CarouselVi
|
|||
var positionControl = new PositionControl(carouselView, nItems);
|
||||
layout.Children.Add(positionControl);
|
||||
|
||||
var spacingModifier = new SpacingModifier(carouselView, "Update Spacing");
|
||||
var spacingModifier = new SpacingModifier(carouselView.ItemsLayout, "Update Spacing");
|
||||
|
||||
layout.Children.Add(spacingModifier);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.CarouselVi
|
|||
};
|
||||
|
||||
var itemsLayout =
|
||||
new ListItemsLayout(ItemsLayoutOrientation.Horizontal)
|
||||
new LinearItemsLayout(ItemsLayoutOrientation.Horizontal)
|
||||
{
|
||||
SnapPointsType = SnapPointsType.MandatorySingle,
|
||||
SnapPointsAlignment = SnapPointsAlignment.Center
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
{
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("Vertical List (Code)", () =>
|
||||
new TemplateCodeCollectionViewGallery(ListItemsLayout.Vertical), Navigation),
|
||||
new TemplateCodeCollectionViewGallery(LinearItemsLayout.Vertical), Navigation),
|
||||
GalleryBuilder.NavButton("Horizontal List (Code)", () =>
|
||||
new TemplateCodeCollectionViewGallery(ListItemsLayout.Horizontal), Navigation),
|
||||
new TemplateCodeCollectionViewGallery(LinearItemsLayout.Horizontal), Navigation),
|
||||
GalleryBuilder.NavButton("Vertical Grid (Code)", () =>
|
||||
new TemplateCodeCollectionViewGridGallery (), Navigation),
|
||||
GalleryBuilder.NavButton("Horizontal Grid (Code)", () =>
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
// so we can demonstrate switching between them
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("Vertical List (Code)", () =>
|
||||
new TextCodeCollectionViewGallery(ListItemsLayout.Vertical), Navigation),
|
||||
new TextCodeCollectionViewGallery(LinearItemsLayout.Vertical), Navigation),
|
||||
GalleryBuilder.NavButton("Horizontal List (Code)", () =>
|
||||
new TextCodeCollectionViewGallery(ListItemsLayout.Horizontal), Navigation),
|
||||
new TextCodeCollectionViewGallery(LinearItemsLayout.Horizontal), Navigation),
|
||||
GalleryBuilder.NavButton("Vertical Grid (Code)", () =>
|
||||
new TextCodeCollectionViewGridGallery(), Navigation),
|
||||
GalleryBuilder.NavButton("Horizontal Grid (Code)", () =>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
{
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("Expanding Text (Vertical List)", () =>
|
||||
new DynamicItemSizeGallery(ListItemsLayout.Vertical), Navigation),
|
||||
new DynamicItemSizeGallery(LinearItemsLayout.Vertical), Navigation),
|
||||
GalleryBuilder.NavButton("Expanding Text (Horizontal List)", () =>
|
||||
new DynamicItemSizeGallery(ListItemsLayout.Horizontal), Navigation),
|
||||
new DynamicItemSizeGallery(LinearItemsLayout.Horizontal), Navigation),
|
||||
GalleryBuilder.NavButton("ItemSizing Strategy", () =>
|
||||
new VariableSizeTemplateGridGallery (ItemsLayoutOrientation.Horizontal), Navigation)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
IItemsLayout itemsLayout = grid
|
||||
? new GridItemsLayout(3, orientation)
|
||||
: new ListItemsLayout(orientation) as IItemsLayout;
|
||||
: new LinearItemsLayout(orientation) as IItemsLayout;
|
||||
|
||||
var itemTemplate = ExampleTemplates.PhotoTemplate();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
var itemsLayout = grid
|
||||
? new GridItemsLayout(3, orientation)
|
||||
: new ListItemsLayout(orientation) as IItemsLayout;
|
||||
: new LinearItemsLayout(orientation) as IItemsLayout;
|
||||
|
||||
var itemTemplate = ExampleTemplates.PhotoTemplate();
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
{
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("Propagate FlowDirection", () =>
|
||||
new PropagateCodeGallery(ListItemsLayout.Vertical), Navigation),
|
||||
new PropagateCodeGallery(LinearItemsLayout.Vertical), Navigation),
|
||||
|
||||
GalleryBuilder.NavButton("Propagate FlowDirection in EmptyView", () =>
|
||||
new PropagateCodeGallery(ListItemsLayout.Vertical, 0), Navigation),
|
||||
new PropagateCodeGallery(LinearItemsLayout.Vertical, 0), Navigation),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.ScrollMode
|
|||
InitializeComponent();
|
||||
|
||||
_collectionView = createCollectionView == null ? new CollectionView() : createCollectionView();
|
||||
_collectionView.ItemsLayout = itemsLayout ?? ListItemsLayout.Vertical;
|
||||
_collectionView.ItemsLayout = itemsLayout ?? LinearItemsLayout.Vertical;
|
||||
|
||||
var scrollModeSelector = new EnumSelector<ItemsUpdatingScrollMode>(() => _collectionView.ItemsUpdatingScrollMode,
|
||||
mode => _collectionView.ItemsUpdatingScrollMode = mode, "SelectScrollMode");
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries
|
|||
{
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("ScrollTo Index (Code, Horizontal List)", () =>
|
||||
new ScrollToCodeGallery(ListItemsLayout.Horizontal), Navigation),
|
||||
new ScrollToCodeGallery(LinearItemsLayout.Horizontal), Navigation),
|
||||
GalleryBuilder.NavButton("ScrollTo Index (Code, Vertical List)", () =>
|
||||
new ScrollToCodeGallery(ListItemsLayout.Vertical), Navigation),
|
||||
new ScrollToCodeGallery(LinearItemsLayout.Vertical), Navigation),
|
||||
GalleryBuilder.NavButton("ScrollTo Index (Code, Horizontal Grid)", () =>
|
||||
new ScrollToCodeGallery(new GridItemsLayout(3, ItemsLayoutOrientation.Horizontal)),
|
||||
Navigation),
|
||||
|
@ -30,10 +30,10 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries
|
|||
Navigation),
|
||||
|
||||
GalleryBuilder.NavButton("ScrollTo Item (Code, Horizontal List)", () =>
|
||||
new ScrollToCodeGallery(ListItemsLayout.Horizontal, ScrollToMode.Element,
|
||||
new ScrollToCodeGallery(LinearItemsLayout.Horizontal, ScrollToMode.Element,
|
||||
ExampleTemplates.ScrollToItemTemplate), Navigation),
|
||||
GalleryBuilder.NavButton("ScrollTo Item (Code, Vertical List)", () =>
|
||||
new ScrollToCodeGallery(ListItemsLayout.Vertical, ScrollToMode.Element,
|
||||
new ScrollToCodeGallery(LinearItemsLayout.Vertical, ScrollToMode.Element,
|
||||
ExampleTemplates.ScrollToItemTemplate), Navigation),
|
||||
GalleryBuilder.NavButton("ScrollTo Item (Code, Horizontal Grid)", () =>
|
||||
new ScrollToCodeGallery(new GridItemsLayout(3, ItemsLayoutOrientation.Horizontal),
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries
|
|||
{
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("Snap Points (Code, Horizontal List)", () =>
|
||||
new SnapPointsCodeGallery(ListItemsLayout.Horizontal as ItemsLayout), Navigation),
|
||||
new SnapPointsCodeGallery(LinearItemsLayout.Horizontal as ItemsLayout), Navigation),
|
||||
GalleryBuilder.NavButton("Snap Points (Code, Vertical List)", () =>
|
||||
new SnapPointsCodeGallery(ListItemsLayout.Vertical as ItemsLayout), Navigation),
|
||||
new SnapPointsCodeGallery(LinearItemsLayout.Vertical as ItemsLayout), Navigation),
|
||||
GalleryBuilder.NavButton("Snap Points (Code, Horizontal Grid)", () =>
|
||||
new SnapPointsCodeGallery(new GridItemsLayout(2, ItemsLayoutOrientation.Horizontal)), Navigation),
|
||||
GalleryBuilder.NavButton("Snap Points (Code, Vertical Grid)", () =>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
{
|
||||
descriptionLabel,
|
||||
GalleryBuilder.NavButton("Vertical List Spacing", () =>
|
||||
new SpacingGallery (ListItemsLayout.Vertical), Navigation),
|
||||
new SpacingGallery (LinearItemsLayout.Vertical), Navigation),
|
||||
GalleryBuilder.NavButton("Horizontal List Spacing", () =>
|
||||
new SpacingGallery (ListItemsLayout.Horizontal), Navigation),
|
||||
new SpacingGallery (LinearItemsLayout.Horizontal), Navigation),
|
||||
GalleryBuilder.NavButton("Vertical Grid Spacing", () =>
|
||||
new SpacingGallery (new GridItemsLayout(3, ItemsLayoutOrientation.Vertical)), Navigation),
|
||||
GalleryBuilder.NavButton("Horizontal Grid Spacing", () =>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
};
|
||||
|
||||
var generator = new ItemsSourceGenerator(collectionView, initialItems: 20);
|
||||
var spacingModifier = new SpacingModifier(collectionView, "Update Spacing");
|
||||
var spacingModifier = new SpacingModifier(collectionView.ItemsLayout, "Update Spacing");
|
||||
|
||||
layout.Children.Add(generator);
|
||||
layout.Children.Add(instructions);
|
||||
|
|
|
@ -4,12 +4,12 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.SpacingGal
|
|||
{
|
||||
internal class SpacingModifier : ContentView
|
||||
{
|
||||
protected readonly ItemsView _cv;
|
||||
protected readonly Entry Entry;
|
||||
protected readonly IItemsLayout ItemsLayout;
|
||||
|
||||
public SpacingModifier(ItemsView cv, string buttonText)
|
||||
public SpacingModifier(IItemsLayout itemsLayout, string buttonText)
|
||||
{
|
||||
_cv = cv;
|
||||
ItemsLayout = itemsLayout;
|
||||
|
||||
var layout = new StackLayout
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.SpacingGal
|
|||
|
||||
protected virtual string LabelText => "Spacing:";
|
||||
|
||||
protected virtual string InitialEntryText => _cv.ItemsLayout is GridItemsLayout ? "0, 0" : "0";
|
||||
protected virtual string InitialEntryText => ItemsLayout is GridItemsLayout ? "0, 0" : "0";
|
||||
|
||||
protected virtual void OnButtonClicked()
|
||||
{
|
||||
|
@ -47,11 +47,11 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.SpacingGal
|
|||
return;
|
||||
}
|
||||
|
||||
if (_cv.ItemsLayout is ListItemsLayout listItemsLayout)
|
||||
if (ItemsLayout is LinearItemsLayout listItemsLayout)
|
||||
{
|
||||
listItemsLayout.ItemSpacing = indexes[0];
|
||||
}
|
||||
else if (_cv.ItemsLayout is GridItemsLayout gridItemsLayout)
|
||||
else if (ItemsLayout is GridItemsLayout gridItemsLayout)
|
||||
{
|
||||
gridItemsLayout.VerticalItemSpacing = indexes[0];
|
||||
gridItemsLayout.HorizontalItemSpacing = indexes[1];
|
||||
|
@ -60,7 +60,7 @@ namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.SpacingGal
|
|||
|
||||
protected virtual bool ParseIndexes(out int[] indexes)
|
||||
{
|
||||
if (_cv.ItemsLayout is ListItemsLayout listItemsLayout)
|
||||
if (ItemsLayout is LinearItemsLayout listItemsLayout)
|
||||
{
|
||||
return IndexParser.ParseIndexes(Entry.Text, 1, out indexes);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
[Test]
|
||||
public void VerticalListMeasurement()
|
||||
{
|
||||
var itemsView = new ItemsView();
|
||||
var itemsView = new StructuredItemsView();
|
||||
|
||||
var sizeRequest = itemsView.Measure(double.PositiveInfinity, double.PositiveInfinity);
|
||||
|
||||
|
@ -37,9 +37,9 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
[Test]
|
||||
public void HorizontalListMeasurement()
|
||||
{
|
||||
var itemsView = new ItemsView();
|
||||
var itemsView = new StructuredItemsView();
|
||||
|
||||
itemsView.ItemsLayout = new ListItemsLayout(ItemsLayoutOrientation.Horizontal);
|
||||
itemsView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);
|
||||
|
||||
var sizeRequest = itemsView.Measure(double.PositiveInfinity, double.PositiveInfinity);
|
||||
|
||||
|
|
|
@ -154,13 +154,23 @@ namespace Xamarin.Forms
|
|||
set => SetValue(PositionChangedCommandParameterProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ItemsLayoutProperty =
|
||||
BindableProperty.Create(nameof(ItemsLayout), typeof(LinearItemsLayout), typeof(ItemsView),
|
||||
LinearItemsLayout.Horizontal);
|
||||
|
||||
public LinearItemsLayout ItemsLayout
|
||||
{
|
||||
get => (LinearItemsLayout)InternalItemsLayout;
|
||||
set => InternalItemsLayout = value;
|
||||
}
|
||||
|
||||
public event EventHandler<CurrentItemChangedEventArgs> CurrentItemChanged;
|
||||
public event EventHandler<PositionChangedEventArgs> PositionChanged;
|
||||
|
||||
public CarouselView()
|
||||
{
|
||||
CollectionView.VerifyCollectionViewFlagEnabled(constructorHint: nameof(CarouselView));
|
||||
ItemsLayout = new ListItemsLayout(ItemsLayoutOrientation.Horizontal)
|
||||
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal)
|
||||
{
|
||||
SnapPointsType = SnapPointsType.MandatorySingle,
|
||||
SnapPointsAlignment = SnapPointsAlignment.Center
|
||||
|
|
|
@ -9,12 +9,12 @@ namespace Xamarin.Forms
|
|||
{
|
||||
if (value == "HorizontalList")
|
||||
{
|
||||
return ListItemsLayout.Horizontal;
|
||||
return LinearItemsLayout.Horizontal;
|
||||
}
|
||||
|
||||
if (value == "VerticalList")
|
||||
{
|
||||
return ListItemsLayout.Vertical;
|
||||
return LinearItemsLayout.Vertical;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(IItemsLayout)}");
|
||||
|
|
|
@ -7,7 +7,7 @@ using Xamarin.Forms.Internals;
|
|||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
public class ItemsView : View
|
||||
public abstract class ItemsView : View
|
||||
{
|
||||
List<Element> _logicalChildren = new List<Element>();
|
||||
|
||||
|
@ -37,13 +37,13 @@ namespace Xamarin.Forms
|
|||
public static readonly BindableProperty ItemsSourceProperty =
|
||||
BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(ItemsView), null);
|
||||
|
||||
public IEnumerable ItemsSource
|
||||
public IEnumerable ItemsSource
|
||||
{
|
||||
get => (IEnumerable)GetValue(ItemsSourceProperty);
|
||||
set => SetValue(ItemsSourceProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty RemainingItemsThresholdReachedCommandProperty =
|
||||
public static readonly BindableProperty RemainingItemsThresholdReachedCommandProperty =
|
||||
BindableProperty.Create(nameof(RemainingItemsThresholdReachedCommand), typeof(ICommand), typeof(ItemsView), null);
|
||||
|
||||
public ICommand RemainingItemsThresholdReachedCommand
|
||||
|
@ -93,47 +93,11 @@ namespace Xamarin.Forms
|
|||
set => SetValue(RemainingItemsThresholdProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty HeaderProperty =
|
||||
BindableProperty.Create(nameof(Header), typeof(object), typeof(ItemsView), null);
|
||||
|
||||
public object Header
|
||||
{
|
||||
get => GetValue(HeaderProperty);
|
||||
set => SetValue(HeaderProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty HeaderTemplateProperty =
|
||||
BindableProperty.Create(nameof(HeaderTemplate), typeof(DataTemplate), typeof(ItemsView), null);
|
||||
|
||||
public DataTemplate HeaderTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(HeaderTemplateProperty);
|
||||
set => SetValue(HeaderTemplateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty FooterProperty =
|
||||
BindableProperty.Create(nameof(Footer), typeof(object), typeof(ItemsView), null);
|
||||
|
||||
public object Footer
|
||||
{
|
||||
get => GetValue(FooterProperty);
|
||||
set => SetValue(FooterProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty FooterTemplateProperty =
|
||||
BindableProperty.Create(nameof(FooterTemplate), typeof(DataTemplate), typeof(ItemsView), null);
|
||||
|
||||
public DataTemplate FooterTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(FooterTemplateProperty);
|
||||
set => SetValue(FooterTemplateProperty, value);
|
||||
}
|
||||
|
||||
public void AddLogicalChild(Element element)
|
||||
{
|
||||
if(element == null)
|
||||
if (element == null)
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
_logicalChildren.Add(element);
|
||||
|
@ -162,23 +126,18 @@ namespace Xamarin.Forms
|
|||
internal override ReadOnlyCollection<Element> LogicalChildrenInternal => _logicalChildren.AsReadOnly();
|
||||
#endif
|
||||
|
||||
public static readonly BindableProperty ItemsLayoutProperty =
|
||||
BindableProperty.Create(nameof(ItemsLayout), typeof(IItemsLayout), typeof(ItemsView),
|
||||
ListItemsLayout.Vertical);
|
||||
internal static readonly BindableProperty InternalItemsLayoutProperty =
|
||||
BindableProperty.Create(nameof(ItemsLayout), typeof(IItemsLayout), typeof(ItemsView),
|
||||
LinearItemsLayout.Vertical);
|
||||
|
||||
public IItemsLayout ItemsLayout
|
||||
|
||||
// public abstract IItemsLayout ItemsLayout { get; }
|
||||
|
||||
|
||||
protected IItemsLayout InternalItemsLayout
|
||||
{
|
||||
get => (IItemsLayout)GetValue(ItemsLayoutProperty);
|
||||
set => SetValue(ItemsLayoutProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ItemTemplateProperty =
|
||||
BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(ItemsView));
|
||||
|
||||
public DataTemplate ItemTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(ItemTemplateProperty);
|
||||
set => SetValue(ItemTemplateProperty, value);
|
||||
get => (IItemsLayout)GetValue(InternalItemsLayoutProperty);
|
||||
set => SetValue(InternalItemsLayoutProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ItemSizingStrategyProperty =
|
||||
|
@ -190,6 +149,16 @@ namespace Xamarin.Forms
|
|||
set => SetValue(ItemSizingStrategyProperty, value);
|
||||
}
|
||||
|
||||
|
||||
public static readonly BindableProperty ItemTemplateProperty =
|
||||
BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(ItemsView));
|
||||
|
||||
public DataTemplate ItemTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(ItemTemplateProperty);
|
||||
set => SetValue(ItemTemplateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ItemsUpdatingScrollModeProperty =
|
||||
BindableProperty.Create(nameof(ItemsUpdatingScrollMode), typeof(ItemsUpdatingScrollMode), typeof(ItemsView),
|
||||
default(ItemsUpdatingScrollMode));
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
public class ListItemsLayout : ItemsLayout
|
||||
public class LinearItemsLayout : ItemsLayout
|
||||
{
|
||||
public ListItemsLayout([Parameter("Orientation")] ItemsLayoutOrientation orientation) : base(orientation)
|
||||
public LinearItemsLayout([Parameter("Orientation")] ItemsLayoutOrientation orientation) : base(orientation)
|
||||
{
|
||||
}
|
||||
|
||||
public static readonly IItemsLayout Vertical = new ListItemsLayout(ItemsLayoutOrientation.Vertical);
|
||||
public static readonly IItemsLayout Horizontal = new ListItemsLayout(ItemsLayoutOrientation.Horizontal);
|
||||
public static readonly IItemsLayout Vertical = new LinearItemsLayout(ItemsLayoutOrientation.Vertical);
|
||||
public static readonly IItemsLayout Horizontal = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);
|
||||
|
||||
// TODO hartez 2018/08/29 20:31:54 Need something like these previous two, but as a carousel default
|
||||
|
||||
public static readonly BindableProperty ItemSpacingProperty =
|
||||
BindableProperty.Create(nameof(ItemSpacing), typeof(double), typeof(ListItemsLayout), default(double),
|
||||
BindableProperty.Create(nameof(ItemSpacing), typeof(double), typeof(LinearItemsLayout), default(double),
|
||||
validateValue: (bindable, value) => (double)value >= 0);
|
||||
|
||||
public double ItemSpacing
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Windows.Input;
|
|||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
public class SelectableItemsView : ItemsView
|
||||
public class SelectableItemsView : StructuredItemsView
|
||||
{
|
||||
public static readonly BindableProperty SelectionModeProperty =
|
||||
BindableProperty.Create(nameof(SelectionMode), typeof(SelectionMode), typeof(SelectableItemsView),
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
namespace Xamarin.Forms
|
||||
{
|
||||
public class StructuredItemsView : ItemsView
|
||||
{
|
||||
public static readonly BindableProperty HeaderProperty =
|
||||
BindableProperty.Create(nameof(Header), typeof(object), typeof(ItemsView), null);
|
||||
|
||||
public object Header
|
||||
{
|
||||
get => GetValue(HeaderProperty);
|
||||
set => SetValue(HeaderProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty HeaderTemplateProperty =
|
||||
BindableProperty.Create(nameof(HeaderTemplate), typeof(DataTemplate), typeof(ItemsView), null);
|
||||
|
||||
public DataTemplate HeaderTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(HeaderTemplateProperty);
|
||||
set => SetValue(HeaderTemplateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty FooterProperty =
|
||||
BindableProperty.Create(nameof(Footer), typeof(object), typeof(ItemsView), null);
|
||||
|
||||
public object Footer
|
||||
{
|
||||
get => GetValue(FooterProperty);
|
||||
set => SetValue(FooterProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty FooterTemplateProperty =
|
||||
BindableProperty.Create(nameof(FooterTemplate), typeof(DataTemplate), typeof(ItemsView), null);
|
||||
|
||||
public DataTemplate FooterTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(FooterTemplateProperty);
|
||||
set => SetValue(FooterTemplateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ItemsLayoutProperty =
|
||||
BindableProperty.Create(nameof(ItemsLayout), typeof(IItemsLayout), typeof(ItemsView),
|
||||
LinearItemsLayout.Vertical);
|
||||
|
||||
public IItemsLayout ItemsLayout
|
||||
{
|
||||
get => InternalItemsLayout;
|
||||
set => InternalItemsLayout = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_horizontalSpacing = gridItemsLayout.HorizontalItemSpacing;
|
||||
_verticalSpacing = gridItemsLayout.VerticalItemSpacing;
|
||||
break;
|
||||
case ListItemsLayout listItemsLayout:
|
||||
case LinearItemsLayout listItemsLayout:
|
||||
_orientation = listItemsLayout.Orientation;
|
||||
if (_orientation == ItemsLayoutOrientation.Horizontal)
|
||||
_horizontalSpacing = listItemsLayout.ItemSpacing;
|
||||
|
|
|
@ -39,16 +39,16 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
protected override void SetUpNewElement(ItemsView newElement)
|
||||
{
|
||||
Carousel = newElement as CarouselView;
|
||||
|
||||
base.SetUpNewElement(newElement);
|
||||
|
||||
if (newElement == null)
|
||||
{
|
||||
Carousel = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Carousel = newElement as CarouselView;
|
||||
_layout = ItemsView.ItemsLayout;
|
||||
_layout = Carousel.ItemsLayout;
|
||||
|
||||
UpdateIsSwipeEnabled();
|
||||
UpdateInitialPosition();
|
||||
|
@ -68,7 +68,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateIsSwipeEnabled();
|
||||
else if (changedProperty.Is(CarouselView.IsBounceEnabledProperty))
|
||||
UpdateIsBounceEnabled();
|
||||
else if (changedProperty.Is(ListItemsLayout.ItemSpacingProperty))
|
||||
else if (changedProperty.Is(LinearItemsLayout.ItemSpacingProperty))
|
||||
UpdateItemSpacing();
|
||||
}
|
||||
|
||||
|
@ -131,11 +131,17 @@ namespace Xamarin.Forms.Platform.Android
|
|||
base.UpdateItemSpacing();
|
||||
}
|
||||
|
||||
|
||||
protected override IItemsLayout GetItemsLayout()
|
||||
{
|
||||
return Carousel.ItemsLayout;
|
||||
}
|
||||
|
||||
int GetItemWidth()
|
||||
{
|
||||
var itemWidth = Width;
|
||||
|
||||
if (_layout is ListItemsLayout listItemsLayout && listItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal)
|
||||
if (_layout is LinearItemsLayout listItemsLayout && listItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal)
|
||||
{
|
||||
var numberOfVisibleItems = Carousel.NumberOfSideItems * 2 + 1;
|
||||
itemWidth = (int)(Width - Carousel.PeekAreaInsets.Left - Carousel.PeekAreaInsets.Right - Context?.ToPixels(listItemsLayout.ItemSpacing)) / numberOfVisibleItems;
|
||||
|
@ -148,7 +154,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
var itemHeight = Height;
|
||||
|
||||
if (_layout is ListItemsLayout listItemsLayout && listItemsLayout.Orientation == ItemsLayoutOrientation.Vertical)
|
||||
if (_layout is LinearItemsLayout listItemsLayout && listItemsLayout.Orientation == ItemsLayoutOrientation.Vertical)
|
||||
{
|
||||
var numberOfVisibleItems = Carousel.NumberOfSideItems * 2 + 1;
|
||||
itemHeight = (int)(Height - Carousel.PeekAreaInsets.Top - Carousel.PeekAreaInsets.Bottom - Context?.ToPixels(listItemsLayout.ItemSpacing)) / numberOfVisibleItems;
|
||||
|
|
|
@ -33,9 +33,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_createItemContentView = createItemContentView;
|
||||
ItemsSource = CreateItemsSource();
|
||||
|
||||
UpdateHasHeader();
|
||||
UpdateHasFooter();
|
||||
|
||||
if (_createItemContentView == null)
|
||||
{
|
||||
_createItemContentView = (view, context) => new ItemContentView(context);
|
||||
|
@ -53,18 +50,10 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
UpdateItemsSource();
|
||||
}
|
||||
else if (property.Is(Xamarin.Forms.ItemsView.HeaderProperty))
|
||||
{
|
||||
UpdateHasHeader();
|
||||
}
|
||||
else if (property.Is(Xamarin.Forms.ItemsView.ItemTemplateProperty))
|
||||
{
|
||||
UpdateUsingItemTemplate();
|
||||
}
|
||||
else if (property.Is(Xamarin.Forms.ItemsView.FooterProperty))
|
||||
{
|
||||
UpdateHasFooter();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnViewRecycled(Object holder)
|
||||
|
@ -79,26 +68,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
|
||||
{
|
||||
if (IsHeader(position))
|
||||
{
|
||||
if (holder is TemplatedItemViewHolder templatedItemViewHolder)
|
||||
{
|
||||
BindTemplatedItemViewHolder(templatedItemViewHolder, ItemsView.Header);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFooter(position))
|
||||
{
|
||||
if (holder is TemplatedItemViewHolder templatedItemViewHolder)
|
||||
{
|
||||
BindTemplatedItemViewHolder(templatedItemViewHolder, ItemsView.Footer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (holder)
|
||||
{
|
||||
case TextViewHolder textViewHolder:
|
||||
|
@ -114,16 +83,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
var context = parent.Context;
|
||||
|
||||
if (viewType == ItemViewType.Header)
|
||||
{
|
||||
return CreateHeaderFooterViewHolder(ItemsView.Header, ItemsView.HeaderTemplate, context);
|
||||
}
|
||||
|
||||
if (viewType == ItemViewType.Footer)
|
||||
{
|
||||
return CreateHeaderFooterViewHolder(ItemsView.Footer, ItemsView.FooterTemplate, context);
|
||||
}
|
||||
|
||||
if (viewType == ItemViewType.TextItem)
|
||||
{
|
||||
var view = new TextView(context);
|
||||
|
@ -139,16 +98,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
public override int GetItemViewType(int position)
|
||||
{
|
||||
if (IsHeader(position))
|
||||
{
|
||||
return ItemViewType.Header;
|
||||
}
|
||||
|
||||
if (IsFooter(position))
|
||||
{
|
||||
return ItemViewType.Footer;
|
||||
}
|
||||
|
||||
if (_usingItemTemplate)
|
||||
{
|
||||
return ItemViewType.TemplatedItem;
|
||||
|
@ -207,42 +156,5 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
_usingItemTemplate = ItemsView.ItemTemplate != null;
|
||||
}
|
||||
|
||||
void UpdateHasHeader()
|
||||
{
|
||||
ItemsSource.HasHeader = ItemsView.Header != null;
|
||||
}
|
||||
|
||||
void UpdateHasFooter()
|
||||
{
|
||||
ItemsSource.HasFooter = ItemsView.Footer != null;
|
||||
}
|
||||
|
||||
bool IsHeader(int position)
|
||||
{
|
||||
return ItemsSource.IsHeader(position);
|
||||
}
|
||||
|
||||
bool IsFooter(int position)
|
||||
{
|
||||
return ItemsSource.IsFooter(position);
|
||||
}
|
||||
|
||||
protected RecyclerView.ViewHolder CreateHeaderFooterViewHolder(object content, DataTemplate template, Context context)
|
||||
{
|
||||
if (template != null)
|
||||
{
|
||||
var footerContentView = new ItemContentView(context);
|
||||
return new TemplatedItemViewHolder(footerContentView, template, isSelectionEnabled: false);
|
||||
}
|
||||
|
||||
if (content is View formsView)
|
||||
{
|
||||
return SimpleViewHolder.FromFormsView(formsView, context);
|
||||
}
|
||||
|
||||
// No template, Footer is not a Forms View, so just display Footer.ToString
|
||||
return SimpleViewHolder.FromText(content?.ToString(), context, fill: false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ using AViewCompat = Android.Support.V4.View.ViewCompat;
|
|||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
public class ItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource> : RecyclerView, IVisualElementRenderer, IEffectControlProvider
|
||||
public abstract class ItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource> : RecyclerView, IVisualElementRenderer, IEffectControlProvider
|
||||
where TItemsView : ItemsView
|
||||
where TAdapter : ItemsViewAdapter<TItemsView, TItemsViewSource>
|
||||
where TItemsViewSource : IItemsViewSource
|
||||
|
@ -56,8 +56,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
ScrollHelper ScrollHelper => _scrollHelper = _scrollHelper ?? new ScrollHelper(this);
|
||||
|
||||
// TODO hartez 2018/10/24 19:27:12 Region all the interface implementations
|
||||
|
||||
protected override void OnLayout(bool changed, int l, int t, int r, int b)
|
||||
{
|
||||
base.OnLayout(changed, l, t, r, b);
|
||||
|
@ -167,7 +165,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
case GridItemsLayout gridItemsLayout:
|
||||
return CreateGridLayout(gridItemsLayout);
|
||||
case ListItemsLayout listItemsLayout:
|
||||
case LinearItemsLayout listItemsLayout:
|
||||
var orientation = listItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal
|
||||
? LinearLayoutManager.Horizontal
|
||||
: LinearLayoutManager.Vertical;
|
||||
|
@ -305,7 +303,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
UpdateItemsSource();
|
||||
|
||||
_layout = ItemsView.ItemsLayout;
|
||||
_layout = GetItemsLayout();
|
||||
SetLayoutManager(SelectLayoutManager(_layout));
|
||||
|
||||
UpdateSnapBehavior();
|
||||
|
@ -329,6 +327,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
AddOnScrollListener(_recyclerViewScrollListener);
|
||||
}
|
||||
|
||||
protected abstract IItemsLayout GetItemsLayout();
|
||||
|
||||
protected virtual void UpdateVerticalScrollBarVisibility()
|
||||
{
|
||||
if (_defaultVerticalScrollVisibility == ScrollBarVisibility.Default)
|
||||
|
@ -420,7 +420,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
UpdateSnapBehavior();
|
||||
}
|
||||
else if (propertyChanged.IsOneOf(ListItemsLayout.ItemSpacingProperty,
|
||||
else if (propertyChanged.IsOneOf(LinearItemsLayout.ItemSpacingProperty,
|
||||
GridItemsLayout.HorizontalItemSpacingProperty, GridItemsLayout.VerticalItemSpacingProperty))
|
||||
{
|
||||
UpdateItemSpacing();
|
||||
|
@ -438,7 +438,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
if (_snapManager == null)
|
||||
{
|
||||
_snapManager = new SnapManager(ItemsView, this);
|
||||
_snapManager = new SnapManager(_layout, this);
|
||||
}
|
||||
return _snapManager;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ using Object = Java.Lang.Object;
|
|||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
public class SelectableItemsViewAdapter<TItemsView, TItemsSource> : ItemsViewAdapter<TItemsView, TItemsSource>
|
||||
public class SelectableItemsViewAdapter<TItemsView, TItemsSource> : StructuredItemsViewAdapter<TItemsView, TItemsSource>
|
||||
where TItemsView : SelectableItemsView
|
||||
where TItemsSource : IItemsViewSource
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ using Android.Content;
|
|||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
public class SelectableItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource> : ItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource>
|
||||
public class SelectableItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource> : StructuredItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource>
|
||||
where TItemsView : SelectableItemsView
|
||||
where TAdapter : SelectableItemsViewAdapter<TItemsView, TItemsViewSource>
|
||||
where TItemsViewSource : IItemsViewSource
|
||||
|
|
|
@ -5,20 +5,20 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
public class SnapManager : IDisposable
|
||||
{
|
||||
readonly IItemsLayout _itemsLayout;
|
||||
readonly RecyclerView _recyclerView;
|
||||
readonly ItemsView _itemsView;
|
||||
SnapHelper _snapHelper;
|
||||
|
||||
public SnapManager(ItemsView itemsView, RecyclerView recyclerView)
|
||||
public SnapManager(IItemsLayout itemsLayout, RecyclerView recyclerView)
|
||||
{
|
||||
Xamarin.Forms.CollectionView.VerifyCollectionViewFlagEnabled(nameof(SnapManager));
|
||||
_itemsLayout = itemsLayout;
|
||||
_recyclerView = recyclerView;
|
||||
_itemsView = itemsView;
|
||||
}
|
||||
|
||||
internal void UpdateSnapBehavior()
|
||||
{
|
||||
if (!(_itemsView.ItemsLayout is ItemsLayout itemsLayout))
|
||||
if (!(_itemsLayout is ItemsLayout itemsLayout))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_horizontalSpacing = gridItemsLayout.HorizontalItemSpacing;
|
||||
_verticalSpacing = gridItemsLayout.VerticalItemSpacing;
|
||||
break;
|
||||
case ListItemsLayout listItemsLayout:
|
||||
case LinearItemsLayout listItemsLayout:
|
||||
_orientation = listItemsLayout.Orientation;
|
||||
if (_orientation == ItemsLayoutOrientation.Horizontal)
|
||||
_horizontalSpacing = listItemsLayout.ItemSpacing;
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Support.V7.Widget;
|
||||
using ViewGroup = Android.Views.ViewGroup;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
public class StructuredItemsViewAdapter<TItemsView, TItemsViewSource> : ItemsViewAdapter<TItemsView, TItemsViewSource>
|
||||
where TItemsView : StructuredItemsView
|
||||
where TItemsViewSource : IItemsViewSource
|
||||
{
|
||||
internal StructuredItemsViewAdapter(TItemsView itemsView,
|
||||
Func<View, Context, ItemContentView> createItemContentView = null) : base(itemsView, createItemContentView)
|
||||
{
|
||||
UpdateHasHeader();
|
||||
UpdateHasFooter();
|
||||
}
|
||||
|
||||
protected override void ItemsViewPropertyChanged(object sender, PropertyChangedEventArgs property)
|
||||
{
|
||||
base.ItemsViewPropertyChanged(sender, property);
|
||||
|
||||
if (property.Is(Xamarin.Forms.StructuredItemsView.HeaderProperty))
|
||||
{
|
||||
UpdateHasHeader();
|
||||
}
|
||||
else if (property.Is(Xamarin.Forms.StructuredItemsView.FooterProperty))
|
||||
{
|
||||
UpdateHasFooter();
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetItemViewType(int position)
|
||||
{
|
||||
if (IsHeader(position))
|
||||
{
|
||||
return ItemViewType.Header;
|
||||
}
|
||||
|
||||
if (IsFooter(position))
|
||||
{
|
||||
return ItemViewType.Footer;
|
||||
}
|
||||
|
||||
return base.GetItemViewType(position);
|
||||
}
|
||||
|
||||
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
|
||||
{
|
||||
var context = parent.Context;
|
||||
|
||||
if (viewType == ItemViewType.Header)
|
||||
{
|
||||
return CreateHeaderFooterViewHolder(ItemsView.Header, ItemsView.HeaderTemplate, context);
|
||||
}
|
||||
|
||||
if (viewType == ItemViewType.Footer)
|
||||
{
|
||||
return CreateHeaderFooterViewHolder(ItemsView.Footer, ItemsView.FooterTemplate, context);
|
||||
}
|
||||
|
||||
return base.OnCreateViewHolder(parent, viewType);
|
||||
}
|
||||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
|
||||
{
|
||||
if (IsHeader(position))
|
||||
{
|
||||
if (holder is TemplatedItemViewHolder templatedItemViewHolder)
|
||||
{
|
||||
BindTemplatedItemViewHolder(templatedItemViewHolder, ItemsView.Header);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFooter(position))
|
||||
{
|
||||
if (holder is TemplatedItemViewHolder templatedItemViewHolder)
|
||||
{
|
||||
BindTemplatedItemViewHolder(templatedItemViewHolder, ItemsView.Footer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnBindViewHolder(holder, position);
|
||||
}
|
||||
|
||||
void UpdateHasHeader()
|
||||
{
|
||||
ItemsSource.HasHeader = ItemsView.Header != null;
|
||||
}
|
||||
|
||||
void UpdateHasFooter()
|
||||
{
|
||||
ItemsSource.HasFooter = ItemsView.Footer != null;
|
||||
}
|
||||
|
||||
bool IsHeader(int position)
|
||||
{
|
||||
return ItemsSource.IsHeader(position);
|
||||
}
|
||||
|
||||
bool IsFooter(int position)
|
||||
{
|
||||
return ItemsSource.IsFooter(position);
|
||||
}
|
||||
|
||||
protected RecyclerView.ViewHolder CreateHeaderFooterViewHolder(object content, DataTemplate template, Context context)
|
||||
{
|
||||
if (template != null)
|
||||
{
|
||||
var footerContentView = new ItemContentView(context);
|
||||
return new TemplatedItemViewHolder(footerContentView, template, isSelectionEnabled: false);
|
||||
}
|
||||
|
||||
if (content is View formsView)
|
||||
{
|
||||
return SimpleViewHolder.FromFormsView(formsView, context);
|
||||
}
|
||||
|
||||
// No template, Footer is not a Forms View, so just display Footer.ToString
|
||||
return SimpleViewHolder.FromText(content?.ToString(), context, fill: false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using Android.Content;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
public class StructuredItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource> : ItemsViewRenderer<TItemsView, TAdapter, TItemsViewSource>
|
||||
where TItemsView : StructuredItemsView
|
||||
where TAdapter : StructuredItemsViewAdapter<TItemsView, TItemsViewSource>
|
||||
where TItemsViewSource : IItemsViewSource
|
||||
{
|
||||
StructuredItemsView _itemsView;
|
||||
|
||||
public StructuredItemsViewRenderer(Context context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
protected override TAdapter CreateAdapter()
|
||||
{
|
||||
return (TAdapter)new StructuredItemsViewAdapter<TItemsView, TItemsViewSource>(ItemsView);
|
||||
}
|
||||
|
||||
protected override void SetUpNewElement(TItemsView newElement)
|
||||
{
|
||||
_itemsView = newElement;
|
||||
|
||||
base.SetUpNewElement(newElement);
|
||||
}
|
||||
|
||||
protected override IItemsLayout GetItemsLayout()
|
||||
{
|
||||
return _itemsView.ItemsLayout;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,6 +102,8 @@
|
|||
<Compile Include="CollectionView\SpacingItemDecoration.cs" />
|
||||
<Compile Include="CollectionView\StartSingleSnapHelper.cs" />
|
||||
<Compile Include="CollectionView\StartSnapHelper.cs" />
|
||||
<Compile Include="CollectionView\StructuredItemsViewAdapter.cs" />
|
||||
<Compile Include="CollectionView\StructuredItemsViewRenderer.cs" />
|
||||
<Compile Include="CollectionView\TemplatedItemViewHolder.cs" />
|
||||
<Compile Include="CollectionView\TextViewHolder.cs" />
|
||||
<Compile Include="CollectionView\ItemViewType.cs" />
|
||||
|
|
|
@ -5,7 +5,7 @@ using Xamarin.Forms.Platform.Tizen.Native;
|
|||
|
||||
namespace Xamarin.Forms.Platform.Tizen
|
||||
{
|
||||
public class ItemsViewRenderer : ViewRenderer<ItemsView, Native.CollectionView>
|
||||
public class ItemsViewRenderer : ViewRenderer<StructuredItemsView, Native.CollectionView>
|
||||
{
|
||||
INotifyCollectionChanged _observableSource;
|
||||
|
||||
|
@ -13,13 +13,13 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
{
|
||||
RegisterPropertyHandler(ItemsView.ItemsSourceProperty, UpdateItemsSource);
|
||||
RegisterPropertyHandler(ItemsView.ItemTemplateProperty, UpdateAdaptor);
|
||||
RegisterPropertyHandler(ItemsView.ItemsLayoutProperty, UpdateItemsLayout);
|
||||
RegisterPropertyHandler(StructuredItemsView.ItemsLayoutProperty, UpdateItemsLayout);
|
||||
RegisterPropertyHandler(ItemsView.ItemSizingStrategyProperty, UpdateSizingStrategy);
|
||||
RegisterPropertyHandler(SelectableItemsView.SelectedItemProperty, UpdateSelectedItem);
|
||||
RegisterPropertyHandler(SelectableItemsView.SelectionModeProperty, UpdateSelectionMode);
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<ItemsView> e)
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<StructuredItemsView> e)
|
||||
{
|
||||
if (Control == null)
|
||||
{
|
||||
|
@ -178,7 +178,7 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
{
|
||||
switch (layout)
|
||||
{
|
||||
case ListItemsLayout listItemsLayout:
|
||||
case LinearItemsLayout listItemsLayout:
|
||||
return new LinearLayoutManager(listItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal, sizing);
|
||||
case GridItemsLayout gridItemsLayout:
|
||||
return new GridLayoutManager(gridItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal, gridItemsLayout.Span, sizing);
|
||||
|
|
|
@ -17,20 +17,16 @@ using UWPDataTemplate = Windows.UI.Xaml.DataTemplate;
|
|||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
public class ItemsViewRenderer : ViewRenderer<ItemsView, ListViewBase>
|
||||
public abstract class ItemsViewRenderer : ViewRenderer<ItemsView, ListViewBase>
|
||||
{
|
||||
IItemsLayout _layout;
|
||||
CollectionViewSource _collectionViewSource;
|
||||
|
||||
protected ListViewBase ListViewBase { get; private set; }
|
||||
UwpScrollBarVisibility? _defaultHorizontalScrollVisibility;
|
||||
UwpScrollBarVisibility? _defaultVerticalScrollVisibility;
|
||||
|
||||
UWPDataTemplate ViewTemplate => (UWPDataTemplate)UWPApp.Current.Resources["View"];
|
||||
UWPDataTemplate ItemsViewTemplate => (UWPDataTemplate)UWPApp.Current.Resources["ItemsViewDefaultTemplate"];
|
||||
|
||||
View _currentHeader;
|
||||
View _currentFooter;
|
||||
protected UWPDataTemplate ViewTemplate => (UWPDataTemplate)UWPApp.Current.Resources["View"];
|
||||
protected UWPDataTemplate ItemsViewTemplate => (UWPDataTemplate)UWPApp.Current.Resources["ItemsViewDefaultTemplate"];
|
||||
|
||||
protected ItemsControl ItemsControl { get; private set; }
|
||||
|
||||
|
@ -53,7 +49,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
UpdateItemTemplate();
|
||||
}
|
||||
else if(changedProperty.Is(ItemsView.HorizontalScrollBarVisibilityProperty))
|
||||
else if (changedProperty.Is(ItemsView.HorizontalScrollBarVisibilityProperty))
|
||||
{
|
||||
UpdateHorizontalScrollBarVisibility();
|
||||
}
|
||||
|
@ -61,30 +57,11 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
UpdateVerticalScrollBarVisibility();
|
||||
}
|
||||
else if (changedProperty.IsOneOf(ItemsView.HeaderProperty, ItemsView.HeaderTemplateProperty))
|
||||
{
|
||||
UpdateHeader();
|
||||
}
|
||||
else if (changedProperty.IsOneOf(ItemsView.FooterProperty, ItemsView.FooterTemplateProperty))
|
||||
{
|
||||
UpdateFooter();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ListViewBase SelectLayout(IItemsLayout layoutSpecification)
|
||||
{
|
||||
switch (layoutSpecification)
|
||||
{
|
||||
case GridItemsLayout gridItemsLayout:
|
||||
return CreateGridView(gridItemsLayout);
|
||||
case ListItemsLayout listItemsLayout
|
||||
when listItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal:
|
||||
return CreateHorizontalListView();
|
||||
}
|
||||
|
||||
// Default to a plain old vertical ListView
|
||||
return new Windows.UI.Xaml.Controls.ListView();
|
||||
}
|
||||
protected abstract ListViewBase SelectListViewBase();
|
||||
protected abstract void HandleLayoutPropertyChange(PropertyChangedEventArgs property);
|
||||
protected abstract IItemsLayout Layout { get; }
|
||||
|
||||
protected virtual void UpdateItemsSource()
|
||||
{
|
||||
|
@ -145,153 +122,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateItemsSource();
|
||||
}
|
||||
|
||||
protected virtual void UpdateHeader()
|
||||
{
|
||||
if (ListViewBase == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentHeader != null)
|
||||
{
|
||||
Element.RemoveLogicalChild(_currentHeader);
|
||||
_currentHeader = null;
|
||||
}
|
||||
|
||||
var header = Element.Header;
|
||||
|
||||
switch (header)
|
||||
{
|
||||
case null:
|
||||
ListViewBase.Header = null;
|
||||
break;
|
||||
|
||||
case string text:
|
||||
ListViewBase.HeaderTemplate = null;
|
||||
ListViewBase.Header = new TextBlock { Text = text };
|
||||
break;
|
||||
|
||||
case View view:
|
||||
ListViewBase.HeaderTemplate = ViewTemplate;
|
||||
_currentHeader = view;
|
||||
Element.AddLogicalChild(_currentHeader);
|
||||
ListViewBase.Header = view;
|
||||
break;
|
||||
|
||||
default:
|
||||
var headerTemplate = Element.HeaderTemplate;
|
||||
if (headerTemplate != null)
|
||||
{
|
||||
ListViewBase.HeaderTemplate = ItemsViewTemplate;
|
||||
ListViewBase.Header = new ItemTemplateContext(headerTemplate, header, Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
ListViewBase.HeaderTemplate = null;
|
||||
ListViewBase.Header = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateFooter()
|
||||
{
|
||||
if (ListViewBase == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentFooter != null)
|
||||
{
|
||||
Element.RemoveLogicalChild(_currentFooter);
|
||||
_currentFooter = null;
|
||||
}
|
||||
|
||||
var footer = Element.Footer;
|
||||
|
||||
switch (footer)
|
||||
{
|
||||
case null:
|
||||
ListViewBase.Footer = null;
|
||||
break;
|
||||
|
||||
case string text:
|
||||
ListViewBase.FooterTemplate = null;
|
||||
ListViewBase.Footer = new TextBlock { Text = text };
|
||||
break;
|
||||
|
||||
case View view:
|
||||
ListViewBase.FooterTemplate = ViewTemplate;
|
||||
_currentFooter = view;
|
||||
Element.AddLogicalChild(_currentFooter);
|
||||
ListViewBase.Footer = view;
|
||||
break;
|
||||
|
||||
default:
|
||||
var footerTemplate = Element.FooterTemplate;
|
||||
if (footerTemplate != null)
|
||||
{
|
||||
ListViewBase.FooterTemplate = ItemsViewTemplate;
|
||||
ListViewBase.Footer = new ItemTemplateContext(footerTemplate, footer, Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
ListViewBase.FooterTemplate = null;
|
||||
ListViewBase.Footer = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ListViewBase CreateGridView(GridItemsLayout gridItemsLayout)
|
||||
{
|
||||
var gridView = new FormsGridView();
|
||||
|
||||
if (gridItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal)
|
||||
{
|
||||
gridView.UseHorizontalItemsPanel();
|
||||
|
||||
// TODO hartez 2018/06/06 12:13:38 Should this logic just be built into FormsGridView?
|
||||
ScrollViewer.SetHorizontalScrollMode(gridView, ScrollMode.Auto);
|
||||
ScrollViewer.SetHorizontalScrollBarVisibility(gridView,
|
||||
Windows.UI.Xaml.Controls.ScrollBarVisibility.Auto);
|
||||
}
|
||||
else
|
||||
{
|
||||
gridView.UseVerticalalItemsPanel();
|
||||
}
|
||||
|
||||
gridView.MaximumRowsOrColumns = gridItemsLayout.Span;
|
||||
|
||||
return gridView;
|
||||
}
|
||||
|
||||
static ListViewBase CreateHorizontalListView()
|
||||
{
|
||||
// TODO hartez 2018/06/05 16:18:57 Is there any performance benefit to caching the ItemsPanelTemplate lookup?
|
||||
// TODO hartez 2018/05/29 15:38:04 Make sure the ItemsViewStyles.xaml xbf gets into the nuspec
|
||||
var horizontalListView = new Windows.UI.Xaml.Controls.ListView()
|
||||
{
|
||||
ItemsPanel =
|
||||
(ItemsPanelTemplate)Windows.UI.Xaml.Application.Current.Resources["HorizontalListItemsPanel"]
|
||||
};
|
||||
|
||||
ScrollViewer.SetHorizontalScrollMode(horizontalListView, ScrollMode.Auto);
|
||||
ScrollViewer.SetHorizontalScrollBarVisibility(horizontalListView,
|
||||
Windows.UI.Xaml.Controls.ScrollBarVisibility.Auto);
|
||||
|
||||
return horizontalListView;
|
||||
}
|
||||
|
||||
void LayoutPropertyChanged(object sender, PropertyChangedEventArgs property)
|
||||
{
|
||||
if (property.Is(GridItemsLayout.SpanProperty))
|
||||
{
|
||||
if (ListViewBase is FormsGridView formsGridView)
|
||||
{
|
||||
formsGridView.MaximumRowsOrColumns = ((GridItemsLayout)_layout).Span;
|
||||
}
|
||||
}
|
||||
HandleLayoutPropertyChange(property);
|
||||
}
|
||||
|
||||
protected virtual void SetUpNewElement(ItemsView newElement)
|
||||
|
@ -303,19 +136,16 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
if (ListViewBase == null)
|
||||
{
|
||||
ListViewBase = SelectLayout(newElement.ItemsLayout);
|
||||
ListViewBase = SelectListViewBase();
|
||||
ListViewBase.IsSynchronizedWithCurrentItem = false;
|
||||
|
||||
_layout = newElement.ItemsLayout;
|
||||
_layout.PropertyChanged += LayoutPropertyChanged;
|
||||
Layout.PropertyChanged += LayoutPropertyChanged;
|
||||
|
||||
SetNativeControl(ListViewBase);
|
||||
}
|
||||
|
||||
UpdateItemTemplate();
|
||||
UpdateItemsSource();
|
||||
UpdateHeader();
|
||||
UpdateFooter();
|
||||
UpdateVerticalScrollBarVisibility();
|
||||
UpdateHorizontalScrollBarVisibility();
|
||||
|
||||
|
@ -330,11 +160,10 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
return;
|
||||
}
|
||||
|
||||
if (_layout != null)
|
||||
if (Layout != null)
|
||||
{
|
||||
// Stop tracking the old layout
|
||||
_layout.PropertyChanged -= LayoutPropertyChanged;
|
||||
_layout = null;
|
||||
Layout.PropertyChanged -= LayoutPropertyChanged;
|
||||
}
|
||||
|
||||
// Stop listening for ScrollTo requests
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using UWPListViewSelectionMode = Windows.UI.Xaml.Controls.ListViewSelectionMode;
|
||||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
public class SelectableItemsViewRenderer : ItemsViewRenderer
|
||||
public class SelectableItemsViewRenderer : StructuredItemsViewRenderer
|
||||
{
|
||||
SelectableItemsView _selectableItemsView;
|
||||
bool _ignoreNativeSelectionChange;
|
||||
|
@ -219,6 +218,5 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
using System.ComponentModel;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Xamarin.Forms.Platform.UAP;
|
||||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
public class StructuredItemsViewRenderer : ItemsViewRenderer
|
||||
{
|
||||
StructuredItemsView _structuredItemsView;
|
||||
View _currentHeader;
|
||||
View _currentFooter;
|
||||
|
||||
protected override IItemsLayout Layout { get => _structuredItemsView.ItemsLayout; }
|
||||
|
||||
protected override void SetUpNewElement(ItemsView newElement)
|
||||
{
|
||||
_structuredItemsView = newElement as StructuredItemsView;
|
||||
|
||||
base.SetUpNewElement(newElement);
|
||||
|
||||
if (newElement == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateHeader();
|
||||
UpdateFooter();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs changedProperty)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, changedProperty);
|
||||
|
||||
if (changedProperty.IsOneOf(StructuredItemsView.HeaderProperty, StructuredItemsView.HeaderTemplateProperty))
|
||||
{
|
||||
UpdateHeader();
|
||||
}
|
||||
else if (changedProperty.IsOneOf(StructuredItemsView.FooterProperty, StructuredItemsView.FooterTemplateProperty))
|
||||
{
|
||||
UpdateFooter();
|
||||
}
|
||||
}
|
||||
|
||||
protected override ListViewBase SelectListViewBase()
|
||||
{
|
||||
switch (Layout)
|
||||
{
|
||||
case GridItemsLayout gridItemsLayout:
|
||||
return CreateGridView(gridItemsLayout);
|
||||
case LinearItemsLayout listItemsLayout
|
||||
when listItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal:
|
||||
return CreateHorizontalListView();
|
||||
}
|
||||
|
||||
// Default to a plain old vertical ListView
|
||||
return new Windows.UI.Xaml.Controls.ListView();
|
||||
}
|
||||
|
||||
protected virtual void UpdateHeader()
|
||||
{
|
||||
if (ListViewBase == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentHeader != null)
|
||||
{
|
||||
Element.RemoveLogicalChild(_currentHeader);
|
||||
_currentHeader = null;
|
||||
}
|
||||
|
||||
var header = _structuredItemsView.Header;
|
||||
|
||||
switch (header)
|
||||
{
|
||||
case null:
|
||||
ListViewBase.Header = null;
|
||||
break;
|
||||
|
||||
case string text:
|
||||
ListViewBase.HeaderTemplate = null;
|
||||
ListViewBase.Header = new TextBlock { Text = text };
|
||||
break;
|
||||
|
||||
case View view:
|
||||
ListViewBase.HeaderTemplate = ViewTemplate;
|
||||
_currentHeader = view;
|
||||
Element.AddLogicalChild(_currentHeader);
|
||||
ListViewBase.Header = view;
|
||||
break;
|
||||
|
||||
default:
|
||||
var headerTemplate = _structuredItemsView.HeaderTemplate;
|
||||
if (headerTemplate != null)
|
||||
{
|
||||
ListViewBase.HeaderTemplate = ItemsViewTemplate;
|
||||
ListViewBase.Header = new ItemTemplateContext(headerTemplate, header, Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
ListViewBase.HeaderTemplate = null;
|
||||
ListViewBase.Header = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateFooter()
|
||||
{
|
||||
if (ListViewBase == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentFooter != null)
|
||||
{
|
||||
Element.RemoveLogicalChild(_currentFooter);
|
||||
_currentFooter = null;
|
||||
}
|
||||
|
||||
var footer = _structuredItemsView.Footer;
|
||||
|
||||
switch (footer)
|
||||
{
|
||||
case null:
|
||||
ListViewBase.Footer = null;
|
||||
break;
|
||||
|
||||
case string text:
|
||||
ListViewBase.FooterTemplate = null;
|
||||
ListViewBase.Footer = new TextBlock { Text = text };
|
||||
break;
|
||||
|
||||
case View view:
|
||||
ListViewBase.FooterTemplate = ViewTemplate;
|
||||
_currentFooter = view;
|
||||
Element.AddLogicalChild(_currentFooter);
|
||||
ListViewBase.Footer = view;
|
||||
break;
|
||||
|
||||
default:
|
||||
var footerTemplate = _structuredItemsView.FooterTemplate;
|
||||
if (footerTemplate != null)
|
||||
{
|
||||
ListViewBase.FooterTemplate = ItemsViewTemplate;
|
||||
ListViewBase.Footer = new ItemTemplateContext(footerTemplate, footer, Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
ListViewBase.FooterTemplate = null;
|
||||
ListViewBase.Footer = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void HandleLayoutPropertyChange(PropertyChangedEventArgs property)
|
||||
{
|
||||
if (property.Is(GridItemsLayout.SpanProperty))
|
||||
{
|
||||
if (ListViewBase is FormsGridView formsGridView)
|
||||
{
|
||||
formsGridView.MaximumRowsOrColumns = ((GridItemsLayout)Layout).Span;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ListViewBase CreateGridView(GridItemsLayout gridItemsLayout)
|
||||
{
|
||||
var gridView = new FormsGridView();
|
||||
|
||||
if (gridItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal)
|
||||
{
|
||||
gridView.UseHorizontalItemsPanel();
|
||||
|
||||
// TODO hartez 2018/06/06 12:13:38 Should this logic just be built into FormsGridView?
|
||||
ScrollViewer.SetHorizontalScrollMode(gridView, ScrollMode.Auto);
|
||||
ScrollViewer.SetHorizontalScrollBarVisibility(gridView,
|
||||
Windows.UI.Xaml.Controls.ScrollBarVisibility.Auto);
|
||||
}
|
||||
else
|
||||
{
|
||||
gridView.UseVerticalalItemsPanel();
|
||||
}
|
||||
|
||||
gridView.MaximumRowsOrColumns = gridItemsLayout.Span;
|
||||
|
||||
return gridView;
|
||||
}
|
||||
|
||||
static ListViewBase CreateHorizontalListView()
|
||||
{
|
||||
// TODO hartez 2018/06/05 16:18:57 Is there any performance benefit to caching the ItemsPanelTemplate lookup?
|
||||
// TODO hartez 2018/05/29 15:38:04 Make sure the ItemsViewStyles.xaml xbf gets into the nuspec
|
||||
var horizontalListView = new Windows.UI.Xaml.Controls.ListView()
|
||||
{
|
||||
ItemsPanel =
|
||||
(ItemsPanelTemplate)Windows.UI.Xaml.Application.Current.Resources["HorizontalListItemsPanel"]
|
||||
};
|
||||
|
||||
ScrollViewer.SetHorizontalScrollMode(horizontalListView, ScrollMode.Auto);
|
||||
ScrollViewer.SetHorizontalScrollBarVisibility(horizontalListView,
|
||||
Windows.UI.Xaml.Controls.ScrollBarVisibility.Auto);
|
||||
|
||||
return horizontalListView;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,6 +42,7 @@
|
|||
<Compile Include="AccessibilityExtensions.cs" />
|
||||
<Compile Include="CollectionView\ItemsViewRenderer.cs" />
|
||||
<Compile Include="CollectionView\SelectableItemsViewRenderer.cs" />
|
||||
<Compile Include="CollectionView\StructuredItemsViewRenderer.cs" />
|
||||
<Compile Include="ColorExtensions.cs" />
|
||||
<Compile Include="DispatcherProvider.cs" />
|
||||
<Compile Include="Extensions\ImageExtensions.cs" />
|
||||
|
|
|
@ -51,6 +51,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
}
|
||||
}
|
||||
|
||||
protected override bool IsHorizontal => (_carouselView?.ItemsLayout as ItemsLayout)?.Orientation == ItemsLayoutOrientation.Horizontal;
|
||||
|
||||
protected override string DetermineCellReuseId()
|
||||
{
|
||||
if (_carouselView.ItemTemplate != null)
|
||||
|
|
|
@ -52,8 +52,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
public override nfloat GetMinimumInteritemSpacingForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section)
|
||||
{
|
||||
if (_itemsLayout is ListItemsLayout listItemsLayout)
|
||||
return (nfloat)listItemsLayout.ItemSpacing;
|
||||
if (_itemsLayout is LinearItemsLayout linearItemsLayout)
|
||||
return (nfloat)linearItemsLayout.ItemSpacing;
|
||||
|
||||
return base.GetMinimumInteritemSpacingForSection(collectionView, layout, section);
|
||||
}
|
||||
|
|
|
@ -33,15 +33,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateIsBounceEnabled();
|
||||
}
|
||||
|
||||
protected override ItemsViewLayout SelectLayout(IItemsLayout layoutSpecification, ItemSizingStrategy itemSizingStrategy)
|
||||
protected override ItemsViewLayout SelectLayout()
|
||||
{
|
||||
if (layoutSpecification is ListItemsLayout listItemsLayout)
|
||||
{
|
||||
return new CarouselViewLayout(listItemsLayout, itemSizingStrategy, CarouselView);
|
||||
}
|
||||
|
||||
// Fall back to horizontal carousel
|
||||
return new CarouselViewLayout(new ListItemsLayout(ItemsLayoutOrientation.Horizontal), itemSizingStrategy, CarouselView);
|
||||
return new CarouselViewLayout(CarouselView.ItemsLayout, CarouselView.ItemSizingStrategy, CarouselView);
|
||||
}
|
||||
|
||||
protected override void SetUpNewElement(ItemsView newElement)
|
||||
|
|
|
@ -6,7 +6,7 @@ using Xamarin.Forms.Internals;
|
|||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
// TODO hartez 2018/06/01 14:21:24 Add a method for updating the layout
|
||||
public class ItemsViewController : UICollectionViewController
|
||||
public abstract class ItemsViewController : UICollectionViewController
|
||||
{
|
||||
public IItemsViewSource ItemsSource { get; protected set; }
|
||||
public ItemsView ItemsView { get; }
|
||||
|
@ -20,12 +20,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UIView _emptyUIView;
|
||||
VisualElement _emptyViewFormsElement;
|
||||
|
||||
UIView _headerUIView;
|
||||
VisualElement _headerViewFormsElement;
|
||||
|
||||
UIView _footerUIView;
|
||||
VisualElement _footerViewFormsElement;
|
||||
|
||||
protected UICollectionViewDelegator Delegator { get; set; }
|
||||
|
||||
public ItemsViewController(ItemsView itemsView, ItemsViewLayout layout) : base(layout)
|
||||
|
@ -68,21 +62,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
if (disposing)
|
||||
{
|
||||
if (_headerViewFormsElement != null)
|
||||
_headerViewFormsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated;
|
||||
|
||||
if (_footerViewFormsElement != null)
|
||||
_footerViewFormsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated;
|
||||
|
||||
ItemsSource?.Dispose();
|
||||
_emptyUIView?.Dispose();
|
||||
_headerUIView?.Dispose();
|
||||
_footerUIView?.Dispose();
|
||||
|
||||
_headerUIView = null;
|
||||
_headerViewFormsElement = null;
|
||||
_footerUIView = null;
|
||||
_footerViewFormsElement = null;
|
||||
_emptyUIView = null;
|
||||
_emptyViewFormsElement = null;
|
||||
}
|
||||
|
@ -150,22 +131,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size);
|
||||
_initialConstraintsSet = true;
|
||||
}
|
||||
|
||||
// This update is only relevant if you have a footer view because it's used to place the footer view
|
||||
// based on the ContentSize so we just update the positions if the ContentSize has changed
|
||||
if (_footerUIView != null)
|
||||
{
|
||||
if (IsHorizontal)
|
||||
{
|
||||
if (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width)
|
||||
UpdateHeaderFooterPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_footerUIView.Frame.Y != ItemsViewLayout.CollectionViewContentSize.Height)
|
||||
UpdateHeaderFooterPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IItemsViewSource CreateItemsViewSource()
|
||||
|
@ -276,55 +241,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
CollectionView.RegisterClassForCell(typeof(VerticalCell), VerticalCell.ReuseId);
|
||||
}
|
||||
|
||||
bool IsHorizontal => (ItemsView?.ItemsLayout as ItemsLayout)?.Orientation == ItemsLayoutOrientation.Horizontal;
|
||||
|
||||
void UpdateHeaderFooterPosition()
|
||||
{
|
||||
if (IsHorizontal)
|
||||
{
|
||||
var currentInset = CollectionView.ContentInset;
|
||||
|
||||
nfloat headerWidth = _headerUIView?.Frame.Width ?? 0f;
|
||||
nfloat footerWidth = _footerUIView?.Frame.Width ?? 0f;
|
||||
|
||||
if (_headerUIView != null && _headerUIView.Frame.X != headerWidth)
|
||||
_headerUIView.Frame = new CoreGraphics.CGRect(-headerWidth, 0, headerWidth, CollectionView.Frame.Height);
|
||||
|
||||
if (_footerUIView != null && (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width))
|
||||
_footerUIView.Frame = new CoreGraphics.CGRect(ItemsViewLayout.CollectionViewContentSize.Width, 0, footerWidth, CollectionView.Frame.Height);
|
||||
|
||||
if (CollectionView.ContentInset.Left != headerWidth || CollectionView.ContentInset.Right != footerWidth)
|
||||
{
|
||||
CollectionView.ContentInset = new UIEdgeInsets(0, headerWidth, 0, footerWidth);
|
||||
|
||||
// if the header grows it will scroll off the screen because if you change the content inset iOS adjusts the content offset so the list doesn't move
|
||||
// this changes the offset of the list by however much the header size has changed
|
||||
CollectionView.ContentOffset = new CoreGraphics.CGPoint(CollectionView.ContentOffset.X + (currentInset.Left - CollectionView.ContentInset.Left), CollectionView.ContentOffset.Y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentInset = CollectionView.ContentInset;
|
||||
|
||||
nfloat headerHeight = _headerUIView?.Frame.Height ?? 0f;
|
||||
nfloat footerHeight = _footerUIView?.Frame.Height ?? 0f;
|
||||
|
||||
if (_headerUIView != null && _headerUIView.Frame.Y != headerHeight)
|
||||
_headerUIView.Frame = new CoreGraphics.CGRect(0, -headerHeight, CollectionView.Frame.Width, headerHeight);
|
||||
|
||||
if (_footerUIView != null && (_footerUIView.Frame.Y != ItemsViewLayout.CollectionViewContentSize.Height))
|
||||
_footerUIView.Frame = new CoreGraphics.CGRect(0, ItemsViewLayout.CollectionViewContentSize.Height, CollectionView.Frame.Width, footerHeight);
|
||||
|
||||
if (CollectionView.ContentInset.Top != headerHeight || CollectionView.ContentInset.Bottom != footerHeight)
|
||||
{
|
||||
CollectionView.ContentInset = new UIEdgeInsets(headerHeight, 0, footerHeight, 0);
|
||||
|
||||
// if the header grows it will scroll off the screen because if you change the content inset iOS adjusts the content offset so the list doesn't move
|
||||
// this changes the offset of the list by however much the header size has changed
|
||||
CollectionView.ContentOffset = new CoreGraphics.CGPoint(CollectionView.ContentOffset.X, CollectionView.ContentOffset.Y + (currentInset.Top - CollectionView.ContentInset.Top));
|
||||
}
|
||||
}
|
||||
}
|
||||
protected abstract bool IsHorizontal { get; }
|
||||
|
||||
internal void UpdateEmptyView()
|
||||
{
|
||||
|
@ -334,17 +251,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateEmptyViewVisibility(ItemsSource?.ItemCount == 0);
|
||||
}
|
||||
|
||||
internal void UpdateFooterView()
|
||||
{
|
||||
UpdateSubview(ItemsView?.Footer, ItemsView?.FooterTemplate, ref _footerUIView, ref _footerViewFormsElement);
|
||||
}
|
||||
|
||||
internal void UpdateHeaderView()
|
||||
{
|
||||
UpdateSubview(ItemsView?.Header, ItemsView?.HeaderTemplate, ref _headerUIView, ref _headerViewFormsElement);
|
||||
}
|
||||
|
||||
internal void UpdateSubview(object view, DataTemplate viewTemplate, ref UIView uiView, ref VisualElement formsElement)
|
||||
protected void UpdateSubview(object view, DataTemplate viewTemplate, ref UIView uiView, ref VisualElement formsElement)
|
||||
{
|
||||
if (uiView != null)
|
||||
CollectionView.Subviews.Remove(uiView);
|
||||
|
@ -388,15 +295,19 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
}
|
||||
}
|
||||
|
||||
void OnFormsElementMeasureInvalidated(object sender, EventArgs e)
|
||||
protected void OnFormsElementMeasureInvalidated(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is VisualElement formsElement)
|
||||
{
|
||||
RemeasureLayout(formsElement);
|
||||
UpdateHeaderFooterPosition();
|
||||
HandleFormsElementMeasureInvalidated(formsElement);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void HandleFormsElementMeasureInvalidated(VisualElement formsElement)
|
||||
{
|
||||
RemeasureLayout(formsElement);
|
||||
}
|
||||
|
||||
internal void UpdateView(object view, DataTemplate viewTemplate, ref UIView uiView, ref VisualElement formsElement)
|
||||
{
|
||||
// Is view set on the ItemsView?
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
protected virtual void HandlePropertyChanged(PropertyChangedEventArgs propertyChanged)
|
||||
{
|
||||
if (propertyChanged.IsOneOf(ListItemsLayout.ItemSpacingProperty,
|
||||
if (propertyChanged.IsOneOf(LinearItemsLayout.ItemSpacingProperty,
|
||||
GridItemsLayout.HorizontalItemSpacingProperty, GridItemsLayout.VerticalItemSpacingProperty))
|
||||
{
|
||||
UpdateItemSpacing();
|
||||
|
@ -111,7 +111,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
public virtual nfloat GetMinimumLineSpacingForSection(UICollectionView collectionView,
|
||||
UICollectionViewLayout layout, nint section)
|
||||
{
|
||||
if (_itemsLayout is ListItemsLayout listViewLayout)
|
||||
if (_itemsLayout is LinearItemsLayout listViewLayout)
|
||||
{
|
||||
return (nfloat)listViewLayout.ItemSpacing;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ using UIKit;
|
|||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
public class ItemsViewRenderer : ViewRenderer<ItemsView, UIView>
|
||||
public abstract class ItemsViewRenderer : ViewRenderer<ItemsView, UIView>
|
||||
{
|
||||
ItemsViewLayout _layout;
|
||||
bool _disposed;
|
||||
|
@ -45,14 +45,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
ItemsViewController.UpdateEmptyView();
|
||||
}
|
||||
else if (changedProperty.IsOneOf(ItemsView.HeaderProperty, ItemsView.HeaderTemplateProperty))
|
||||
{
|
||||
ItemsViewController.UpdateHeaderView();
|
||||
}
|
||||
else if (changedProperty.IsOneOf(ItemsView.FooterProperty, ItemsView.FooterTemplateProperty))
|
||||
{
|
||||
ItemsViewController.UpdateFooterView();
|
||||
}
|
||||
else if (changedProperty.Is(ItemsView.ItemSizingStrategyProperty))
|
||||
{
|
||||
UpdateItemSizingStrategy();
|
||||
|
@ -71,21 +63,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
}
|
||||
}
|
||||
|
||||
protected virtual ItemsViewLayout SelectLayout(IItemsLayout layoutSpecification, ItemSizingStrategy itemSizingStrategy)
|
||||
{
|
||||
if (layoutSpecification is GridItemsLayout gridItemsLayout)
|
||||
{
|
||||
return new GridViewLayout(gridItemsLayout, itemSizingStrategy);
|
||||
}
|
||||
|
||||
if (layoutSpecification is ListItemsLayout listItemsLayout)
|
||||
{
|
||||
return new ListViewLayout(listItemsLayout, itemSizingStrategy);
|
||||
}
|
||||
|
||||
// Fall back to vertical list
|
||||
return new ListViewLayout(new ListItemsLayout(ItemsLayoutOrientation.Vertical), itemSizingStrategy);
|
||||
}
|
||||
protected abstract ItemsViewLayout SelectLayout();
|
||||
|
||||
protected virtual void TearDownOldElement(ItemsView oldElement)
|
||||
{
|
||||
|
@ -120,9 +98,6 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
SetNativeControl(ItemsViewController.View);
|
||||
ItemsViewController.CollectionView.BackgroundColor = UIColor.Clear;
|
||||
ItemsViewController.UpdateEmptyView();
|
||||
ItemsViewController.UpdateFooterView();
|
||||
ItemsViewController.UpdateHeaderView();
|
||||
|
||||
UpdateHorizontalScrollBarVisibility();
|
||||
UpdateVerticalScrollBarVisibility();
|
||||
|
||||
|
@ -132,7 +107,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
protected virtual void UpdateLayout()
|
||||
{
|
||||
_layout = SelectLayout(Element.ItemsLayout, Element.ItemSizingStrategy);
|
||||
_layout = SelectLayout();
|
||||
|
||||
if (ItemsViewController != null)
|
||||
{
|
||||
|
@ -150,10 +125,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
_layout.ItemsUpdatingScrollMode = Element.ItemsUpdatingScrollMode;
|
||||
}
|
||||
|
||||
protected virtual ItemsViewController CreateController(ItemsView newElement, ItemsViewLayout layout)
|
||||
{
|
||||
return new ItemsViewController(newElement, layout);
|
||||
}
|
||||
protected abstract ItemsViewController CreateController(ItemsView newElement, ItemsViewLayout layout);
|
||||
|
||||
NSIndexPath DetermineIndex(ScrollToRequestEventArgs args)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
internal class ListViewLayout : ItemsViewLayout
|
||||
{
|
||||
public ListViewLayout(ListItemsLayout itemsLayout, ItemSizingStrategy itemSizingStrategy) : base(itemsLayout, itemSizingStrategy)
|
||||
public ListViewLayout(LinearItemsLayout itemsLayout, ItemSizingStrategy itemSizingStrategy) : base(itemsLayout, itemSizingStrategy)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ using UIKit;
|
|||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
public class SelectableItemsViewController : ItemsViewController
|
||||
public class SelectableItemsViewController : StructuredItemsViewController
|
||||
{
|
||||
SelectableItemsView SelectableItemsView => (SelectableItemsView)ItemsView;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.ComponentModel;
|
|||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
public class SelectableItemsViewRenderer : ItemsViewRenderer
|
||||
public class SelectableItemsViewRenderer : StructuredItemsViewRenderer
|
||||
{
|
||||
SelectableItemsView SelectableItemsView => (SelectableItemsView)Element;
|
||||
SelectableItemsViewController SelectableItemsViewController => (SelectableItemsViewController)ItemsViewController;
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
public class StructuredItemsViewController : ItemsViewController
|
||||
{
|
||||
bool _disposed;
|
||||
|
||||
StructuredItemsView StructuredItemsView => (StructuredItemsView)ItemsView;
|
||||
|
||||
UIView _headerUIView;
|
||||
VisualElement _headerViewFormsElement;
|
||||
|
||||
UIView _footerUIView;
|
||||
VisualElement _footerViewFormsElement;
|
||||
|
||||
public StructuredItemsViewController(StructuredItemsView structuredItemsView, ItemsViewLayout layout)
|
||||
: base(structuredItemsView, layout)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (_headerViewFormsElement != null)
|
||||
_headerViewFormsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated;
|
||||
|
||||
if (_footerViewFormsElement != null)
|
||||
_footerViewFormsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated;
|
||||
|
||||
_headerUIView = null;
|
||||
_headerViewFormsElement = null;
|
||||
_footerUIView = null;
|
||||
_footerViewFormsElement = null;
|
||||
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override bool IsHorizontal => (StructuredItemsView?.ItemsLayout as ItemsLayout)?.Orientation == ItemsLayoutOrientation.Horizontal;
|
||||
|
||||
public override void ViewWillLayoutSubviews()
|
||||
{
|
||||
base.ViewWillLayoutSubviews();
|
||||
|
||||
// This update is only relevant if you have a footer view because it's used to place the footer view
|
||||
// based on the ContentSize so we just update the positions if the ContentSize has changed
|
||||
if (_footerUIView != null)
|
||||
{
|
||||
if (IsHorizontal)
|
||||
{
|
||||
if (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width)
|
||||
UpdateHeaderFooterPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_footerUIView.Frame.Y != ItemsViewLayout.CollectionViewContentSize.Height)
|
||||
UpdateHeaderFooterPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateFooterView()
|
||||
{
|
||||
UpdateSubview(StructuredItemsView?.Footer, StructuredItemsView?.FooterTemplate,
|
||||
ref _footerUIView, ref _footerViewFormsElement);
|
||||
}
|
||||
|
||||
internal void UpdateHeaderView()
|
||||
{
|
||||
UpdateSubview(StructuredItemsView?.Header, StructuredItemsView?.HeaderTemplate,
|
||||
ref _headerUIView, ref _headerViewFormsElement);
|
||||
}
|
||||
|
||||
void UpdateHeaderFooterPosition()
|
||||
{
|
||||
if (IsHorizontal)
|
||||
{
|
||||
var currentInset = CollectionView.ContentInset;
|
||||
|
||||
nfloat headerWidth = _headerUIView?.Frame.Width ?? 0f;
|
||||
nfloat footerWidth = _footerUIView?.Frame.Width ?? 0f;
|
||||
|
||||
if (_headerUIView != null && _headerUIView.Frame.X != headerWidth)
|
||||
_headerUIView.Frame = new CoreGraphics.CGRect(-headerWidth, 0, headerWidth, CollectionView.Frame.Height);
|
||||
|
||||
if (_footerUIView != null && (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width))
|
||||
_footerUIView.Frame = new CoreGraphics.CGRect(ItemsViewLayout.CollectionViewContentSize.Width, 0, footerWidth, CollectionView.Frame.Height);
|
||||
|
||||
if (CollectionView.ContentInset.Left != headerWidth || CollectionView.ContentInset.Right != footerWidth)
|
||||
{
|
||||
CollectionView.ContentInset = new UIEdgeInsets(0, headerWidth, 0, footerWidth);
|
||||
|
||||
// if the header grows it will scroll off the screen because if you change the content inset iOS adjusts the content offset so the list doesn't move
|
||||
// this changes the offset of the list by however much the header size has changed
|
||||
CollectionView.ContentOffset = new CoreGraphics.CGPoint(CollectionView.ContentOffset.X + (currentInset.Left - CollectionView.ContentInset.Left), CollectionView.ContentOffset.Y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentInset = CollectionView.ContentInset;
|
||||
|
||||
nfloat headerHeight = _headerUIView?.Frame.Height ?? 0f;
|
||||
nfloat footerHeight = _footerUIView?.Frame.Height ?? 0f;
|
||||
|
||||
if (_headerUIView != null && _headerUIView.Frame.Y != headerHeight)
|
||||
_headerUIView.Frame = new CoreGraphics.CGRect(0, -headerHeight, CollectionView.Frame.Width, headerHeight);
|
||||
|
||||
if (_footerUIView != null && (_footerUIView.Frame.Y != ItemsViewLayout.CollectionViewContentSize.Height))
|
||||
_footerUIView.Frame = new CoreGraphics.CGRect(0, ItemsViewLayout.CollectionViewContentSize.Height, CollectionView.Frame.Width, footerHeight);
|
||||
|
||||
if (CollectionView.ContentInset.Top != headerHeight || CollectionView.ContentInset.Bottom != footerHeight)
|
||||
{
|
||||
CollectionView.ContentInset = new UIEdgeInsets(headerHeight, 0, footerHeight, 0);
|
||||
|
||||
// if the header grows it will scroll off the screen because if you change the content inset iOS adjusts the content offset so the list doesn't move
|
||||
// this changes the offset of the list by however much the header size has changed
|
||||
CollectionView.ContentOffset = new CoreGraphics.CGPoint(CollectionView.ContentOffset.X, CollectionView.ContentOffset.Y + (currentInset.Top - CollectionView.ContentInset.Top));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void HandleFormsElementMeasureInvalidated(VisualElement formsElement)
|
||||
{
|
||||
base.HandleFormsElementMeasureInvalidated(formsElement);
|
||||
UpdateHeaderFooterPosition();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
public class StructuredItemsViewRenderer : ItemsViewRenderer
|
||||
{
|
||||
StructuredItemsView StructuredItemsView => (StructuredItemsView)Element;
|
||||
StructuredItemsViewController StructuredItemsViewController => (StructuredItemsViewController)ItemsViewController;
|
||||
|
||||
protected override ItemsViewController CreateController(ItemsView itemsView, ItemsViewLayout layout)
|
||||
{
|
||||
return new StructuredItemsViewController(itemsView as StructuredItemsView, layout);
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs changedProperty)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, changedProperty);
|
||||
|
||||
if (changedProperty.IsOneOf(StructuredItemsView.HeaderProperty, StructuredItemsView.HeaderTemplateProperty))
|
||||
{
|
||||
StructuredItemsViewController.UpdateHeaderView();
|
||||
}
|
||||
else if (changedProperty.IsOneOf(StructuredItemsView.FooterProperty, StructuredItemsView.FooterTemplateProperty))
|
||||
{
|
||||
StructuredItemsViewController.UpdateFooterView();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetUpNewElement(ItemsView newElement)
|
||||
{
|
||||
base.SetUpNewElement(newElement);
|
||||
|
||||
if (newElement == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StructuredItemsViewController.UpdateFooterView();
|
||||
StructuredItemsViewController.UpdateHeaderView();
|
||||
}
|
||||
|
||||
protected override ItemsViewLayout SelectLayout()
|
||||
{
|
||||
var itemSizingStrategy = StructuredItemsView.ItemSizingStrategy;
|
||||
var layoutSpecification = StructuredItemsView.ItemsLayout;
|
||||
|
||||
if (layoutSpecification is GridItemsLayout gridItemsLayout)
|
||||
{
|
||||
return new GridViewLayout(gridItemsLayout, itemSizingStrategy);
|
||||
}
|
||||
|
||||
if (layoutSpecification is LinearItemsLayout listItemsLayout)
|
||||
{
|
||||
return new ListViewLayout(listItemsLayout, itemSizingStrategy);
|
||||
}
|
||||
|
||||
// Fall back to vertical list
|
||||
return new ListViewLayout(new LinearItemsLayout(ItemsLayoutOrientation.Vertical), itemSizingStrategy);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -128,6 +128,8 @@
|
|||
<Compile Include="CollectionView\TemplateHelpers.cs" />
|
||||
<Compile Include="CollectionView\UICollectionViewDelegator.cs" />
|
||||
<Compile Include="CollectionView\VerticalCell.cs" />
|
||||
<Compile Include="CollectionView\StructuredItemsViewController.cs" />
|
||||
<Compile Include="CollectionView\StructuredItemsViewRenderer.cs" />
|
||||
<Compile Include="CollectionView\VerticalDefaultCell.cs" />
|
||||
<Compile Include="CollectionView\GridViewLayout.cs" />
|
||||
<Compile Include="CollectionView\ItemsViewLayout.cs" />
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
x:Name="self">
|
||||
<CollectionView ItemsSource="{Binding Items}" x:Name="collectionview">
|
||||
<CollectionView.ItemsLayout>
|
||||
<ListItemsLayout ItemSpacing="4">
|
||||
<LinearItemsLayout ItemSpacing="4">
|
||||
<x:Arguments>
|
||||
<ItemsLayoutOrientation>Vertical</ItemsLayoutOrientation>
|
||||
</x:Arguments>
|
||||
</ListItemsLayout>
|
||||
</LinearItemsLayout>
|
||||
</CollectionView.ItemsLayout>
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
|
|
Загрузка…
Ссылка в новой задаче