How to avoid showing keyboard when focusing EntryCell

fernandopfernandop USMember ✭✭

Hi,
I have a Xamarin.forms project, I have a page with an EntryCell control, I want to avoid showing the keyboard when the EntryCell gets the focus since it is for scanning barcode labels, how can I achieve that? thanks.

«1

Posts

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Sounds like you should use a label or a button instead.

  • fernandopfernandop USMember ✭✭

    but I still need to set the focus on the control... it is an input cell, not sure if using button or label is better than EntryCell,, I will check. In any case I set keyboard to null to check, but I am running in the issues generating the release for API-15 so first I need to fix that to be able to test in real device. How do you declare a button or label to entry text? thanks.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Why do you need it to have focus? Is this a limitation of how the scanner works? Is there an API for the scanner to do it differently?

    How do you declare a button or label to entry text?

    I don't know what you mean by that. I was suggesting that you just show the text in a button or label. You wouldn't be able to "type" in it because you don't want the keyboard to show. I'm assuming you have an API that gets the scanned value from the scanner, and you can do whatever you want with that. If the scanner just pretends to be a keyboard then I don't know what your options are. Presumably there is some way to say "if I have a hardware keyboard connected then don't show the software keyboard", but I'm pretty sure that's a platform-specific issue. iOS just seems to do that automatically.

  • fernandopfernandop USMember ✭✭

    I want to allow to manually enter text too, the device already has a keyboard, anyway, I will test it with keyboard = null and let you know if that works. thanks.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    For that you can overlay a button on top of an Entry. When the user taps the button you hide the button and give focus to the Entry. Basically, if you can avoid actually giving focus to an Entry it's much easier to avoid showing the software keyboard.

  • fernandopfernandop USMember ✭✭

    Setting keyboard = null worked fine, I have the focus on the EntryCell and it gets the scanned values.
    Regards.

  • fernandopfernandop USMember ✭✭

    Well, I need to do the same for an Entry control but that doesn't work, any idea?
    This works, i.e: the keyboard is not displayed when the control gets the focus:
    txtSubProdNo = new EntryCell {
    Placeholder = "",
    Keyboard = null
    };

    This doesn't work:
    txtSubProdNo = new Entry{
    Text = "",
    Keyboard = null
    };

    Thanks.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I already gave you my suggestion. :)

  • fernandopfernandop USMember ✭✭

    Hi, when you suggest something it should be related to what the other person needs. Thanks for your help, but I need an Entry focused when the form is shown, without keyboard being shown, that is not what you answered. Regards.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    It was related. It is what I would do for this situation because what you are trying may be much harder. Sometimes people have a solution in mind already and just want an implementation, but their solution is not the right solution in the first place. A different approach can save you a lot of trouble even if it wasn't what you were originally thinking. Tunnel vision on one approach will just lead you to spending countless hours going nowhere. I won't apologize for that. My answer was infinitely better than the other responses you got (none).

    That said, you could also have used Google to come to this solution. That took me 30 seconds.

  • fernandopfernandop USMember ✭✭

    Look your approach: setting focus in the Entry control, then the keyboard is displayed. My apologies, I think you didnt understand what I need , so we are fine. I will try to get some response from Xamarin support. Regards.

  • DanielMayDanielMay GBMember

    Adam Kemp has a point. The Entry control is designed for text entry, whereas it looks like you are accepting input from not a keyboard but a barcode scanner.

    In your position, I would subclass the Entry and provide a custom renderer that did not open the keyboard on focus, but instead prompted input of a barcode.

    Alternatively you could just have a button - "Enter Barcode" - which when pressed prompted barcode entry. You could have the barcode # bound to a read-only Entry field easily, if that is your end goal.

  • fernandopfernandop USMember ✭✭

    Please, first: nothing about buttons, the idea is that user doesnt need to do anything in the screen, just scan a barcode.

    I will check subclassing Entry, but I have more issues with that control, for example, the Enter key code is not being processed, the scanner sends a Enter at the end of barcode. Anyway, thanks for your help. Regards.

  • fernandopfernandop USMember ✭✭

    Well, I accomplished that by writing a custom renderer but anyway there is a bug in Xamarin when calling entry.Focus() that doesn't allow hiding the keyboard. Xamarin support responded:
    [It looks like the Focus method is doing something that is conflicting with the hiding. You might have better luck making a custom method for focusing the control. For example, make your own SetFocus method and only do what you need. ]

    If somebody needs the renderer, please tell me.

  • RogerKelleyRogerKelley USMember

    Fernando, I am interested in the details of you solution. Could you provide the code for your custom renderer? Thanks much.

  • fernandopfernandop USMember ✭✭

    Hi, below is my renderer, it needs to be improved, also the logic to call HideKeyboard can be improved, but I didnt resume working on it yet, this is the initial version:

    MyEntry class, it goes in PCL project:

    `using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Xamarin.Forms;

    namespace Scanpack.net
    {
    public class MyEntry: Entry
    {
    public event Action OnHideKeyboard;

        public void HideKeyboard()
        {
            if (OnHideKeyboard != null)
                OnHideKeyboard();
        }
    
        public Action OnEnterPressed;
    
        public void EnterPressed()
        {
            if (OnEnterPressed != null)
                OnEnterPressed();
        }
    
        public Action OnFocusChanged;
    
        public void FocusChanged()
        {
            if (OnFocusChanged != null)
                OnFocusChanged();
        }
    }
    

    }
    `

    Renderer, it goes in the Android project, you need to create one in iOS and Windows phone if needed.
    `
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Xamarin.Forms;
    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Xamarin.Forms.Platform.Android;
    using Scanpack.net;

    using Android.Views.InputMethods;

    [assembly: ExportRenderer(typeof(MyEntry), typeof(Scanpack.net.Android.MyEntryRenderer))]

    namespace Scanpack.net.Android
    {
    public class MyEntryRenderer : EntryRenderer
    {
    // Override the OnElementChanged method so we can tweak this renderer post-initial setup
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);

            if (e.OldElement == null)
            {
                var nativeEditText = (global::Android.Widget.EditText)Control;
                nativeEditText.SetSelectAllOnFocus(true);
            }
    
            if (Control != null &&  e.OldElement == null)
            {
                System.Diagnostics.Debug.WriteLine("Adding EditorAction method");
    
                // this is a sample: do whatever you want to the textField here!
                //Control.SetBackgroundColor(global::Android.Graphics.Color.DarkGray);
    
                (this.Element as MyEntry).OnHideKeyboard += MyEntryRenderer_hideKeyboard;
    
               //TODO: (fernandop) Check if this logic to process Enter key is fine, not sure about using ImeAction.ImeNull
               // It looks like it is called twice.
               // Control.ImeOptions = ImeAction.Done;
                Control.EditorAction += (sender, args) =>
                {
                    System.Diagnostics.Debug.WriteLine("EditorAction {0}", args.ActionId);
                    if (args.ActionId == ImeAction.ImeNull)
                    {
                        System.Diagnostics.Debug.WriteLine("EnterPressed");
                        (this.Element as MyEntry).EnterPressed();
                    }
                };
    
            }
    
    
        }
    
        void MyEntryRenderer_hideKeyboard()
        {
            HideKeyboard();
        }
    
        public void ShowKeyboard()
        {
            this.Control.RequestFocus();
            InputMethodManager inputMethodManager = this.Control.Context.GetSystemService(Context.InputMethodService) as InputMethodManager;
            inputMethodManager.ShowSoftInput(this.Control, ShowFlags.Forced);
            inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
        }
    
        /// <summary>
        /// Hides the soft keyboard.
        /// </summary>
        public void HideKeyboard()
        {
    
            //this.Control.RequestFocus();
            System.Diagnostics.Debug.WriteLine("HideKeyboard");
            this.Control.InputType = 0;
            InputMethodManager inputMethodManager = this.Control.Context.GetSystemService(Context.InputMethodService) as InputMethodManager;
            inputMethodManager.HideSoftInputFromWindow(this.Control.WindowToken, HideSoftInputFlags.ImplicitOnly);
        }
    
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
    
            var view = (MyEntry)Element;
    
            //System.Diagnostics.Debug.WriteLine("OnElementPropertyChanged {0}", e.PropertyName);
    
            if (e.PropertyName == "Text")
            {
               // System.Diagnostics.Debug.WriteLine("Text changed");
            }
    
            if (e.PropertyName == "IsFocused")
            {
                System.Diagnostics.Debug.WriteLine("IsFocused changed");
                view.FocusChanged();
            }
    
        }
    }
    

    }`

    you use it in PCL side:

    `
    MyEntry txtLocalWebServer;
    txtLocalWebServer = new MyEntry
    {
    Text = "Entry",
    };
    txtLocalWebServer.Focused += (sender, e) =>
    {
    txtLocalWebServer.HideKeyboard();
    };

    `

  • ToddmorrisToddmorris NZMember ✭✭

    Good stuff.
    Any update to this? I have implemented it and is mostly works.. except.... when I enter the entry control txtChanged event and set the text value to "" after a barcode scan.. the keyboard pops up again.
    Any help would be appreciated.

  • fernandopfernandop USMember ✭✭

    Yes, we used a workaround, I will send you the code.

  • fernandopfernandop USMember ✭✭

    @Toddmorris please see attached and tell me if that is enough to get your app working.

  • ToddmorrisToddmorris NZMember ✭✭

    You my kind sir... are a legend!
    Works perfectly. Although one small note, I needed to add 'CanShowVirtualKeyboard = false', when I set up the Entry form. This property (usefull btw)was not in the original version and I forgot to set it for awhile, nothing a small amount of debugging didn't fix. I really appreciate your assistance, you have saved my a huge amount of time effort and frustration. Thanks again.

  • fernandopfernandop USMember ✭✭

    Hi, you are welcome. Sorry about that property I saw it today when copying the code and forgot to comment about it in txt file, we use it as a global setting of the app.

  • FLITDevFLITDev USMember
    edited September 2015

    Hi,
    I have a similar problem as well. Would it be possible to get the code for the workaround as well? The rest already works like a charm. Thank you for sharing this!

  • LukasBurnsLukasBurns CLMember, University

    Is there a way you could share me your code of this? would really appreciate it!
    thanks!

  • fernandopfernandop USMember ✭✭

    Hi @FLITDev and @LukasBurns , I will attach the code later today here.

    @Toddmorris do you have the code I sent you?

  • ToddmorrisToddmorris NZMember ✭✭

    @LukasBurns @FLITDev @fernandop

    Yes here it is, it is working great.

  • fernandopfernandop USMember ✭✭

    thank you!

  • LukasBurnsLukasBurns CLMember, University

    @fernandop @Toddmorris ,
    Thanks !

  • Hello @Toddmorris,

    Thanks for all hardwork, its helping me as well. Could you pls tell me how to set default focus on MyEntry.

    Regards,
    Sreedhar

  • fernandopfernandop USMember ✭✭

    Hi.
    I have this on the view that uses it, txtSubProdNo is of MyEntry type.
    protected override void OnAppearing () { base.OnAppearing (); txtSubProdNo.Focus(); }

  • MichelangeloFrancoMichelangeloFranco ITUniversity ✭✭

    @Toddmorris Thanks, work great on android. I have to make same thing on iOS, did you have any solution?

  • fernandopfernandop USMember ✭✭

    Not me. Maybe another user here in this thread.

  • JoakimMnssonJoakimMnsson SEMember ✭✭
    edited February 2017

    Just a tip. I wanted to be able to show the keyboard Onclick (on Entry) and have it focused otherwise. So I added this to OnElementChanged

     Control.FocusChange += (sender, evt) => {
                    new Handler().Post(delegate
                    {
                        var imm = (InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
                        var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);
    
                        Console.WriteLine(result);
                    });
                };
    

    Wherever I needed focus on my Entry without showing keyboard I called
    myEntry.Focus();

  • NagAkkiNagAkki USUniversity

    First timer here, couple of months into Xamarin development. I tried the code in code behind project, and it works well. But in MVVM, I am having problem implementing the solution. Setting CanShowVirtualKeyboard=false is hiding the keyboard, perfect. But tap on the Entry field needs CanShowVirtualKeyboard=true for the Keboard to appear. Not sure logically when and where to set the value to true. Can someone share code or ideas? You all my heroes, been reading the site forever. Thanks

  • fernandopfernandop USMember ✭✭
    edited March 2017

    Hi,
    I use this control in MVVM too. In my case, I implemented this because the device has a physical keyboard, so the idea is to never show the soft keyboard. I think there is a method to force the soft keyboard to be displayed, then you can implement it in the Tap event of the Entry. Let me know if you don't find the way to force to show it. Also, you should consider to remove CanShowVirtualKeyboard and use an instance property for the custom Entry control, in order to be able to set it to every control (I use it globally as a setting of the app).
    Regards,

  • MuhammadUsman.2067MuhammadUsman.2067 USMember ✭✭

    Hi, please help me in this problem
    when i press the back button to go back on previous screen then a white screen splashes that look like a bug in app.
    how can i get rid of it???
    and second problem is that when i focus on entry field to insert some data then app moves upward. means navigation bar hides then when i close the keyboard then title bar comes back.
    how can i adjust it?
    I am using xamarin crossplate forms and working on android.
    thanks in advance

  • fernandopfernandop USMember ✭✭

    Hi,
    scrolling the screen up to show the keyboard and still the Entry being visible is normal in the apps I think.
    About the bug with the back button, I think I need to see the code to check it. Can you attach it here?
    Regards.

  • KayKuoKayKuo Member ✭✭✭

    @fernandop,@MuhammadUsman.2067
    hi i use it,but cannot press enter

  • fernandopV2fernandopV2 Member ✭✭

    @KayKuo , does you device have a physical keyboard? I use this control in a device with physical keyboard, so I use Enter key on the device.

  • KayKuoKayKuo Member ✭✭✭
    @fernandopV2
    There is no physical keyboard on my device, but there will be an enter after scanning the code,but enter does not work,
    And I used the Genymotion to test, I can enter the number normally, but click on the enter does not work.
«1
Sign In or Register to comment.