Introduction

Xamarin is a development platform, which allows us to code native, cross-platform iOS, Android and Windows phone apps in C#.

UI Designers

The tools which we use to create mobile user interfaces are called the designers. These generate Extensible Markup Language (XML) files in their respective proprietary file formats. Two designers are available from Xamarin: Xamarin Designer for Android, Xamarin Designer for iOS. With the availability of these designers, the need for the original, native XML editors has diminished. Anything you might need to build Android or iOS UI's can be found in Xamarin’s tools. However, iOS developers still frequently use the Xcode Interface Builder and Android developers (less frequently) use XML editors such as the Android Development Tools (ADT) plug-in for Eclipse. An XML layout is an XML layout and the tool is largely a matter of taste and personal preference and even the decision to use a designer tool lies on him. Some Xamarin developers are opting to code UIs by hand in C# for all the platforms with no designer use whatsoever. I recommend the designers to help them to learn the file formats, UI elements and their properties. Some people use a designer tool like training wheels, until they’re ready to ride freestyle.

Requirements

  • Visual Studio RC 2017
  • Xamarin Studio Packages should be installed
  • Self confidence with creativity

Steps should be followed

Please follow my steps to create sliding Tab layout interface to use this tutorial effectively.

Step 1

Launch Visual Studio RC 2017 and go to file new project.

Step 2

There is a need to select Android template from the list, name the Application, press to create the Project and select where to save the project.

Step 3

Here, we go to our new project has been created and then we need to navigate to Designer Page. To open the Designer page, you need to open Solution Explorer ViewàSolution Explorer.

Step 4

Now, open Designer page and in Solution ExploreràResourcesàLayoutàMain.Xaml, you need to select, as shown below.

Step 5

Add the code given below in Layout folder as Main.axml and fragment_sample.axml and pager_item.axml.

Main.axml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:background="#E2E2E2"
  7. android:id="@+id/sample_main_layout">
  8. <View
  9. android:layout_width="match_parent"
  10. android:layout_height="1dp"
  11. android:background="@android:color/darker_gray" />
  12. <FrameLayout
  13. android:id="@+id/sample_content_fragment"
  14. android:layout_weight="2"
  15. android:layout_width="match_parent"
  16. android:layout_height="0px" />
  17. </LinearLayout>
pager_item.axml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. android:gravity="center">
  7. <TextView
  8. android:id="@+id/item_subtitle"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:textAppearance="?android:attr/textAppearanceLarge"
  12. android:text="Page:" />
  13. <TextView
  14. android:id="@+id/item_title"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:textSize="80sp" />
  18. </LinearLayout>
fragment_sample.axml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical">
  6. <SlidingTabLayoutTutorial.SlidingTabScrollView
  7. android:id="@+id/sliding_tabs"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content" />
  10. <android.support.v4.view.ViewPager
  11. android:id="@+id/viewpager"
  12. android:layout_width="match_parent"
  13. android:layout_height="0px"
  14. android:layout_weight="1"
  15. android:background="@android:color/white" />
  16. </LinearLayout>
Step 6

Add C# code given below in your project under .SlidingTabLayoutTutorials.

MainActivity.cs
  1. using System;
  2. using Android.App;
  3. using Android.Content;
  4. using Android.Runtime;
  5. using Android.Views;
  6. using Android.Widget;
  7. using Android.OS;
  8. using App10;
  9. namespace SlidingTabLayoutTutorial
  10. {
  11. [Activity(Label = "Sliding Tab Layout", MainLauncher = true, Icon = "@drawable/xs")]
  12. public class MainActivity : Activity
  13. {
  14. protected override void OnCreate(Bundle bundle)
  15. {
  16. base.OnCreate(bundle);
  17. // Set our view from the "main" layout resource
  18. SetContentView(Resource.Layout.Main);
  19. FragmentTransaction transaction = FragmentManager.BeginTransaction();
  20. SlidingTabsFragment fragment = new SlidingTabsFragment();
  21. transaction.Replace(Resource.Id.sample_content_fragment, fragment);
  22. transaction.Commit();
  23. }
  24. public override bool OnCreateOptionsMenu(IMenu menu)
  25. {
  26. MenuInflater.Inflate(Resource.Menu.actionbar_main, menu);
  27. return base.OnCreateOptionsMenu(menu);
  28. }
  29. }
  30. }
