First pass at tab view

This commit is contained in:
watsonb8 2019-12-22 17:10:06 -05:00
parent 7560e122f8
commit 945b7e8e11

View File

@ -1,4 +1,4 @@
using CarouselView.FormsPlugin.Abstractions;
// using CarouselView.FormsPlugin.Abstractions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@ -10,7 +10,7 @@ using Aurora.Design.Converters;
namespace Aurora.Design.Components.TabView
{
public delegate void PositionChangingEventHandler(object sender, PositionChangingEventArgs e);
public delegate void PositionChangedEventHandler(object sender, PositionChangedEventArgs e);
public delegate void PositionChangedEventHandler(object sender, TabChangedEventArgs e);
public class PositionChangingEventArgs : EventArgs
{
@ -19,7 +19,7 @@ namespace Aurora.Design.Components.TabView
public int OldPosition { get; set; }
}
public class PositionChangedEventArgs : EventArgs
public class TabChangedEventArgs : EventArgs
{
public int NewPosition { get; set; }
public int OldPosition { get; set; }
@ -36,19 +36,21 @@ namespace Aurora.Design.Components.TabView
{
private StackLayout _mainContainerSL;
private Grid _headerContainerGrid;
private CarouselViewControl _carouselView;
// private CarouselViewControl _carouselView;
private ScrollView _tabHeadersContainerSv;
private ContentPresenter _tabPresenter;
public event PositionChangingEventHandler PositionChanging;
public event PositionChangedEventHandler PositionChanged;
protected virtual void OnPositionChanging(ref PositionChangingEventArgs e)
protected virtual void OnTabChanging(ref PositionChangingEventArgs e)
{
PositionChangingEventHandler handler = PositionChanging;
handler?.Invoke(this, e);
}
protected virtual void OnPositionChanged(PositionChangedEventArgs e)
protected virtual void OnTabChanged(TabChangedEventArgs e)
{
PositionChangedEventHandler handler = PositionChanged;
handler?.Invoke(this, e);
@ -108,33 +110,39 @@ namespace Aurora.Design.Components.TabView
}
private bool _supressCarouselViewPositionChangedEvent;
private void _carouselView_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(_carouselView.Position) && !_supressCarouselViewPositionChangedEvent)
{
var positionChangingArgs = new PositionChangingEventArgs()
{
Canceled = false,
NewPosition = _carouselView.Position,
OldPosition = SelectedTabIndex
};
OnPositionChanging(ref positionChangingArgs);
/// <summary>
/// Allows for intercepting carousel property changing
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
// private void _carouselView_PropertyChanged(object sender, PropertyChangedEventArgs e)
// {
// if (e.PropertyName == nameof(_carouselView.Position) && !_supressCarouselViewPositionChangedEvent)
// {
// var positionChangingArgs = new PositionChangingEventArgs()
// {
// Canceled = false,
// NewPosition = _carouselView.Position,
// OldPosition = SelectedTabIndex
// };
if (positionChangingArgs != null && positionChangingArgs.Canceled)
{
_supressCarouselViewPositionChangedEvent = true;
_carouselView.PositionSelected -= _carouselView_PositionSelected;
_carouselView.PropertyChanged -= _carouselView_PropertyChanged;
_carouselView.Position = SelectedTabIndex;
_carouselView.PositionSelected += _carouselView_PositionSelected;
_carouselView.PropertyChanged += _carouselView_PropertyChanged;
_supressCarouselViewPositionChangedEvent = false;
}
// OnPositionChanging(ref positionChangingArgs);
SetPosition(positionChangingArgs.NewPosition);
}
}
// if (positionChangingArgs != null && positionChangingArgs.Canceled)
// {
// _supressCarouselViewPositionChangedEvent = true;
// _carouselView.PositionSelected -= _carouselView_PositionSelected;
// _carouselView.PropertyChanged -= _carouselView_PropertyChanged;
// _carouselView.Position = SelectedTabIndex;
// _carouselView.PositionSelected += _carouselView_PositionSelected;
// _carouselView.PropertyChanged += _carouselView_PropertyChanged;
// _supressCarouselViewPositionChangedEvent = false;
// }
// SetPosition(positionChangingArgs.NewPosition);
// }
// }
private void Init()
{
@ -158,30 +166,32 @@ namespace Aurora.Design.Components.TabView
HorizontalOptions = LayoutOptions.FillAndExpand
};
_carouselView = new CarouselViewControl
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
HeightRequest = ContentHeight,
ShowArrows = false,
ShowIndicators = false,
BindingContext = this
};
_tabPresenter = new ContentPresenter();
// _carouselView = new CarouselViewControl
// {
// HorizontalOptions = LayoutOptions.FillAndExpand,
// VerticalOptions = LayoutOptions.FillAndExpand,
// HeightRequest = ContentHeight,
// ShowArrows = false,
// ShowIndicators = false,
// BindingContext = this
// };
_carouselView.PropertyChanged += _carouselView_PropertyChanged;
_carouselView.PositionSelected += _carouselView_PositionSelected;
// _carouselView.PropertyChanged += _carouselView_PropertyChanged;
// _carouselView.PositionSelected += _carouselView_PositionSelected;
_mainContainerSL = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { _tabHeadersContainerSv, _carouselView },
Children = { _tabHeadersContainerSv, _tabPresenter },
// Children = { _tabHeadersContainerSv, _carouselView }, //Need to set new child in place of carousel
Spacing = 0
};
Content = _mainContainerSL;
ItemSource.CollectionChanged += ItemSource_CollectionChanged;
SetPosition(SelectedTabIndex, true);
SetCurrentTab(SelectedTabIndex, true);
}
protected override void OnBindingContextChanged()
@ -199,13 +209,13 @@ namespace Aurora.Design.Components.TabView
}
}
private void _carouselView_PositionSelected(object sender, PositionSelectedEventArgs e)
{
if (_carouselView.Position != e.NewValue || SelectedTabIndex != e.NewValue)
{
SetPosition(e.NewValue);
}
}
// private void _carouselView_PositionSelected(object sender, PositionSelectedEventArgs e)
// {
// if (_carouselView.Position != e.NewValue || SelectedTabIndex != e.NewValue)
// {
// SetPosition(e.NewValue);
// }
// }
private void AddTabToView(TabItem tab)
{
@ -266,7 +276,7 @@ namespace Aurora.Design.Components.TabView
{
if (e.PropertyName == nameof(TabItem.IsCurrent))
{
SetPosition(ItemSource.IndexOf((TabItem)((BoxView)sender).BindingContext));
SetCurrentTab(ItemSource.IndexOf((TabItem)((BoxView)sender).BindingContext));
}
if (e.PropertyName == nameof(WidthRequest))
{
@ -282,33 +292,21 @@ namespace Aurora.Design.Components.TabView
Spacing = 0
};
var tapRecognizer = new TapGestureRecognizer();
//Appears to set the current view
tapRecognizer.Tapped += (object s, EventArgs e) =>
{
_supressCarouselViewPositionChangedEvent = true;
// _supressCarouselViewPositionChangedEvent = true;
var capturedIndex = _headerContainerGrid.Children.IndexOf((View)s);
SetPosition(capturedIndex);
_supressCarouselViewPositionChangedEvent = false;
SetCurrentTab(capturedIndex);
// _supressCarouselViewPositionChangedEvent = false;
};
headerItemSL.GestureRecognizers.Add(tapRecognizer);
_headerContainerGrid.Children.Add(headerItemSL, _headerContainerGrid.ColumnDefinitions.Count - 1, 0);
_carouselView.ItemsSource = ItemSource.Select(t => t.Content);
}
#region IsSwipingEnabled
public bool IsSwipingEnabled
{
get { return (bool)GetValue(IsSwipingEnabledProperty); }
set { SetValue(IsSwipingEnabledProperty, value); }
//Sets caourselview itemssource to current tab
// _carouselView.ItemsSource = ItemSource.Select(t => t.Content);
}
private static void IsSwipingEnabledChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is TabViewControl tabViewControl)
{
tabViewControl._carouselView.IsSwipeEnabled = (bool)newValue;
}
}
public static readonly BindableProperty IsSwipingEnabledProperty = BindableProperty.Create(nameof(IsSwipingEnabled), typeof(bool), typeof(TabViewControl), true, BindingMode.Default, null, IsSwipingEnabledChanged);
#endregion
#region HeaderBackgroundColor
public Color HeaderBackgroundColor
@ -354,10 +352,11 @@ namespace Aurora.Design.Components.TabView
}
private static void ContentHeightChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is TabViewControl tabViewControl && tabViewControl._carouselView != null)
{
tabViewControl._carouselView.HeightRequest = (double)newValue;
}
throw new NotImplementedException();
// if (bindable is TabViewControl tabViewControl && tabViewControl._carouselView != null)
// {
// tabViewControl._carouselView.HeightRequest = (double)newValue;
// }
}
public static readonly BindableProperty ContentHeightProperty = BindableProperty.Create(nameof(ContentHeight), typeof(double), typeof(TabViewControl), (double)200, BindingMode.Default, null, ContentHeightChanged);
#endregion
@ -510,10 +509,9 @@ namespace Aurora.Design.Components.TabView
public static readonly BindableProperty SelectedTabIndexProperty = BindableProperty.Create(nameof(SelectedTabIndex), typeof(int), typeof(TabViewControl), 0, propertyChanged: OnSelectedTabIndexChanged);
private static void OnSelectedTabIndexChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null &&
tabViewControl._carouselView.Position != (int)newValue)
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
{
tabViewControl.SetPosition((int)newValue);
tabViewControl.SetCurrentTab((int)newValue);
}
}
public int SelectedTabIndex
@ -523,7 +521,7 @@ namespace Aurora.Design.Components.TabView
}
#endregion
public void SetPosition(int position, bool initialRun = false)
public void SetCurrentTab(int position, bool initialRun = false)
{
if (SelectedTabIndex == position && !initialRun)
{
@ -537,60 +535,76 @@ namespace Aurora.Design.Components.TabView
NewPosition = position,
OldPosition = oldPosition
};
OnPositionChanging(ref positionChangingArgs);
OnTabChanging(ref positionChangingArgs);
if (positionChangingArgs != null && positionChangingArgs.Canceled)
{
return;
}
if ((position >= 0 && position < ItemSource.Count) || initialRun)
if (((position >= 0 && position < ItemSource.Count) || initialRun) &&
oldPosition != position)
{
if (_carouselView.Position != position || initialRun)
if (oldPosition < ItemSource.Count)
{
_carouselView.PositionSelected -= _carouselView_PositionSelected;
_carouselView.Position = position;
_carouselView.PositionSelected += _carouselView_PositionSelected;
ItemSource[oldPosition].IsCurrent = false;
}
if (oldPosition != position)
{
if (oldPosition < ItemSource.Count)
{
ItemSource[oldPosition].IsCurrent = false;
}
ItemSource[position].IsCurrent = true;
SelectedTabIndex = position;
_tabPresenter.Content = ItemSource[position].Content;
ItemSource[position].IsCurrent = true;
SelectedTabIndex = position;
Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
}
}
var positionChangedArgs = new PositionChangedEventArgs()
//Need to change to not use carouselView
// if ((position >= 0 && position < ItemSource.Count) || initialRun)
// {
// if (_carouselView.Position != position || initialRun)
// {
// _carouselView.PositionSelected -= _carouselView_PositionSelected;
// _carouselView.Position = position;
// _carouselView.PositionSelected += _carouselView_PositionSelected;
// }
// if (oldPosition != position)
// {
// if (oldPosition < ItemSource.Count)
// {
// ItemSource[oldPosition].IsCurrent = false;
// }
// ItemSource[position].IsCurrent = true;
// SelectedTabIndex = position;
// Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
// }
// }
var tabChangedArgs = new TabChangedEventArgs()
{
NewPosition = SelectedTabIndex,
OldPosition = oldPosition
};
OnPositionChanged(positionChangedArgs);
OnTabChanged(tabChangedArgs);
}
public void SelectNext()
{
SetPosition(SelectedTabIndex + 1);
SetCurrentTab(SelectedTabIndex + 1);
}
public void SelectPrevious()
{
SetPosition(SelectedTabIndex - 1);
SetCurrentTab(SelectedTabIndex - 1);
}
public void SelectFirst()
{
SetPosition(0);
SetCurrentTab(0);
}
public void SelectLast()
{
SetPosition(ItemSource.Count - 1);
SetCurrentTab(ItemSource.Count - 1);
}
public void AddTab(TabItem tab, int position = -1, bool selectNewPosition = false)
@ -623,7 +637,7 @@ namespace Aurora.Design.Components.TabView
_headerContainerGrid.Children.RemoveAt(_headerContainerGrid.Children.Count - 1);
_headerContainerGrid.ColumnDefinitions.Remove(_headerContainerGrid.ColumnDefinitions.Last());
}
_carouselView.ItemsSource = ItemSource.Select(t => t.Content);
// _carouselView.ItemsSource = ItemSource.Select(t => t.Content);
SelectedTabIndex = position >= 0 && position < ItemSource.Count ? position : ItemSource.Count - 1;
}
}