From ef02a0739637369a877262bc28778618d88e88bc Mon Sep 17 00:00:00 2001 From: Seungkeun Lee Date: Mon, 26 Jun 2017 14:25:55 +0900 Subject: Enable scrolling in TabbedPageRenderer TASK=TCAPI-2487, TNET-1176 - Fix layout issue with scroller Change-Id: I9c17eb5edf2133c474a3767dcabcf2da71bff124 --- .../Renderers/TabbedPageRenderer.cs | 149 +++++++++++++-------- 1 file changed, 95 insertions(+), 54 deletions(-) mode change 100755 => 100644 Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs (limited to 'Xamarin.Forms.Platform.Tizen') diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs old mode 100755 new mode 100644 index d2661197..683f3232 --- a/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs @@ -6,14 +6,16 @@ using EToolbarItem = ElmSharp.ToolbarItem; using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; using EColor = ElmSharp.Color; using Xamarin.Forms.PlatformConfiguration.TizenSpecific; +using Xamarin.Forms.Internals; namespace Xamarin.Forms.Platform.Tizen { public class TabbedPageRenderer : VisualElementRenderer, IVisualElementRenderer { - Box _box; + Box _outterLayout; + Box _innerBox; + Scroller _scroller; Toolbar _toolbar; - EvasObject _content; Dictionary _itemToItemPage = new Dictionary(); public TabbedPageRenderer() @@ -22,7 +24,6 @@ namespace Xamarin.Forms.Platform.Tizen RegisterPropertyHandler(TabbedPage.TitleProperty, UpdateTitle); //Register for current page change property RegisterPropertyHandler("CurrentPage", CurrentPageChanged); - //TODO renderer should add item on EFL toolbar when new Page is added to TabbedPage RegisterPropertyHandler(TabbedPage.BarBackgroundColorProperty, UpdateBarBackgroundColor); } @@ -31,7 +32,7 @@ namespace Xamarin.Forms.Platform.Tizen if (_toolbar == null) { //Create box that holds toolbar and selected content - _box = new Box(Forms.Context.MainWindow) + _outterLayout = new Box(Forms.Context.MainWindow) { AlignmentX = -1, AlignmentY = -1, @@ -39,9 +40,9 @@ namespace Xamarin.Forms.Platform.Tizen WeightY = 1, IsHorizontal = false, }; - _box.Show(); + _outterLayout.Show(); - //Create toolbar that is placed inside the _box + //Create toolbar that is placed inside the _outterLayout _toolbar = new Toolbar(Forms.Context.MainWindow) { AlignmentX = -1, @@ -51,21 +52,50 @@ namespace Xamarin.Forms.Platform.Tizen if (Device.Idiom == TargetIdiom.Phone) { - //Set ShrinkMode to Expand as default only for Mobile profile + //Set ShrinkMode to Expand as defauly only for Mobile profile _toolbar.ShrinkMode = ToolbarShrinkMode.Expand; } else if (Device.Idiom == TargetIdiom.TV) { - //According to TV UX Guideleine, toolbar style should be set to "tabbar_with_title" in case of TabbedPage + //According to TV UX Guideline, toolbar style should be set to "tabbar_with_title" in case of TabbedPage only for TV profile. _toolbar.Style = "tabbar_with_title"; } _toolbar.Show(); - //Add callback for item selection - _toolbar.Selected += OnCurrentPageChanged; - _box.PackEnd(_toolbar); + //Add callback for Toolbar item selection + _toolbar.Selected += OnToolbarItemSelected; + _outterLayout.PackEnd(_toolbar); - SetNativeControl(_box); + _scroller = new Scroller(_outterLayout) + { + AlignmentX = -1, + AlignmentY = -1, + WeightX = 1, + WeightY = 1, + HorizontalPageScrollLimit = 1, + ScrollBlock = ScrollBlock.Vertical, + HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible + }; + _scroller.SetPageSize(1.0, 1.0); + _scroller.PageScrolled += OnItemPageScrolled; + + _innerBox = new Box(Forms.Context.MainWindow) + { + AlignmentX = -1, + AlignmentY = -1, + WeightX = 1, + WeightY = 1, + IsHorizontal = true, + }; + + _innerBox.SetLayoutCallback(OnInnerLayoutUpdate); + + _scroller.SetContent(_innerBox); + _scroller.Show(); + + _outterLayout.PackEnd(_scroller); + + SetNativeControl(_outterLayout); UpdateTitle(); } @@ -74,14 +104,15 @@ namespace Xamarin.Forms.Platform.Tizen protected override void Dispose(bool disposing) { - if (_box != null) + if (_outterLayout != null) { - _box.Unrealize(); - _box = null; + _outterLayout.Unrealize(); + _outterLayout = null; } if (_toolbar != null) { - _toolbar.Selected -= OnCurrentPageChanged; + _toolbar.Selected -= OnToolbarItemSelected; + _scroller.PageScrolled -= OnItemPageScrolled; _toolbar.Unrealize(); _toolbar = null; @@ -91,7 +122,7 @@ namespace Xamarin.Forms.Platform.Tizen protected override void OnElementReady() { - FillToolbar(); + FillToolbarAndContents(); base.OnElementReady(); } @@ -105,6 +136,36 @@ namespace Xamarin.Forms.Platform.Tizen } } + void OnInnerLayoutUpdate() + { + int baseX = _innerBox.Geometry.X; + Rect bound = _scroller.Geometry; + int index = 0; + foreach (var page in Element.Children) + { + var nativeView = Platform.GetRenderer(page).NativeView; + bound.X = baseX + index * bound.Width; + nativeView.Geometry = bound; + index++; + } + _innerBox.MinimumWidth = Element.Children.Count * bound.Width; + int currentPage = MultiPage.GetIndex(_itemToItemPage[_toolbar.SelectedItem]); + _scroller.ScrollTo(currentPage, 0, true); + } + + void OnItemPageScrolled(object sender, System.EventArgs e) + { + Page newPage = Element.GetPageByIndex(_scroller.HorizontalPageIndex); + foreach (var pair in _itemToItemPage) + { + if (pair.Value == newPage) + { + pair.Key.IsSelected = true; + return; + } + } + } + void UpdateBarBackgroundColor() { EColor bgColor = Element.BarBackgroundColor.ToNative(); @@ -144,73 +205,53 @@ namespace Xamarin.Forms.Platform.Tizen } } - void FillToolbar() + void FillToolbarAndContents() { - var logicalChildren = (Element as IElementController).LogicalChildren; - //add items to toolbar - foreach (Page child in logicalChildren) + foreach (Page child in Element.Children) { - var childRenderer = Platform.GetRenderer(child); - if (childRenderer != null) - { - childRenderer.NativeView.Hide(); - } - EToolbarItem toolbarItem = _toolbar.Append(child.Title, string.IsNullOrEmpty(child.Icon) ? null : ResourcePath.GetPath(child.Icon)); if (Element.BarBackgroundColor != Color.Default) { toolbarItem.SetPartColor("bg", _toolbar.BackgroundColor); } _itemToItemPage.Add(toolbarItem, child); + + var childContent = Platform.GetOrCreateRenderer(child).NativeView; + _innerBox.PackEnd(childContent); + if (Element.CurrentPage == child) { //select item on the toolbar and fill content toolbarItem.IsSelected = true; - CreateNewPage(); } child.PropertyChanged += OnPageTitleChanged; } } - void OnCurrentPageChanged(object sender, EToolbarItemEventArgs e) + void OnToolbarItemSelected(object sender, EToolbarItemEventArgs e) { if (_toolbar.SelectedItem == null) return; - var selectedContent = Platform.GetRenderer(_itemToItemPage[e.Item]).NativeView; + var oldPage = Element.CurrentPage; + var newPage = _itemToItemPage[_toolbar.SelectedItem]; - if (selectedContent == _content) + if (oldPage == newPage) return; - //detach content from view without EvasObject changes - if (_content != null) - { - //hide content that should not be visible - _content.Hide(); - //unpack content that is hiden an prepare for new content - _box.UnPack(_content); - Element.CurrentPage?.SendDisappearing(); - } - Element.CurrentPage = _itemToItemPage[_toolbar.SelectedItem]; - CreateNewPage(); - } + oldPage?.SendDisappearing(); - void CreateNewPage() - { - //create EvasObject using renderer and remember to not destroy - //it for better performance (create once) - _content = Platform.GetOrCreateRenderer(Element.CurrentPage).NativeView; - _content.SetAlignment(-1, -1); - _content.SetWeight(1, 1); - _content.Show(); - _box.PackEnd(_content); - Element.CurrentPage?.SendAppearing(); + Element.CurrentPage = newPage; + newPage?.SendAppearing(); + + int index = MultiPage.GetIndex(newPage); + _scroller.ScrollTo(index, 0, true); } void CurrentPageChanged() { - foreach (KeyValuePair pair in _itemToItemPage) + foreach (var pair in _itemToItemPage) { if (pair.Value == Element.CurrentPage) { -- cgit v1.2.3