SlidingTabScrollView.cs
  1. using System;
  2. using System.Linq;
  3. using Android.Content;
  4. using Android.OS;
  5. using Android.Views;
  6. using Android.Widget;
  7. using Android.Util;
  8. namespace SlidingTabLayoutTutorial
  9. {
  10. public class SlidingTabScrollView : HorizontalScrollView
  11. {
  12. private const int TITLE_OFFSET_DIPS = 24;
  13. private const int TAB_VIEW_PADDING_DIPS = 16;
  14. private const int TAB_VIEW_TEXT_SIZE_SP = 12;
  15. private int mTitleOffset;
  16. private int mTabViewLayoutID;
  17. private int mTabViewTextViewID;
  18. private ViewPager mViewPager;
  19. private ViewPager.IOnPageChangeListener mViewPagerPageChangeListener;
  20. private static SlidingTabStrip mTabStrip;
  21. private int mScrollState;
  22. public interface TabColorizer
  23. {
  24. int GetIndicatorColor(int position);
  25. int GetDividerColor(int position);
  26. }
  27. public SlidingTabScrollView(Context context) : this(context, null) { }
  28. public SlidingTabScrollView(Context context, IAttributeSet attrs) : this(context, attrs, 0) { }
  29. public SlidingTabScrollView (Context context, IAttributeSet attrs, int defaultStyle) : base(context, attrs, defaultStyle)
  30. {
  31. //Disable the scroll bar
  32. HorizontalScrollBarEnabled = false;
  33. //Make sure the tab strips fill the view
  34. FillViewport = true;
  35. this.SetBackgroundColor(Android.Graphics.Color.Rgb(0xE5, 0xE5, 0xE5)); //Gray color
  36. mTitleOffset = (int)(TITLE_OFFSET_DIPS * Resources.DisplayMetrics.Density);
  37. mTabStrip = new SlidingTabStrip(context);
  38. this.AddView(mTabStrip, LayoutParams.MatchParent, LayoutParams.MatchParent);
  39. }
  40. public TabColorizer CustomTabColorizer
  41. {
  42. set { mTabStrip.CustomTabColorizer = value; }
  43. }
  44. public int [] SelectedIndicatorColor
  45. {
  46. set { mTabStrip.SelectedIndicatorColors = value; }
  47. }
  48. public int [] DividerColors
  49. {
  50. set { mTabStrip.DividerColors = value; }
  51. }
  52. public ViewPager.IOnPageChangeListener OnPageListener
  53. {
  54. set { mViewPagerPageChangeListener = value; }
  55. }
  56. public ViewPager ViewPager
  57. {
  58. set
  59. {
  60. mTabStrip.RemoveAllViews();
  61. mViewPager = value;
  62. if (value != null)
  63. {
  64. value.PageSelected += value_PageSelected;
  65. value.PageScrollStateChanged += value_PageScrollStateChanged;
  66. value.PageScrolled += value_PageScrolled;
  67. PopulateTabStrip();
  68. }
  69. }
  70. }
  71. void value_PageScrolled(object sender, ViewPager.PageScrolledEventArgs e)
  72. {
  73. int tabCount = mTabStrip.ChildCount;
  74. if ((tabCount == 0) || (e.Position < 0) || (e.Position >= tabCount))
  75. {
  76. //if any of these conditions apply, return, no need to scroll
  77. return;
  78. }
  79. mTabStrip.OnViewPagerPageChanged(e.Position, e.PositionOffset);
  80. View selectedTitle = mTabStrip.GetChildAt(e.Position);
  81. int extraOffset = (selectedTitle != null ? (int)(e.Position * selectedTitle.Width) : 0);
  82. ScrollToTab(e.Position, extraOffset);
  83. if (mViewPagerPageChangeListener != null)
  84. {
  85. mViewPagerPageChangeListener.OnPageScrolled(e.Position, e.PositionOffset, e.PositionOffsetPixels);
  86. }
  87. }
  88. void value_PageScrollStateChanged(object sender, ViewPager.PageScrollStateChangedEventArgs e)
  89. {
  90. mScrollState = e.State;
  91. if (mViewPagerPageChangeListener != null)
  92. {
  93. mViewPagerPageChangeListener.OnPageScrollStateChanged(e.State);
  94. }
  95. }
  96. void value_PageSelected(object sender, ViewPager.PageSelectedEventArgs e)
  97. {
  98. if (mScrollState == ViewPager.ScrollStateIdle)
  99. {
  100. mTabStrip.OnViewPagerPageChanged(e.Position, 0f);
  101. ScrollToTab(e.Position, 0);
  102. }
  103. if (mViewPagerPageChangeListener != null)
  104. {
  105. mViewPagerPageChangeListener.OnPageSelected(e.Position);
  106. }
  107. }
  108. private void PopulateTabStrip()
  109. {
  110. PagerAdapter adapter = mViewPager.Adapter;
  111. for (int i = 0; i < adapter.Count; i++)
  112. {
  113. TextView tabView = CreateDefaultTabView(Context);
  114. tabView.Text = ((SlidingTabsFragment.SamplePagerAdapter)adapter).GetHeaderTitle(i);
  115. tabView.SetTextColor(Android.Graphics.Color.Black);
  116. tabView.Tag = i;
  117. tabView.Click += tabView_Click;
  118. mTabStrip.AddView(tabView);
  119. }
  120. }
  121. void tabView_Click(object sender, EventArgs e)
  122. {
  123. TextView clickTab = (TextView)sender;
  124. int pageToScrollTo = (int)clickTab.Tag;
  125. mViewPager.CurrentItem = pageToScrollTo;
  126. }
  127. private TextView CreateDefaultTabView(Android.Content.Context context)
  128. {
  129. TextView textView = new TextView(context);
  130. textView.Gravity = GravityFlags.Center;
  131. textView.SetTextSize(ComplexUnitType.Sp, TAB_VIEW_TEXT_SIZE_SP);
  132. textView.Typeface = Android.Graphics.Typeface.DefaultBold;
  133. if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Honeycomb)
  134. {
  135. TypedValue outValue = new TypedValue();
  136. Context.Theme.ResolveAttribute(Android.Resource.Attribute.SelectableItemBackground, outValue, false);
  137. textView.SetBackgroundResource(outValue.ResourceId);
  138. }
  139. if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.IceCreamSandwich)
  140. {
  141. textView.SetAllCaps(true);
  142. }
  143. int padding = (int)(TAB_VIEW_PADDING_DIPS * Resources.DisplayMetrics.Density);
  144. textView.SetPadding(padding, padding, padding, padding);
  145. return textView;
  146. }
  147. protected override void OnAttachedToWindow()
  148. {
  149. base.OnAttachedToWindow();
  150. if (mViewPager != null)
  151. {
  152. ScrollToTab(mViewPager.CurrentItem, 0);
  153. }
  154. }
  155. private void ScrollToTab(int tabIndex, int extraOffset)
  156. {
  157. int tabCount = mTabStrip.ChildCount;
  158. if (tabCount == 0 || tabIndex < 0 || tabIndex >= tabCount)
  159. {
  160. //No need to go further, dont scroll
  161. return;
  162. }
  163. View selectedChild = mTabStrip.GetChildAt(tabIndex);
  164. if (selectedChild != null)
  165. {
  166. int scrollAmountX = selectedChild.Left + extraOffset;
  167. if (tabIndex >0 || extraOffset > 0)
  168. {
  169. scrollAmountX -= mTitleOffset;
  170. }
  171. this.ScrollTo(scrollAmountX, 0);
  172. }
  173. }
  174. }
  175. }
