TabView is a very popular view in mobile development, in xamarin forms there is no tabview implementation, side note This is why i love xamarin forms, you are given the flint and asked to build the fire, it sounds stressful right?, but in my opinion, this is an asset...this is what sets us apart...they give you power over the abstraction, and over the native implementation.
Back to the topic, recently i was building an app, and part of the UI was a tabview, where some other static views were to be placed above the view, automatically i knew the default tab page in forms would not work...after some googling i found this TabView looking into it, i found it uses an implementation of a carousel plugin in the tabview, while this is ok, i just needed something light, with no dependency.
So, After some brainstorming i thought, a tabview is really a single view with extended contents that scrolls right?, then what is the best way to have extended views..in applications?...then boom!! like a ray of light ScrollView came to the rescue.
The theory is simple
- Get a horizontal scrollview with disabled scroll
- Have views with 100% screen width
- Programatically scroll the views(tabs) to move between tabs
So
Step 1 I created a TabScrollView, with a property to disable scroll
Step 2 Created renderers for android and ios to handle this natively, since there was no option to disable scroll by default. On ios there is a property to disable scroll, on android, its a bit tricky, we need to capture scroll events and not handle it
Step 3 Created a TabItem, a normal ContentView with a HeaderText
property
Step 4 On the TabView the trick is simple have a collection of tabitem, create views for the HeaderText with indicators..then add the TabItem content into the body of the tabview, and set the width to its parent's width.
In forms, there is no way to get the parents width on initialisation, the layouts have to do their measurements first and the widths come later...so at initialisation i just assigned a constant width...for the previewer basically.
Then i had to override this method to set the widths later
protected override void LayoutChildren(double x, double y, double width, double height)
{
this.width = width;
base.LayoutChildren(x, y, width, height);
foreach (var item in body.Children)
{
item.WidthRequest = width;
}
InvalidateMeasure();
}
So widths are now 100% of their parent.
The last piece of the puzzle was how to programatically scroll the tabs, the scrollview has a method to scroll views by either the X/Y coordinates, in our case, since the Body Views have equal widths, their X coordinates are in a multiple of the widths, so first view would be 0 , second view width, third view width*2 etc
so it was as easy as having the index of the tab u want to see and multiplying by the width
await scroll.ScrollToAsync(width * SelectedIndex, 0, true);
Yea, so basically that is it, this method is great, you can put whatever you want in the tab body...even scrollviews, would work perfectly, zero dependency, you can put views ontop or below the tabview...basically it is a normal view as any other.
You can see the full Source code Here
In conclusion, Scrollviews are like duct tape, you can use it for many things, even carousels, horizontal listviews etc
PS this is my first time writing my developer experience, forgive me if my article is weird
Top comments (1)
Weird is good :)