Monthly Archives: May 2017

A Keyboard disabled Entry control in Xamarin Forms?

A Xamarin Forms Entry Control without a keyboard? So when the user clicks on the Entry, the keyboard wouldn’t pop up? Yep, that’s what I’m talking about yo!

Oh sweet! So that I could use my custom keyboard or key buttons to enter values into it without the keyboard popping over and covering up the view? Oh yeah! that’s awesome! 😀

So it all began..

There was this one time where I was asked to implement a page which had an Entry with a bunch of custom buttons in the page, which would insert their specific values into the Entry controls when they’re clicked.
But if the User somehow clicked on the Entry, the Keyboard shouldn’t pop up and hover over the custom keyboard. And keep on mind the Entry field or the whatever alternative text editor view should be exactly similar to an entry looks and feel! 😮

Why such a requirement you ask? Imagine an text field which has limited or custom character inputs or a security code input field, where you want to have a custom keyboard on the view without using the default system keyboard for security reason, and many more. 🙂

Alternatives?

You could say, use a Label control where you would append its text value upon the custom key button clicks.
But the problem is, Label control doesn’t have the looks and feel of an Entry control, and it would be a big hassle to customize it to look as an Entry. Also from the performance aspect as well, since it will surely require custom rendering approach. 😦

Then you might say use the Keyboard dismissal service which I posted last time in my blog, and call up on it every time the user clicks on the Entry? But nope, that would look extremely distracting while the keyboard keep on popping up and down when the User clicks on the Entry every time.

So the solution?

So the only solution here is to have a Custom Entry control which doesn’t allow the popping up of the keyboard, or in other words, an Entry which has no Keyboard attachment up on focus.  😉

This is obviously the easiest and the fastest solution to execute, since we already got the Entry’s generic look and feel, along with all the behavior, except for the on Focus Keyboard attachment behavior. 😀

^there you go 😉

How could we do this?

Alright since we are going to customize our Entry control, we need to drill down to native levels of the actual Entry’s control rendering.

The Android EditText control that associates with the Xamarin Forms Entry’s has a property called ShowSoftInputOnFocus property which allows you to disable Keyboard attachment behavior upon focus for the EditText.

Then for iOS UITextField control that associates with the Xamarin Forms Entry’s has a property called InputView property which allows you to disable the Keyboard attachment by assigning it to an empty UIView object.

So we are going to use those native properties to implement this awesomeness! 😀

Coding it is!

First of all create a Custom Entry control by sub-classing it.

namespace WhateverYourNamespace
{
    public class SoftkeyboardDisabledEntry : Entry
    {

    }
}

 

Let’s call it SoftKeyboardDisabledEntry, just for the kicks of it 😉 !

iOS Custom Renderer…

Alright let’s drill down to iOS renderering of our custom control.

[assembly: ExportRenderer(typeof(SoftkeyboardDisabledEntry), typeof(SoftkeyboardDisabledEntryRenderer))]
namespace WhateverYourNamespace.iOS
{
    public class SoftkeyboardDisabledEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            // Disabling the keyboard
            this.Control.InputView = new UIView();
        }
    }
}

 

Alright there we assign an empty UIView to the InputView property of the native control instance, which will replace Keyboard attachment at run time.

Android Custom Renderer…

Ok then comes the Android renderer, with a bit of work though.

[assembly: ExportRenderer(typeof(SoftkeyboardDisabledEntry), typeof(SoftkeyboardDisabledEntryRenderer))]
namespace WhateverYourNamespace.Droid
{
    public class SoftkeyboardDisabledEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
        
            if (e.NewElement != null)
            {
                ((SoftkeyboardDisabledEntry)e.NewElement).PropertyChanging += OnPropertyChanging;
            }

            if (e.OldElement != null)
            {
                ((SoftkeyboardDisabledEntry)e.OldElement).PropertyChanging -= OnPropertyChanging;
            }

            // Disable the Keyboard on Focus
            this.Control.ShowSoftInputOnFocus = false;
        }

        private void OnPropertyChanging(object sender, PropertyChangingEventArgs propertyChangingEventArgs)
        {
            // Check if the view is about to get Focus
            if (propertyChangingEventArgs.PropertyName == VisualElement.IsFocusedProperty.PropertyName)
            {
                // incase if the focus was moved from another Entry
                // Forcefully dismiss the Keyboard 
                InputMethodManager imm = (InputMethodManager)this.Context.GetSystemService(Context.InputMethodService);
                imm.HideSoftInputFromWindow(this.Control.WindowToken, 0);
            }
        }
    }
}

 

So there we are disabling ShowSoftInputOnFocus property by setting it false, to disable Keyboard attachment event. 😀

But then you notice that we are subscribing to the IsFocused PropertyChanged event as well. This is because in Android if we move the focus to our Custom Entry from another Entry which already had the Keyboard attached, the Keyboard wouldn’t dismiss itself. So in order to dismiss the Keyboard in case if it was already popped up, we are calling the InputMethodManager to forcefully dismiss the Keyboard. 🙂  Well this is more of a fail safe for our object, but if you think you wouldn’t run into such a scenario as above then you could remove the additional fail safe bit. 😉

Try it out?

Alright to test this out, below is a cool demo I threw in together, which you could also find in my github repo: https://github.com/XFNoSoftKeyboadEntryControl

Here’s how to consume it in your XAML!

<StackLayout Padding="10,10,10,0">

	<Label Text="Welcome to the Entry with disabled Keyboard!"
		   FontSize="22" FontAttributes="Bold" Margin="0,0,0,10"/>

	<Label Text="here is the normal Entry with Keyboard popping up on Focus"  TextColor="Gray" />
	<Entry Placeholder="Normal Entry Control..."/>

	<BoxView HeightRequest="0.7"  Margin="0,5,0,5"/>

	<Label Text="and here is our Entry with Keyboard disabled on Focus (but still editable)"  TextColor="Gray" />
	<local:SoftkeyboardDisabledEntry Placeholder="Keyboard disabled Entry Control..." x:Name="SoftkeyboardDisabledEntry" />
	
	
	<StackLayout VerticalOptions="EndAndExpand" Margin="0,0,0,10">
		<Label Text="So a simple custom keyboard may be? 😉 "  TextColor="Gray" />
		<StackLayout Orientation="Horizontal">
			<Button Text="A" Clicked="Button_OnClicked" WidthRequest="35" />
			<Button Text="B" Clicked="Button_OnClicked" WidthRequest="35" />
			<Button Text="C"  Clicked="Button_OnClicked" WidthRequest="35" />
			<Button Text="D"  Clicked="Button_OnClicked" WidthRequest="35" />
			<Button Text="E"  Clicked="Button_OnClicked" WidthRequest="35" />
			<Button Text="Clear All"  Clicked="ButtonClear_OnClicked" />
		</StackLayout>
	</StackLayout>

</StackLayout>

 

Next let’s add some Custom Key buttons to enter text to our Custom Entry with no Keyboard attached control! 😉

public partial class MainPage : ContentPage
{
	public MainPage()
	{
		InitializeComponent();
	}

	private void Button_OnClicked(object sender, EventArgs e)
	{
		SoftkeyboardDisabledEntry.Text 
                                  += ((Button) sender).Text;
	}

	private void ButtonClear_OnClicked(object sender, EventArgs e)
	{
		SoftkeyboardDisabledEntry.Text = "";
	}
}

 

that’s it.

Fire it up!

Hit that F5 and see the magic! 😀

 

WOOT! WOOT!

How cool is that eh! 😉

github repo: https://github.com/XFNoSoftKeyboadEntryControl

Enjoy and share.

Advertisements