SlidingTabFragment.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Android.App;
  6. using Android.Content;
  7. using Android.OS;
  8. using Android.Runtime;
  9. using Android.Util;
  10. using Android.Views;
  11. using Android.Widget;
  12. using Android.Support.V4.View;
  13. namespace SlidingTabLayoutTutorial
  14. {
  15. public class SlidingTabsFragment : Fragment
  16. {
  17. private SlidingTabScrollView mSlidingTabScrollView;
  18. private ViewPager mViewPager;
  19. public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  20. {
  21. return inflater.Inflate(Resource.Layout.fragment_sample, container, false);
  22. }
  23. public override void OnViewCreated(View view, Bundle savedInstanceState)
  24. {
  25. mSlidingTabScrollView = view.FindViewById<SlidingTabScrollView>(Resource.Id.sliding_tabs);
  26. mViewPager = view.FindViewById<ViewPager>(Resource.Id.viewpager);
  27. mViewPager.Adapter = new SamplePagerAdapter();
  28. mSlidingTabScrollView.ViewPager = mViewPager;
  29. }
  30. public class SamplePagerAdapter : PagerAdapter
  31. {
  32. List<string> items = new List<string>();
  33. public SamplePagerAdapter() : base()
  34. {
  35. items.Add("Xamarin");
  36. items.Add("Android");
  37. items.Add("Tutorial");
  38. items.Add("Part");
  39. items.Add("12");
  40. items.Add("Hooray");
  41. }
  42. public override int Count
  43. {
  44. get { return items.Count; }
  45. }
  46. public override bool IsViewFromObject(View view, Java.Lang.Object obj)
  47. {
  48. return view == obj;
  49. }
  50. public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
  51. {
  52. View view = LayoutInflater.From(container.Context).Inflate(Resource.Layout.pager_item, container, false);
  53. container.AddView(view);
  54. TextView txtTitle = view.FindViewById<TextView>(Resource.Id.item_title);
  55. int pos = position + 1;
  56. txtTitle.Text = pos.ToString();
  57. return view;
  58. }
  59. public string GetHeaderTitle (int position)
  60. {
  61. return items[position];
  62. }
  63. public override void DestroyItem(ViewGroup container, int position, Java.Lang.Object obj)
  64. {
  65. container.RemoveView((View)obj);
  66. }
  67. }
  68. }
  69. }
