[Tizen] Changed CarouselView scroll logic according to the Core change. (#10235)
* [Tizen] Invoke ItemsView Scrolled event * [Tizen] Changed CarouselView scroll logic * [Tizen] Add IndicatorView
This commit is contained in:
Родитель
c8b99fb391
Коммит
ed2ad60b25
|
@ -124,9 +124,7 @@ namespace Xamarin.Forms.Platform
|
|||
internal class _CheckBoxRenderer { }
|
||||
#endif
|
||||
|
||||
#if !TIZEN4_0
|
||||
[RenderWith(typeof(IndicatorViewRenderer))]
|
||||
#endif
|
||||
internal class _IndicatorViewRenderer { }
|
||||
|
||||
#if __IOS__
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Xamarin.Forms.ControlGallery.Tizen
|
|||
{
|
||||
var app = new MainApplication();
|
||||
FormsMaps.Init("HERE", "write-your-API-key-here");
|
||||
Forms.SetFlags("CollectionView_Experimental", "Shell_Experimental", "MediaElement_Experimental");
|
||||
Forms.SetFlags("CollectionView_Experimental", "Shell_Experimental", "MediaElement_Experimental", "IndicatorView_Experimental");
|
||||
Forms.Init(app);
|
||||
FormsMaterial.Init();
|
||||
app.Run(args);
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace Xamarin.Forms.Platform.Tizen.Native
|
|||
SnapPointsType _snapPoints;
|
||||
ESize _itemSize = new ESize(-1, -1);
|
||||
|
||||
public event EventHandler<ItemsViewScrolledEventArgs> Scrolled;
|
||||
|
||||
public CollectionView(EvasObject parent) : base(parent)
|
||||
{
|
||||
SetLayoutCallback(OnLayout);
|
||||
|
@ -522,9 +524,24 @@ namespace Xamarin.Forms.Platform.Tizen.Native
|
|||
_innerLayout.MinimumHeight = size.Height;
|
||||
}
|
||||
|
||||
int _previousHorizontalOffset = 0;
|
||||
int _previousVerticalOffset = 0;
|
||||
void OnScrolled(object sender, EventArgs e)
|
||||
{
|
||||
_layoutManager.LayoutItems(Scroller.CurrentRegion);
|
||||
_layoutManager.LayoutItems(ViewPort);
|
||||
var args = new ItemsViewScrolledEventArgs();
|
||||
args.FirstVisibleItemIndex = _layoutManager.GetVisibleItemIndex(ViewPort.X, ViewPort.Y);
|
||||
args.CenterItemIndex = _layoutManager.GetVisibleItemIndex(ViewPort.X + (ViewPort.Width / 2), ViewPort.Y + (ViewPort.Height / 2));
|
||||
args.LastVisibleItemIndex = _layoutManager.GetVisibleItemIndex(ViewPort.X + ViewPort.Width, ViewPort.Y + ViewPort.Height);
|
||||
args.HorizontalOffset = ViewPort.X;
|
||||
args.HorizontalDelta = ViewPort.X - _previousHorizontalOffset;
|
||||
args.VerticalOffset = ViewPort.Y;
|
||||
args.VerticalDelta = ViewPort.Y - _previousVerticalOffset;
|
||||
|
||||
Scrolled?.Invoke(this, args);
|
||||
|
||||
_previousHorizontalOffset = ViewPort.X;
|
||||
_previousVerticalOffset = ViewPort.Y;
|
||||
}
|
||||
|
||||
void UpdateSnapPointsType(SnapPointsType snapPoints)
|
||||
|
|
|
@ -338,6 +338,29 @@ namespace Xamarin.Forms.Platform.Tizen.Native
|
|||
}
|
||||
}
|
||||
|
||||
public int GetVisibleItemIndex(int x, int y)
|
||||
{
|
||||
int index = 0;
|
||||
if (x < 0 || y < 0)
|
||||
return index;
|
||||
if (_scrollCanvasSize.Width < x || _scrollCanvasSize.Height < y)
|
||||
return CollectionView.Count - 1;
|
||||
|
||||
int first = (IsHorizontal ? x : y) / BaseItemSize;
|
||||
if (_hasUnevenRows)
|
||||
first = _accumulatedItemSizes.FindIndex(current => (IsHorizontal ? x : y) <= current);
|
||||
|
||||
int second = (IsHorizontal ? y : x) / ColumnSize;
|
||||
if (second == Span)
|
||||
second -= 1;
|
||||
|
||||
index = (first * Span) + second;
|
||||
|
||||
if (index < CollectionView.Count)
|
||||
return index;
|
||||
return CollectionView.Count - 1;
|
||||
}
|
||||
|
||||
void InitializeMeasureCache()
|
||||
{
|
||||
_baseItemSize = 0;
|
||||
|
|
|
@ -28,5 +28,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native
|
|||
void Reset();
|
||||
|
||||
void ItemMeasureInvalidated(int index);
|
||||
|
||||
int GetVisibleItemIndex(int x, int y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ElmSharp;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Tizen.Native
|
||||
{
|
||||
public class IndicatorView : Index
|
||||
{
|
||||
List<IndexItem> _list = new List<IndexItem>();
|
||||
|
||||
public IndicatorView(EvasObject parent) : base(parent)
|
||||
{
|
||||
AutoHide = false;
|
||||
IsHorizontal = true;
|
||||
Style = "pagecontrol";
|
||||
if (Device.Idiom == TargetIdiom.Watch)
|
||||
Style = "circle";
|
||||
}
|
||||
|
||||
public event EventHandler<SelectedPositionChangedEventArgs> SelectedPosition;
|
||||
|
||||
public void UpdateSelectedIndex(int index)
|
||||
{
|
||||
if (index > -1 && index < _list.Count)
|
||||
{
|
||||
_list[index].Select(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void AppendIndex(int count = 1)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var item = Append(null);
|
||||
item.Selected += OnSelected;
|
||||
_list.Add(item);
|
||||
}
|
||||
if (Device.Idiom == TargetIdiom.Watch)
|
||||
ApplyStyle();
|
||||
}
|
||||
|
||||
public void ClearIndex()
|
||||
{
|
||||
foreach (var item in _list)
|
||||
{
|
||||
item.Selected -= OnSelected;
|
||||
}
|
||||
_list.Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
void ApplyStyle()
|
||||
{
|
||||
foreach (var item in _list)
|
||||
{
|
||||
int center = 10;
|
||||
int start = center - (_list.Count / 2);
|
||||
int index = _list.IndexOf(item);
|
||||
int position = start + index;
|
||||
if (_list.Count % 2 == 0)
|
||||
{
|
||||
string itemStyle = "item/even_" + position;
|
||||
item.Style = itemStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
string itemStyle = "item/odd_" + position;
|
||||
item.Style = itemStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnSelected(object sender, EventArgs e)
|
||||
{
|
||||
var index = _list.IndexOf((IndexItem)sender);
|
||||
SelectedPosition?.Invoke(this, new SelectedPositionChangedEventArgs(index));
|
||||
UpdateSelectedIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -296,6 +296,22 @@ namespace Xamarin.Forms.Platform.Tizen.Native
|
|||
}
|
||||
}
|
||||
|
||||
public int GetVisibleItemIndex(int x, int y)
|
||||
{
|
||||
int coordinate = IsHorizontal ? x : y;
|
||||
int canvasSize = IsHorizontal ? _scrollCanvasSize.Width : _scrollCanvasSize.Height;
|
||||
|
||||
if (coordinate < 0)
|
||||
return 0;
|
||||
if (canvasSize < coordinate)
|
||||
return CollectionView.Count - 1;
|
||||
|
||||
if (!_hasUnevenRows)
|
||||
return coordinate / BaseItemSize;
|
||||
else
|
||||
return _accumulatedItemSizes.FindIndex(current => coordinate <= current);
|
||||
}
|
||||
|
||||
void InitializeMeasureCache()
|
||||
{
|
||||
_baseItemSize = 0;
|
||||
|
|
|
@ -30,6 +30,7 @@ using Xamarin.Forms.Platform.Tizen;
|
|||
[assembly: ExportRenderer(typeof(ListView), typeof(ListViewRenderer))]
|
||||
[assembly: ExportRenderer(typeof(BoxView), typeof(BoxViewRenderer))]
|
||||
[assembly: ExportRenderer(typeof(ActivityIndicator), typeof(ActivityIndicatorRenderer))]
|
||||
[assembly: ExportRenderer(typeof(IndicatorView), typeof(IndicatorViewRenderer))]
|
||||
[assembly: ExportRenderer(typeof(SearchBar), typeof(SearchBarRenderer))]
|
||||
[assembly: ExportRenderer(typeof(Entry), typeof(EntryRenderer))]
|
||||
[assembly: ExportRenderer(typeof(Editor), typeof(EditorRenderer))]
|
||||
|
@ -42,6 +43,7 @@ using Xamarin.Forms.Platform.Tizen;
|
|||
[assembly: ExportRenderer(typeof(SwipeView), typeof(SwipeViewRenderer))]
|
||||
[assembly: ExportRenderer(typeof(RefreshView), typeof(RefreshViewRenderer))]
|
||||
[assembly: ExportRenderer(typeof(MediaElement), typeof(MediaElementRenderer))]
|
||||
[assembly: ExportRenderer(typeof(IndicatorView), typeof(IndicatorViewRenderer))]
|
||||
|
||||
[assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImageSourceHandler))]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace Xamarin.Forms.Platform.Tizen
|
||||
using System;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Tizen
|
||||
{
|
||||
public class CarouselViewRenderer : ItemsViewRenderer<CarouselView, Native.CarouselView>
|
||||
{
|
||||
|
@ -7,7 +9,8 @@
|
|||
RegisterPropertyHandler(CarouselView.ItemsLayoutProperty, UpdateItemsLayout);
|
||||
RegisterPropertyHandler(CarouselView.IsBounceEnabledProperty, UpdateIsBounceEnabled);
|
||||
RegisterPropertyHandler(CarouselView.IsSwipeEnabledProperty, UpdateIsSwipeEnabled);
|
||||
RegisterPropertyHandler(CarouselView.PositionProperty, UpdatePosition);
|
||||
RegisterPropertyHandler(CarouselView.PositionProperty, UpdatePositionFromElement);
|
||||
RegisterPropertyHandler(CarouselView.CurrentItemProperty, UpdateCurrentItemFromElement);
|
||||
}
|
||||
|
||||
protected override Native.CarouselView CreateNativeControl(ElmSharp.EvasObject parent)
|
||||
|
@ -20,17 +23,23 @@
|
|||
return Element.ItemsLayout;
|
||||
}
|
||||
|
||||
ElmSharp.SmartEvent _animationStart;
|
||||
ElmSharp.SmartEvent _animationStop;
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<CarouselView> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
Control.Scroll.Scrolled += OnScrollStart;
|
||||
Control.Scroll.PageScrolled += OnScrollStop;
|
||||
}
|
||||
|
||||
protected override void OnItemSelectedFromUI(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
Element.Position = e.SelectedItemIndex;
|
||||
Element.CurrentItem = e.SelectedItem;
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
Control.Scrolled += OnScrolled;
|
||||
Control.Scroll.DragStart += OnDragStart;
|
||||
Control.Scroll.DragStop += OnDragStop;
|
||||
_animationStart = new ElmSharp.SmartEvent(Control.Scroll, Control.Scroll.RealHandle, "scroll,anim,start");
|
||||
_animationStart.On += OnScrollStart;
|
||||
_animationStop = new ElmSharp.SmartEvent(Control.Scroll, Control.Scroll.RealHandle, "scroll,anim,stop");
|
||||
_animationStop.On += OnScrollStop;
|
||||
}
|
||||
UpdatePositionFromElement(false);
|
||||
UpdateCurrentItemFromElement(false);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
@ -39,39 +48,79 @@
|
|||
{
|
||||
if (Element != null)
|
||||
{
|
||||
Control.Scroll.Scrolled -= OnScrollStart;
|
||||
Control.Scroll.PageScrolled -= OnScrollStop;
|
||||
Control.Scrolled -= OnScrolled;
|
||||
Control.Scroll.DragStart -= OnDragStart;
|
||||
Control.Scroll.DragStop -= OnDragStop;
|
||||
_animationStart.On -= OnScrollStart;
|
||||
_animationStop.On -= OnScrollStop;
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
void OnDragStart(object sender, System.EventArgs e)
|
||||
{
|
||||
Element.SetIsDragging(true);
|
||||
Element.IsScrolling = true;
|
||||
}
|
||||
|
||||
void OnDragStop(object sender, System.EventArgs e)
|
||||
{
|
||||
Element.SetIsDragging(false);
|
||||
Element.IsScrolling = false;
|
||||
}
|
||||
|
||||
void OnScrollStart(object sender, System.EventArgs e)
|
||||
{
|
||||
if (!Element.IsDragging)
|
||||
{
|
||||
Element.SetIsDragging(true);
|
||||
}
|
||||
Element.IsScrolling = true;
|
||||
}
|
||||
|
||||
void OnScrollStop(object sender, System.EventArgs e)
|
||||
{
|
||||
if (Element.IsDragging)
|
||||
{
|
||||
Element.SetIsDragging(false);
|
||||
}
|
||||
var scrollerIndex = Control.LayoutManager.IsHorizontal ? Control.Scroll.HorizontalPageIndex : Control.Scroll.VerticalPageIndex;
|
||||
Element.SetValueFromRenderer(CarouselView.PositionProperty, scrollerIndex);
|
||||
Element.SetValueFromRenderer(CarouselView.CurrentItemProperty, Control.Adaptor[scrollerIndex]);
|
||||
Control.Adaptor.RequestItemSelected(Control.Adaptor[scrollerIndex]);
|
||||
Element.IsScrolling = false;
|
||||
}
|
||||
|
||||
void UpdatePosition(bool initialize)
|
||||
void OnScrolled(object sender, ItemsViewScrolledEventArgs e)
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
if (!Element.IsScrolling)
|
||||
Element.IsScrolling = true;
|
||||
|
||||
if (Element.IsDragging)
|
||||
if (Element.Position != e.CenterItemIndex)
|
||||
Element.SetValueFromRenderer(CarouselView.PositionProperty, e.CenterItemIndex);
|
||||
}
|
||||
|
||||
void UpdateCurrentItemFromElement(bool isInitializing)
|
||||
{
|
||||
if (isInitializing)
|
||||
return;
|
||||
}
|
||||
if (Element.Position > -1 && Element.Position < Control.Adaptor.Count)
|
||||
|
||||
if (Element.CurrentItem != null)
|
||||
ScrollTo(Control.Adaptor.GetItemIndex(Element.CurrentItem));
|
||||
}
|
||||
|
||||
void UpdatePositionFromElement(bool isInitializing)
|
||||
{
|
||||
if (isInitializing)
|
||||
return;
|
||||
|
||||
ScrollTo(Element.Position);
|
||||
}
|
||||
|
||||
void ScrollTo(int position)
|
||||
{
|
||||
if (Element.IsScrolling)
|
||||
return;
|
||||
|
||||
if (position > -1 && position < Control.Adaptor.Count)
|
||||
{
|
||||
Control.Adaptor.RequestItemSelected(Element.Position);
|
||||
Element.CurrentItem = Control.Adaptor[Element.Position];
|
||||
var scrollerIndex = Control.LayoutManager.IsHorizontal ? Control.Scroll.HorizontalPageIndex : Control.Scroll.VerticalPageIndex;
|
||||
if (position != scrollerIndex)
|
||||
Control.ScrollTo(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
using System.Collections;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Tizen
|
||||
{
|
||||
public class IndicatorViewRenderer : ViewRenderer<IndicatorView, Native.IndicatorView>
|
||||
{
|
||||
public IndicatorViewRenderer()
|
||||
{
|
||||
RegisterPropertyHandler(IndicatorView.CountProperty, UpdateItemsSource);
|
||||
RegisterPropertyHandler(IndicatorView.PositionProperty, UpdatePosition);
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<IndicatorView> e)
|
||||
{
|
||||
if (Control == null)
|
||||
{
|
||||
SetNativeControl(new Native.IndicatorView(Forms.NativeParent));
|
||||
}
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
Control.SelectedPosition += OnSelectedPosition;
|
||||
}
|
||||
if (e.OldElement != null)
|
||||
{
|
||||
Control.SelectedPosition -= OnSelectedPosition;
|
||||
}
|
||||
base.OnElementChanged(e);
|
||||
}
|
||||
|
||||
void OnSelectedPosition(object sender, SelectedPositionChangedEventArgs e)
|
||||
{
|
||||
Element.SetValueFromRenderer(IndicatorView.PositionProperty, (int)e.SelectedPosition);
|
||||
}
|
||||
|
||||
void UpdateItemsSource()
|
||||
{
|
||||
Control.ClearIndex();
|
||||
int count = 0;
|
||||
if (Element.ItemsSource is ICollection collection)
|
||||
{
|
||||
count = collection.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
var enumerator = Element.ItemsSource.GetEnumerator();
|
||||
while (enumerator?.MoveNext() ?? false)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Control.AppendIndex(count);
|
||||
}
|
||||
|
||||
void UpdatePosition()
|
||||
{
|
||||
Control.UpdateSelectedIndex(Element.Position);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Specialized;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
|
||||
using Xamarin.Forms.Platform.Tizen.Native;
|
||||
|
@ -26,6 +27,7 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
if (Control == null)
|
||||
{
|
||||
SetNativeControl(CreateNativeControl(Forms.NativeParent));
|
||||
Control.Scrolled += OnScrolled;
|
||||
}
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
|
@ -44,6 +46,7 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
{
|
||||
Element.ScrollToRequested -= OnScrollToRequest;
|
||||
ItemsLayout.PropertyChanged -= OnLayoutPropertyChanged;
|
||||
Control.Scrolled -= OnScrolled;
|
||||
}
|
||||
if (_observableSource != null)
|
||||
{
|
||||
|
@ -93,6 +96,11 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
{
|
||||
}
|
||||
|
||||
void OnScrolled(object sender, ItemsViewScrolledEventArgs e)
|
||||
{
|
||||
Element.SendScrolled(e);
|
||||
}
|
||||
|
||||
void OnScrollToRequest(object sender, ScrollToRequestEventArgs e)
|
||||
{
|
||||
if (e.Mode == ScrollToMode.Position)
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
Registered.Register(typeof(SwipeView), () => new SwipeViewRenderer());
|
||||
Registered.Register(typeof(RefreshView), () => new RefreshViewRenderer());
|
||||
Registered.Register(typeof(MediaElement), () => new MediaElementRenderer());
|
||||
Registered.Register(typeof(IndicatorView), () => new IndicatorViewRenderer());
|
||||
|
||||
//ImageSourceHandlers
|
||||
Registered.Register(typeof(FileImageSource), () => new FileImageSourceHandler());
|
||||
|
|
Загрузка…
Ссылка в новой задаче