Add Scrollbar Visibility option to the CollectionView (#6602)
authorRavinder Jangra <ravinderjangra@live.com>
Thu, 11 Jul 2019 23:03:12 +0000 (04:33 +0530)
committerSamantha Houts <samhouts@users.noreply.github.com>
Thu, 11 Jul 2019 23:03:12 +0000 (16:03 -0700)
* Add Horizontal and Vertical Scrollbar Visibility option to the CollectionView

* bump gitinfo

* make requested changes

* Add Android implementation

* use ScrollBarVisibility.Default instead of 0 and other requested changes
fixes #6053

GitInfo.txt
Xamarin.Forms.Core/Items/ItemsView.cs
Xamarin.Forms.Platform.Android/CollectionView/ItemsViewRenderer.cs
Xamarin.Forms.Platform.Android/Resources/values/styles.xml [new file with mode: 0644]
Xamarin.Forms.Platform.Android/Xamarin.Forms.Platform.Android.csproj
Xamarin.Forms.Platform.UAP/CollectionView/ItemsViewRenderer.cs
Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewRenderer.cs

index 6aba2b2..8089590 100644 (file)
@@ -1 +1 @@
-4.2.0
+4.3.0
index c89dbbc..6a508d7 100644 (file)
@@ -44,6 +44,31 @@ namespace Xamarin.Forms
                        set => SetValue(ItemsSourceProperty, value);
                }
 
+               public static readonly BindableProperty HorizontalScrollBarVisibilityProperty = BindableProperty.Create(
+                       nameof(HorizontalScrollBarVisibility),
+                       typeof(ScrollBarVisibility),
+                       typeof(ItemsView),
+                       ScrollBarVisibility.Default);
+
+               public ScrollBarVisibility HorizontalScrollBarVisibility
+               {
+                       get => (ScrollBarVisibility)GetValue(HorizontalScrollBarVisibilityProperty);
+                       set => SetValue(HorizontalScrollBarVisibilityProperty, value);
+               }
+
+
+               public static readonly BindableProperty VerticalScrollBarVisibilityProperty = BindableProperty.Create(
+                       nameof(VerticalScrollBarVisibility),
+                       typeof(ScrollBarVisibility),
+                       typeof(ItemsView),
+                       ScrollBarVisibility.Default);
+
+               public ScrollBarVisibility VerticalScrollBarVisibility
+               {
+                       get => (ScrollBarVisibility)GetValue(VerticalScrollBarVisibilityProperty);
+                       set => SetValue(VerticalScrollBarVisibilityProperty, value);
+               }
+
                public void AddLogicalChild(Element element)
                {
                        _logicalChildren.Add(element);
index 4840a11..437aeee 100644 (file)
@@ -33,14 +33,20 @@ namespace Xamarin.Forms.Platform.Android
                DataChangeObserver _dataChangeViewObserver;
                bool _watchingForEmpty;
 
+               ScrollBarVisibility _defaultHorizontalScrollVisibility = ScrollBarVisibility.Default;
+               ScrollBarVisibility _defaultVerticalScrollVisibility = ScrollBarVisibility.Default;
+
                RecyclerView.ItemDecoration _itemDecoration;
 
-               public ItemsViewRenderer(Context context) : base(context)
+               public ItemsViewRenderer(Context context) : base(new ContextThemeWrapper(context, Resource.Style.collectionViewStyle))
                {
                        CollectionView.VerifyCollectionViewFlagEnabled(nameof(ItemsViewRenderer));
 
                        _automationPropertiesProvider = new AutomationPropertiesProvider(this);
                        _effectControlProvider = new EffectControlProvider(this);
+
+                       VerticalScrollBarEnabled = false;
+                       HorizontalScrollBarEnabled = false;
                }
 
                ScrollHelper ScrollHelper => _scrollHelper ?? (_scrollHelper = new ScrollHelper(this));
@@ -210,6 +216,14 @@ namespace Xamarin.Forms.Platform.Android
                        {
                                UpdateAdapter();
                        }
+                       else if(changedProperty.Is(ItemsView.HorizontalScrollBarVisibilityProperty))
+                       {
+                               UpdateHorizontalScrollBarVisibility();
+                       }
+                       else if (changedProperty.Is(ItemsView.VerticalScrollBarVisibilityProperty))
+                       {
+                               UpdateVerticalScrollBarVisibility();
+                       }
                }
 
                protected virtual void UpdateItemsSource()
@@ -296,6 +310,9 @@ namespace Xamarin.Forms.Platform.Android
                        UpdateFlowDirection();
                        UpdateItemSpacing();
 
+                       UpdateHorizontalScrollBarVisibility();
+                       UpdateVerticalScrollBarVisibility();
+
                        // Keep track of the ItemsLayout's property changes
                        if (_layout != null)
                        {
@@ -306,6 +323,33 @@ namespace Xamarin.Forms.Platform.Android
                        ItemsView.ScrollToRequested += ScrollToRequested;
                }
 