SlidingTabStrips.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Android.App;
  6. using Android.Content;
  7. using Android.OS;
  8. using Android.Runtime;
  9. using Android.Views;
  10. using Android.Widget;
  11. using Android.Graphics;
  12. using Android.Util;
  13. namespace SlidingTabLayoutTutorial
  14. {
  15. public class SlidingTabStrip : LinearLayout
  16. {
  17. //Copy and paste from here................................................................
  18. private const int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
  19. private const byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0X26;
  20. private const int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
  21. private int[] INDICATOR_COLORS = { 0x19A319, 0x0000FC };
  22. private int[] DIVIDER_COLORS = { 0xC5C5C5 };
  23. private const int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
  24. private const float DEFAULT_DIVIDER_HEIGHT = 0.5f;
  25. //Bottom border
  26. private int mBottomBorderThickness;
  27. private Paint mBottomBorderPaint;
  28. private int mDefaultBottomBorderColor;
  29. //Indicator
  30. private int mSelectedIndicatorThickness;
  31. private Paint mSelectedIndicatorPaint;
  32. //Divider
  33. private Paint mDividerPaint;
  34. private float mDividerHeight;
  35. //Selected position and offset
  36. private int mSelectedPosition;
  37. private float mSelectionOffset;
  38. //Tab colorizer
  39. private SlidingTabScrollView.TabColorizer mCustomTabColorizer;
  40. private SimpleTabColorizer mDefaultTabColorizer;
  41. //Stop copy and paste here........................................................................
  42. //Constructors
  43. public SlidingTabStrip (Context context) : this(context, null)
  44. { }
  45. public SlidingTabStrip (Context context, IAttributeSet attrs) : base(context, attrs)
  46. {
  47. SetWillNotDraw(false);
  48. float density = Resources.DisplayMetrics.Density;
  49. TypedValue outValue = new TypedValue();
  50. context.Theme.ResolveAttribute(Android.Resource.Attribute.ColorForeground, outValue, true);
  51. int themeForeGround = outValue.Data;
  52. mDefaultBottomBorderColor = SetColorAlpha(themeForeGround, DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
  53. mDefaultTabColorizer = new SimpleTabColorizer();
  54. mDefaultTabColorizer.IndicatorColors = INDICATOR_COLORS;
  55. mDefaultTabColorizer.DividerColors = DIVIDER_COLORS;
  56. mBottomBorderThickness = (int)(DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
  57. mBottomBorderPaint = new Paint();
  58. mBottomBorderPaint.Color = GetColorFromInteger(0xC5C5C5); //Gray
  59. mSelectedIndicatorThickness = (int)(SELECTED_INDICATOR_THICKNESS_DIPS * density);
  60. mSelectedIndicatorPaint = new Paint();
  61. mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
  62. mDividerPaint = new Paint();
  63. mDividerPaint.StrokeWidth = (int)(DEFAULT_DIVIDER_THICKNESS_DIPS * density);
  64. }
  65. public SlidingTabScrollView.TabColorizer CustomTabColorizer
  66. {
  67. set
  68. {
  69. mCustomTabColorizer = value;
  70. this.Invalidate();
  71. }
  72. }
  73. public int [] SelectedIndicatorColors
  74. {
  75. set
  76. {
  77. mCustomTabColorizer = null;
  78. mDefaultTabColorizer.IndicatorColors = value;
  79. this.Invalidate();
  80. }
  81. }
  82. public int [] DividerColors
  83. {
  84. set
  85. {
  86. mDefaultTabColorizer = null;
  87. mDefaultTabColorizer.DividerColors = value;
  88. this.Invalidate();
  89. }
  90. }
  91. private Color GetColorFromInteger(int color)
  92. {
  93. return Color.Rgb(Color.GetRedComponent(color), Color.GetGreenComponent(color), Color.GetBlueComponent(color));
  94. }
  95. private int SetColorAlpha(int color, byte alpha)
  96. {
  97. return Color.Argb(alpha, Color.GetRedComponent(color), Color.GetGreenComponent(color), Color.GetBlueComponent(color));
  98. }
  99. public void OnViewPagerPageChanged(int position, float positionOffset)
  100. {
  101. mSelectedPosition = position;
  102. mSelectionOffset = positionOffset;
  103. this.Invalidate();
  104. }
  105. protected override void OnDraw(Canvas canvas)
  106. {
  107. int height = Height;
  108. int tabCount = ChildCount;
  109. int dividerHeightPx = (int)(Math.Min(Math.Max(0f, mDividerHeight), 1f) * height);
  110. SlidingTabScrollView.TabColorizer tabColorizer = mCustomTabColorizer != null ? mCustomTabColorizer : mDefaultTabColorizer;
  111. //Thick colored underline below the current selection
  112. if (tabCount > 0)
  113. {
  114. View selectedTitle = GetChildAt(mSelectedPosition);
  115. int left = selectedTitle.Left;
  116. int right = selectedTitle.Right;
  117. int color = tabColorizer.GetIndicatorColor(mSelectedPosition);
  118. if (mSelectionOffset > 0f && mSelectedPosition < (tabCount - 1))
  119. {
  120. int nextColor = tabColorizer.GetIndicatorColor(mSelectedPosition + 1);
  121. if (color != nextColor)
  122. {
  123. color = blendColor(nextColor, color, mSelectionOffset);
  124. }
  125. View nextTitle = GetChildAt(mSelectedPosition + 1);
  126. left = (int)(mSelectionOffset * nextTitle.Left + (1.0f - mSelectionOffset) * left);
  127. right = (int)(mSelectionOffset * nextTitle.Right + (1.0f - mSelectionOffset) * right);
  128. }
  129. mSelectedIndicatorPaint.Color = GetColorFromInteger(color);
  130. canvas.DrawRect(left, height - mSelectedIndicatorThickness, right, height, mSelectedIndicatorPaint);
  131. //Creat vertical dividers between tabs
  132. int separatorTop = (height - dividerHeightPx) / 2;
  133. for (int i = 0; i < ChildCount; i++)
  134. {
  135. View child = GetChildAt(i);
  136. mDividerPaint.Color = GetColorFromInteger(tabColorizer.GetDividerColor(i));
  137. canvas.DrawLine(child.Right, separatorTop, child.Right, separatorTop + dividerHeightPx, mDividerPaint);
  138. }
  139. canvas.DrawRect(0, height - mBottomBorderThickness, Width, height, mBottomBorderPaint);
  140. }
  141. }
  142. private int blendColor(int color1, int color2, float ratio)
  143. {
  144. float inverseRatio = 1f - ratio;
  145. float r = (Color.GetRedComponent(color1) * ratio) + (Color.GetRedComponent(color2) * inverseRatio);
  146. float g = (Color.GetGreenComponent(color1) * ratio) + (Color.GetGreenComponent(color2) * inverseRatio);
  147. float b = (Color.GetBlueComponent(color1) * ratio) + (Color.GetBlueComponent(color2) * inverseRatio);
  148. return Color.Rgb((int)r, (int)g, (int)b);
  149. }
  150. private class SimpleTabColorizer : SlidingTabScrollView.TabColorizer
  151. {
  152. private int[] mIndicatorColors;
  153. private int[] mDividerColors;
  154. public int GetIndicatorColor(int position)
  155. {
  156. return mIndicatorColors[position % mIndicatorColors.Length];
  157. }
  158. public int GetDividerColor (int position)
  159. {
  160. return mDividerColors[position % mDividerColors.Length];
  161. }
  162. public int[] IndicatorColors
  163. {
  164. set { mIndicatorColors = value; }
  165. }
  166. public int[] DividerColors
  167. {
  168. set { mDividerColors = value; }
  169. }
  170. }
  171. }
  172. }
Conclusion

This project shows you how to create SlidingTabLayout.

Output





Thank you for reading.