Detect device keyboard is on or not in xamarin forms?

Sreejith Sreenivasan 896 Reputation points
2023-06-06T15:14:33.5866667+00:00

Is there any way to detect the device keyboard is on or not in Xamarin Forms?

I tried the solution on this thread, but it is not working, it is breaking with some kind of exception.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,366 questions
0 comments No comments
{count} votes

Accepted answer
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 45,566 Reputation points Microsoft Vendor
    2023-06-07T03:10:46.58+00:00

    Hello,

    After testing, I replaced the deprecated API in this solution.

    Please refer to the following code snippets for more details about how to detect device keyboard is on or not.

    Define interface for the platform service:

    public interface IKeyboardService
    {
        event EventHandler KeyboardIsShown;
        event EventHandler KeyboardIsHidden;
    }
    

    For Android:

    Step 1. Add an Instance static variable into MainActivity.cs.

    public static MainActivity Instance { get; private set; }
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        Instance = this;
        LoadApplication(new App());
    }
    

    Step 2. Implement IKeyboardService in Android.

    [assembly: Xamarin.Forms.Dependency(typeof(KeyboardService))]
    namespace App5.Droid
    {
        public class KeyboardService : IKeyboardService
        {
            public event EventHandler KeyboardIsShown;
            public event EventHandler KeyboardIsHidden;
    
            private InputMethodManager inputMethodManager;
    
            private bool wasShown = false;
    
            public KeyboardService()
            {
                GetInputMethodManager();
                SubscribeEvents();
            }
    
            public void OnGlobalLayout(object sender, EventArgs args)
            {
                GetInputMethodManager();
                if (!wasShown && IsCurrentlyShown())
                {
                    KeyboardIsShown?.Invoke(this, EventArgs.Empty);
                    wasShown = true;
                }
                else if (wasShown && !IsCurrentlyShown())
                {
                    KeyboardIsHidden?.Invoke(this, EventArgs.Empty);
                    wasShown = false;
                }
            }
    
            private bool IsCurrentlyShown()
            {
                return inputMethodManager.IsAcceptingText;
            }
    
            private void GetInputMethodManager()
            {
                if (inputMethodManager == null || inputMethodManager.Handle == IntPtr.Zero)
                {
                    inputMethodManager = (InputMethodManager)MainActivity.Instance.GetSystemService(Context.InputMethodService);
                }
            }
    
            private void SubscribeEvents()
            {
                MainActivity.Instance.Window.DecorView.ViewTreeObserver.GlobalLayout += this.OnGlobalLayout;
            }
        }
    }
    

    For iOS, you could implement IKeyboardService as the following code:

    [assembly: Xamarin.Forms.Dependency(typeof(KeyboardService))]
    namespace App5.iOS
    {
        public class KeyboardService : IKeyboardService
        {
            public event EventHandler KeyboardIsShown;
            public event EventHandler KeyboardIsHidden;
    
            public KeyboardService()
            {
                SubscribeEvents();
            }
    
            private void SubscribeEvents()
            {
                UIKeyboard.Notifications.ObserveDidShow(OnKeyboardDidShow);
                UIKeyboard.Notifications.ObserveDidHide(OnKeyboardDidHide);
            }
    
            private void OnKeyboardDidShow(object sender, EventArgs e)
            {
                KeyboardIsShown?.Invoke(this, EventArgs.Empty);
            }
    
            private void OnKeyboardDidHide(object sender, EventArgs e)
            {
                KeyboardIsHidden?.Invoke(this, EventArgs.Empty);
            }
        }
    }
    

    After that, you could invoke this service to detect keybord show/hide event in Xamarin.Forms.

    var keyboardService = Xamarin.Forms.DependencyService.Get<IKeyboardService>();
    keyboardService.KeyboardIsShown += (s, e) =>
    {
        // Add Keyboard show event.
        Console.WriteLine("KeyboardIsShown");
    };
    keyboardService.KeyboardIsHidden += (s, e) =>
    {
        // Add Keyboard hide event.
        Console.WriteLine("KeyboardIsHidden");
    };
    

    Update:

    You could implement this requirement by following these steps.

    Step 1. Modify the IsCurrentlyShown method in Android to determine whether the keyboard pops up based on the overall height change of the page.

    private bool IsCurrentlyShown()
    {
        Rect r = new Rect();
        var view = MainActivity.Instance.Window.DecorView;
        view.GetWindowVisibleDisplayFrame(r);
        int screenHeight = view.RootView.Height;
        int heightDifference = screenHeight - (r.Bottom);
        if (heightDifference > 200)
        {
            return true;
        }
        else
        {
            return false;
    
        }
    }
    

    Step 2. Set the icon to hide and display in the background code of the page.

    protected override void OnAppearing()
    {
        base.OnAppearing();
        var keybordservice = DependencyService.Get<IKeyboardService>();
        keybordservice.KeyboardIsShown += (s, e) =>
        {
            test_icon.IsVisible = false;
        };
        keybordservice.KeyboardIsHidden += (s, e) =>
        {
            test_icon.IsVisible = true;
        };
    }
    // in my testing, I used an image as icon for test.
    <Image x:Name="test_icon" Source="icon_about.png"/>
    

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.