+               void UpdateVerticalScrollBarVisibility()
+               {
+                       if (_defaultVerticalScrollVisibility == ScrollBarVisibility.Default)
+                               _defaultVerticalScrollVisibility = VerticalScrollBarEnabled ? ScrollBarVisibility.Always : ScrollBarVisibility.Never;
+
+                       var newVerticalScrollVisibility = ItemsView.VerticalScrollBarVisibility;
+
+                       if (newVerticalScrollVisibility == ScrollBarVisibility.Default)
+                               newVerticalScrollVisibility = _defaultVerticalScrollVisibility;
+
+                       VerticalScrollBarEnabled = newVerticalScrollVisibility == ScrollBarVisibility.Always;
+               }
+
+               void UpdateHorizontalScrollBarVisibility()
+               {
+                       if (_defaultHorizontalScrollVisibility == ScrollBarVisibility.Default)
+                               _defaultHorizontalScrollVisibility =
+                                       HorizontalScrollBarEnabled ? ScrollBarVisibility.Always : ScrollBarVisibility.Never;
+
+                       var newHorizontalScrollVisiblility = ItemsView.HorizontalScrollBarVisibility;
+
+                       if (newHorizontalScrollVisiblility == ScrollBarVisibility.Default)
+                               newHorizontalScrollVisiblility = _defaultHorizontalScrollVisibility;
+
+                       HorizontalScrollBarEnabled = newHorizontalScrollVisiblility == ScrollBarVisibility.Always;
+               }
+
                protected virtual void TearDownOldElement(ItemsView oldElement)
                {
                        if (oldElement == null)
diff --git a/Xamarin.Forms.Platform.Android/Resources/values/styles.xml b/Xamarin.Forms.Platform.Android/Resources/values/styles.xml
new file mode 100644 (file)
index 0000000..d18d4b4
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+               xmlns:app="http://schemas.android.com/apk/res-auto">
+  <style name="collectionViewStyle" android:id="@+id/collectionViewStyle">
+    <item name="android:scrollbars">vertical|horizontal</item>
+  </style>
+</resources>
index d395346..990eeb9 100644 (file)
       <Properties>CreateAllAndroidTargets=false;Configuration=$(Configuration);Platform=$(Platform);AndroidTargetFrameworkVersion=v8.1</Properties>
     </ProjectToBuild>
   </ItemGroup>
+  <ItemGroup>
+    <AndroidResource Include="Resources\values\styles.xml" />
+  </ItemGroup>
   <Target Name="BeforeBuild" Condition=" '$(CreateAllAndroidTargets)' == 'true' ">
     <!--  create 8.1 binaries-->
     <MSBuild Targets="Restore" Projects="@(ProjectToBuild)">
index 0fe4c31..45fb00d 100644 (file)
@@ -11,6 +11,7 @@ using Windows.UI.Xaml.Controls.Primitives;
 using Windows.UI.Xaml.Data;
 using Xamarin.Forms.Internals;
 using Xamarin.Forms.Platform.UAP;
+using UwpScrollBarVisibility = Windows.UI.Xaml.Controls.ScrollBarVisibility;
 
 namespace Xamarin.Forms.Platform.UWP
 {
@@ -20,6 +21,10 @@ namespace Xamarin.Forms.Platform.UWP
                CollectionViewSource _collectionViewSource;
 
                protected ListViewBase ListViewBase { get; private set; }
+               UwpScrollBarVisibility? _defaultHorizontalScrollVisibility;
+               UwpScrollBarVisibility? _defaultVerticalScrollVisibility;
+
+               protected ItemsControl ItemsControl { get; private set; }
 
                protected override void OnElementChanged(ElementChangedEventArgs<CollectionView> args)
                {
@@ -40,6 +45,14 @@ namespace Xamarin.Forms.Platform.UWP
                        {
                                UpdateItemTemplate();
                        }
+                       else if(changedProperty.Is(ItemsView.HorizontalScrollBarVisibilityProperty))
+                       {
+                               UpdateHorizontalScrollBarVisibility();
+                       }
+                       else if (changedProperty.Is(ItemsView.VerticalScrollBarVisibilityProperty))
+                       {
+                               UpdateVerticalScrollBarVisibility();
+                       }
                }
 
                protected virtual ListViewBase SelectLayout(IItemsLayout layoutSpecification)
@@ -200,6 +213,8 @@ namespace Xamarin.Forms.Platform.UWP
 
                        UpdateItemTemplate();
                        UpdateItemsSource();
+                       UpdateVerticalScrollBarVisibility();
+                       UpdateHorizontalScrollBarVisibility();
 
                        // Listen for ScrollTo requests
                        newElement.ScrollToRequested += ScrollToRequested;
@@ -354,6 +369,44 @@ namespace Xamarin.Forms.Platform.UWP
                        //}
                }
 
+               void UpdateVerticalScrollBarVisibility()
+               {
+                       if (_defaultVerticalScrollVisibility == null)
+                               _defaultVerticalScrollVisibility = ScrollViewer.GetVerticalScrollBarVisibility(Control);
+
+                       switch (Element.VerticalScrollBarVisibility)
+                       {
+                               case (ScrollBarVisibility.Always):
+                                       ScrollViewer.SetVerticalScrollBarVisibility(Control, UwpScrollBarVisibility.Visible);
+                                       break;
+                               case (ScrollBarVisibility.Never):
+                                       ScrollViewer.SetVerticalScrollBarVisibility(Control, UwpScrollBarVisibility.Hidden);
+                                       break;
+                               case (ScrollBarVisibility.Default):
+                                       ScrollViewer.SetVerticalScrollBarVisibility(Control, _defaultVerticalScrollVisibility.Value);
+                                       break;
+                       }
+               }
+
+               void UpdateHorizontalScrollBarVisibility()
+               {
+                       if (_defaultHorizontalScrollVisibility == null)
+                               _defaultHorizontalScrollVisibility = ScrollViewer.GetHorizontalScrollBarVisibility(Control);
+
+                       switch (Element.HorizontalScrollBarVisibility)
+                       {
+                               case (ScrollBarVisibility.Always):
+                                       ScrollViewer.SetHorizontalScrollBarVisibility(Control, UwpScrollBarVisibility.Visible);
+                                       break;
+                               case (ScrollBarVisibility.Never):
+                                       ScrollViewer.SetHorizontalScrollBarVisibility(Control, UwpScrollBarVisibility.Hidden);
+                                       break;
+                               case (ScrollBarVisibility.Default):
+                                       ScrollViewer.SetHorizontalScrollBarVisibility(Control, _defaultHorizontalScrollVisibility.Value);
+                                       break;
+                       }
+               }
+
                protected virtual async Task ScrollTo(ScrollToRequestEventArgs args)
                {
                        if (!(Control is ListViewBase list))
index 8edb121..f010f87 100644 (file)
@@ -8,6 +8,8 @@ namespace Xamarin.Forms.Platform.iOS
        {
                ItemsViewLayout _layout;
                bool _disposed;
+               bool? _defaultHorizontalScrollVisibility;
+               bool? _defaultVerticalScrollVisibility;
 
                public ItemsViewRenderer()
                {
@@ -47,6 +49,14 @@ namespace Xamarin.Forms.Platform.iOS
                        {
                                UpdateItemSizingStrategy();
                        }
+                       else if (changedProperty.Is(ItemsView.HorizontalScrollBarVisibilityProperty))
+                       {
+                               UpdateHorizontalScrollBarVisibility();
+                       }
+                       else if (changedProperty.Is(ItemsView.VerticalScrollBarVisibilityProperty))
+                       {
+                               UpdateVerticalScrollBarVisibility();
+                       }
                }
 
                protected virtual ItemsViewLayout SelectLayout(IItemsLayout layoutSpecification)
@@ -99,6 +109,9 @@ namespace Xamarin.Forms.Platform.iOS
                        ItemsViewController.CollectionView.BackgroundColor = UIColor.Clear;
                        ItemsViewController.UpdateEmptyView();
 
+                       UpdateHorizontalScrollBarVisibility();
+                       UpdateVerticalScrollBarVisibility();
+
                        // Listen for ScrollTo requests
                        newElement.ScrollToRequested += ScrollToRequested;
                }
@@ -146,6 +159,44 @@ namespace Xamarin.Forms.Platform.iOS
                        return ItemsViewController.GetIndexForItem(args.Item);
                }
 
+               void UpdateVerticalScrollBarVisibility()
+               {
+                       if (_defaultVerticalScrollVisibility == null)
+                               _defaultVerticalScrollVisibility = ItemsViewController.CollectionView.ShowsHorizontalScrollIndicator;
+
+                       switch (Element.VerticalScrollBarVisibility)
+                       {
+                               case (ScrollBarVisibility.Always):
+                                       ItemsViewController.CollectionView.ShowsVerticalScrollIndicator = true;
+                                       break;
+                               case (ScrollBarVisibility.Never):
+                                       ItemsViewController.CollectionView.ShowsVerticalScrollIndicator = false;
+                                       break;
+                               case (ScrollBarVisibility.Default):
+                                       ItemsViewController.CollectionView.ShowsVerticalScrollIndicator = _defaultVerticalScrollVisibility.Value;
+                                       break;
+                       }
+               }
+
+               void UpdateHorizontalScrollBarVisibility()
+               {
+                       if (_defaultHorizontalScrollVisibility == null)
+                               _defaultHorizontalScrollVisibility = ItemsViewController.CollectionView.ShowsHorizontalScrollIndicator;
+
+                       switch (Element.HorizontalScrollBarVisibility)
+                       {
+                               case (ScrollBarVisibility.Always):
+                                       ItemsViewController.CollectionView.ShowsHorizontalScrollIndicator = true;
+                                       break;
+                               case (ScrollBarVisibility.Never):
+                                       ItemsViewController.CollectionView.ShowsHorizontalScrollIndicator = false;
+                                       break;
+                               case (ScrollBarVisibility.Default):
+                                       ItemsViewController.CollectionView.ShowsHorizontalScrollIndicator = _defaultHorizontalScrollVisibility.Value;
+                                       break;
+                       }
+               }
+
                void ScrollToRequested(object sender, ScrollToRequestEventArgs args)
                {
                        var indexPath = DetermineIndex(args);