Saturday 23 December 2017

Time Picker as 24 Hours Format in Xamarin.Forms

Introduction

This article describes how we can set 24h format for TimePicker Control. Sometimes we may get the requirement to set 24h for TimePicker, So in this article, we can learn how to achieve this functionality using CustomRenderer.

Requirements:
  • This article source code is prepared by using Visual Studio. And it is better to install latest visual studio updates from here.
  • This article is prepared on a MAC machine.
  • This sample project is Xamarin.Forms PCL project.
  • This sample app is targeted for Android, iOS. And tested for Android & iOS.
Description:
The creation of  Xamarin.Forms project is very simple in Visual Studio for Mac. It creates will three projects 
1) Shared Code
2) Xamarin.Android
3) Xamarin.iOS
Because Mac system with  Visual Studio for Mac it doesn't support Windows projects(UWP, Windows, Windows Phone)

The following steps will show you how to create Xamarin.Forms project in Mac system with  Visual Studio,

First, open the Visual Studio for Mac. And Click on New Project


After that, we need to select whether you're doing Xamarin.Forms or Xamarin.Android or Xamarin.iOS project. if we want to create Xamarin.Forms project just follow the below screenshot.


Then we have to give the App Name i.e TimePickerDemo.


Note: In the above screen under Shared Code, select Portable class Library or Use Shared Library.

Then click on Next Button the following screenshot will be displayed. In that screen, we have to browse the file path where we want to save that application on our PC.


After Click on Create, button it will create the RoundedCornerViewDemo Xamarin.Forms project like below.


And project structure will be.
  • TimePickerDemo: It is for Shared Code
  • TimePickerDemo.Droid: It is for Android.
  • TimePickerDemo.iOS: It is for iOS

We need to follow below few steps to set 24H for TimePicker.

