Alright now when it comes to the default Xamarin Forms ScrollView, its pretty much generic and limited with the simple common attributes and behaviours, and it does not deliver any specific “cool” features with it.
What’s so cool about it?
So I thought of creating my own Custom ScrollView for Xamarin Forms using Custom Renderers, which would include the following awesome features,
Bouncy Effect – Yeah you gotta admit, the bounce effect of a native scrollview is pretty fun to play with, in a User’s perspective. So I thought of enabling this feature in my custom ScrollView even when the Child Element doesn’t exceeds the ScrollView boundaries… 😉
(PS: this effect is interpreted in native Android and iOS differently)
Disabling and Enabling Horizontal and Vertical Scroll Indicators – Now sometimes these scroll bar indicators are useful but there are times which we want to hide them, as it might look ugly on the UI in certain cases. So yeah let’s have some control over it shall we? 😀
Background Image – Of course who wouldn’t like a background Image on a Scroll view eh! 😉 Well to be specific we are going to add a Fixed Background Image for the ScrollView. And note that this background Image would be fixed, and will not be scrolling with the Content of the ScrollView. (I will do another post to enable that feature).
Yes behold, me, myself and I presenting the “BloopyScrollView” why the name “BloopyScrollView”? I don’t even know. lol 😛
Alright let’s go ahead and create our Custom ScrollView Control in the PCL project. Along with the following properties, so that we could have direct control over the above said behaviours.
Alright now expect this to be longer, since I have added the properties as Bindable Properties, so you could use them in any MVVM scenario with ease. 😀
There we go IsHorizontalScrollbarEnabled, IsVerticalScrollbarEnabled to disable/enable Horizonal and Vertical Scrollbars.
IsNativeBouncyEffectEnabled to control the Native Bouncy effect.
BackgroundImage to set the ImageSource for the ScrollView’s background Image. And make sure to provide a proper image for this hence we will be resizing the given image in our native renderer level to fit to the background of the ScrollView.(You will see in the next steps below)
Alright let’s head over to creating the Custom Renderers associated with our BloopyScrollView.
Something to keep in mind…
So if you’re a frequent reader of my blog, you may remember sometime ago I created an Extention class for handling Xamarin Forms Images in Native code level: https://theconfuzedsourcecode.wordpress.com/2016/12/12/an-awesome-image-helper-to-convert-xamarin-forms-imagesource-to-ios-uiimage-or-android-bitmap/
Why I’m bringing this up, is because we are going to be needing it for this project. You ask why? Because we need to convert the above BackgroundImage, which is of type Xamarin Forms ImageSource.
So we need to convert that ImageSource to native UIImage or Bitmap image respectively in our Custom renderer levels. 😉
So go ahead and grab that code real quick and add it to your Native Projects. 😀
Now let’s create the Custom Renderer for the Control in Xamarin.iOS project.
Inside the method we are assigning the relevant properties of our BloopyScrollView to the native control properties.
The UIScrollView which is associated with the Xamarin Forms ScrollView has the following native properties:
- ShowsVerticalScrollIndicator: Make the vertical scrollbar visible or hidden
- ShowsHorizontalScrollIndicator: Make the horizontal scrollbar visible or hidden
- Bounces: Always enable the native bounce effect on iOS UIScrollView
- BackgroundColor: Allows to set the background color for the UIScrollView or set an Image as a pattern
Also you may have noted that we are converting our Image Source BackgroundImage to a UIImage using our extension.
And then when the Height and Width are set to the Control, we are resizing the Image to fit those properties and setting that as the Background of the UIScrollView through the UIColor.FromPatternImage() which allows us to set the image as a pattern throughout the canvas of the UIScrollView.
the strange tale of getting the UIScrollView’s Fixed background in Xamarin… :O
Notice that we are overriding the Draw(CGRect rect) method, this is to have the UIScroll Background Image to be fixed within the boundaries, and not to be spanned across the Content area.
Because usually if we set the BackgroundColor property, it will span across the Content area, but strangely if we override the Draw() method, BackgroundColor would only be contained within UIScrollView’s boundaries, without spanning across the Content area. This is something I figured out while playing around with the above implementation. 😀
Alright let’s jump into Android… 😀
Now let’s create the Custom Renderer for the Control in Xamarin.Android project.
The Android ScrollView which is associated with the Xamarin Forms ScrollView has the following native properties:
- VerticalScrollBarEnabled: Make the vertical scrollbar visible or hidden
- HorizontalScrollBarEnabled: Make the horizontal scrollbar visible or hidden
- OverScrollMode: Always enable the native bounce effect on Android ScrollView
- Background: Allows to set the background drawable for the ScrollView
As you may have noticed we are converting our Xamarin Forms Image Source BackgroundImage to a Bitmap image using our extension.
Then we are resizing out Bitmap image according to the Width and Height of the ScrollView to fit to the full background to be wrapped around a BitmapDrawable and set to the Background of ScrollView.
There you go! 😀
Let’s use it… 😉
Alright now that’s done, let’s consume this in our PCL project.
As you can see I have inserted my BloopyScrollView in a StackLayout and as the content of the ScrollView I have added Label. Well you can add any content you want or set any Height or Width as you wish.
Notice that I have set IsNativeBouncyEffectEnabled to be True as I want to see the native Bouncy effect. Then I have disabled the Vertical and Horizontal Scrollbars from the properties we added earlier. Then finally I have added the BackgroundImage and set the FileImageSource to the ImageSource type, where as I have placed the image in the native Resource folder, as you would do with any defualt Xamarin Forms Image. 😉
Now let’s see the results… 😀
As we expected the Vertical and Horizontal Scrollbars are disabled and our ScrollView has full native bouncy effect accordingly.
Also you can see the Background Image nicely resized itself and fit to the background of the BloopyScrollView. 😀
Happy dance! lol
Now there’s some stuff I wanted to recap, that is you may have noticed that when I was resizing the Image, I needed the Control’s Height and Width, and where I have acquired those properties are in two different places on each Android and iOS renderers.
To be specific I have accessed the Control’s Width and Height on Android right from the OnElementChanged method, but on iOS renderer I have accessed those values from the OnPropertyChanged method’s Height property event.
This is because of the differences of the Rendering cycling of Android and iOS, whereas on Android right at the firing of the Custom Renderer it assigns itself Width and Height. But on iOS we have to access them indirectly by waiting till those properties are set, by listening to the OnPropertyChanged event.
Get it on Github! 😀 XFImprovedScrollView
Pass this on to another developer to make them smile! 😀
– Udara Alwis