Portable Class Library (PCL):
Step 1: 
In PCL, create a class name is CustomTimePicker24H which should inherit any TimePicker like below.
CustomTimePicker24H.cs
  1. using System;    
  2. using Xamarin.Forms;    
  3.     
  4. namespace TimePickerDemo    
  5. {    
  6.     public class CustomTimePicker24H : TimePicker    
  7.     {    
  8.         public CustomTimePicker24H()    
  9.         {    
  10.         }    
  11.     }    
  12.   

Step 2:
Create your own Xaml page name is TimePicker24HPage.xaml, and make sure refer "CustomTimePicker24H" class in Xaml by declaring a namespace for its location and using the namespace prefix on the control element. The following code example shows how the "CustomTimePicker24H" renderer class can be consumed by a Xaml page:

TimePicker24HPage.xaml
  1. <?xml version="1.0" encoding="UTF-8"?>        
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" BackgroundColor="White" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:custom="clr-namespace:TimePickerDemo.CustomControls;assembly=TimePickerDemo" x:Class="TimePickerDemo.Views.TimePicker24HPage">        
  3.     <ContentPage.Content>        
  4.         <StackLayout Padding="30,80,30,0" Spacing="40" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">        
  5.             <Label Text="TimePicker 24H Format" HorizontalOptions="CenterAndExpand" TextColor="Gray" FontSize="20"/>        
  6.             <custom:CustomTimePicker24H TextColor="Gray" Format="HH:mm" HeightRequest="40" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"/>        
  7.         </StackLayout>        
  8.     </ContentPage.Content>        
  9. </ContentPage>      

Note:
The "custom" namespace prefix can be named anything. However, the clr-namespace and assembly values must match the details of the custom renderer class. Once the namespace is declared the prefix is used to reference the custom control.

TimePicker24HPage.xaml.cs

  1. using System;    
  2. using System.Collections.Generic;    
  3.     
  4. using Xamarin.Forms;    
  5.     
  6. namespace TimePickerDemo.Views    
  7. {    
  8.     public partial class TimePicker24HPage : ContentPage    
  9.     {    
  10.         public TimePicker24HPage()    
  11.         {    
  12.             InitializeComponent();    
  13.         }    
  14.     }    
  15. }    

Xamarin.Andriod:


In Android project, create a class name is CustomTimePicker24HRenderer and make sure to add renderer registration for our CustomTimePicker24H class in above of the namespace:

CustomTimePicker24HRenderer.cs

  1. using System;    
  2. using Android.Widget;    
  3. using Xamarin.Forms;    
  4. using Xamarin.Forms.Platform.Android;    
  5. using Android.App;    
  6. using Android.Runtime;    
  7. using TimePickerDemo.Droid;    
  8. using TimePickerDemo.CustomControls;    
  9.     
  10. [assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]    
  11. namespace TimePickerDemo.Droid    
  12. {    
  13.     public class CustomTimePicker24HRenderer : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable    
  14.     {    
  15.         private TimePickerDialog dialog = null;    
  16.     
  17.         protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)    
  18.         {    
  19.             base.OnElementChanged(e);    
  20.             this.SetNativeControl(new Android.Widget.EditText(Forms.Context));    
  21.             this.Control.Click += Control_Click;    
  22.             this.Control.Text = DateTime.Now.ToString("HH:mm");    
  23.             this.Control.KeyListener = null;    
  24.             this.Control.FocusChange += Control_FocusChange;    
  25.         }    
  26.     
  27.         void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)    
  28.         {    
  29.             if (e.HasFocus)    
  30.                 ShowTimePicker();    
  31.         }    
  32.     
  33.         void Control_Click(object sender, EventArgs e)    
  34.         {    
  35.             ShowTimePicker();    
  36.         }    
  37.     
  38.         private void ShowTimePicker()    
  39.         {    
  40.             if (dialog == null)    
  41.             {    
  42.                 dialog = new TimePickerDialog(Forms.Context, this, DateTime.Now.Hour, DateTime.Now.Minute, true);    
  43.             }    
  44.     
  45.             dialog.Show();    
  46.         }    
  47.     
  48.         public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)    
  49.         {    
  50.             var time = new TimeSpan(hourOfDay, minute, 0);    
  51.             this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);    
  52.     
  53.             this.Control.Text = time.ToString(@"hh\:mm");    
  54.         }    
  55.     }    
  56. }    

Here OnElementChanged method instantiates an Android UI Layout in that I assigned current time to TimePicker and set 24h format.


Xamarin.iOS

In iOS project, create a class name is CustomTimePicker24HRenderer and make sure to add renderer registration for our CustomTimePicker24H class in above of the namespace:


CustomTimePicker24HRenderer.cs

  1. using System;    
  2. using Xamarin.Forms.Platform.iOS;    
  3. using UIKit;    
  4. using Xamarin.Forms;    
  5. using TimePickerDemo.iOS;    
  6. using Foundation;    
  7. using TimePickerDemo.CustomControls;    
  8.     
  9. [assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]    
  10. namespace TimePickerDemo.iOS    
  11. {    
  12.     public class CustomTimePicker24HRenderer : TimePickerRenderer    
  13.     {    
  14.         protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)    
  15.         {    
  16.             base.OnElementChanged(e);    
  17.             var timePicker = (UIDatePicker)Control.InputView;    
  18.             timePicker.Locale = new NSLocale("no_nb");    
  19.     
  20.             if (Control != null)    
  21.             {    
  22.                 Control.Text = DateTime.Now.ToString("HH:mm");    
  23.             }    
  24.         }    
  25.     }    
  26. }    

Here OnElementChanged method instantiates a Here OnElementChanged method instantiates an iOS UI, in that I assigned current time to the Control and set 24h format using NSLocale.


 Output:  
               

Please download the source code from below.

1 comment:

  1. The property changed event is not fired when the date is not change and ok is clicked , which is expected. But the Unfocused event is also fired when Ok / Cancel is pressed on Android .

    ReplyDelete