EditText with CocosSharp (Android)

HeikofantHeikofant USUniversity ✭✭

Hey,

I need a editable text field in my CocosSharp game that uses the soft keyboard of a mobile device that starts the input with lower case letters and does not use any auto completion (or shows optional completions).

Since the only available cross-platform option for handling with a soft keyboard is the
Microsoft.Xna.Framework.GamerServices.Guide.BeginShowKeyboardInput and it doesn't support any option for the displayed keyboard itself, I need a different solution.

Does anyone know of solution for my problem?

I was thinking about displaying an Android EditText on top of my game, but I did not find any solution to do so. I trie

var et = new EditText(this); var l =(FrameLayout) FindViewById(Android.Resource.Id.Content); l.AddView(et);
in my MainActivity, but nothing happened.

Kind regards,

Heiko

Answers

  • kjpou1kjpou1 LUMember, Xamarin Team Xamurai

    @Heikofant

    You could try capturing the input yourself.

    This is just something I threw together and is nowhere complete but it may be a starting base to continue. Of course it is not cross platform at all.

    using System.Collections.Generic;
    using CocosSharp;
    
    using Android.App;
    using Android.Content;
    using Android.Views;
    using Android.Views.InputMethods;
    using Android.OS;
    
    
    namespace CocosSharpKeyboard
    {
        public class IntroLayer : CCLayerColor
        {
    
            // Define a label variable
            CCLabel label;
    
            public IntroLayer() : base(CCColor4B.Blue)
            {
    
                // create and initialize a Label
                label = new CCLabel("[Click here to enter text]", "arial", 80, CCLabelFormat.SystemFont);
    
                // add the label as a child to this Layer
                AddChild(label);
    
    
    
            }
    
            protected override void AddedToScene()
            {
                base.AddedToScene();
    
                // Use the bounds to layout the positioning of our drawable assets
                var bounds = VisibleBoundsWorldspace;
    
                // position the label on the center of the screen
                label.Position = bounds.Center;
                label.PositionY = bounds.Size.Height - 40;
    
                label.Color = CCColor3B.Gray;
    
                // Register for touch events
                var touchListener = new CCEventListenerTouchAllAtOnce();
                touchListener.OnTouchesEnded = OnTouchesEnded;
                AddEventListener(touchListener, this);
    
                Activity gameActivity = this.Application.AndroidContentView.Context as Activity;
    
                if (gameActivity != null)
                {
                    gameActivity.IsSoftKeyboardActive(out SoftKeyboardActive);
    
                }
    
                var labelListener = new CCEventListenerTouchAllAtOnce();
                labelListener.OnTouchesEnded = OnLabelTouchesEnded;
                AddEventListener(labelListener, label);
            }
    
            bool SoftKeyboardActive = false;
    
            void OnLabelTouchesEnded(List<CCTouch> touches, CCEvent touchEvent)
            {
                if (touches.Count > 0)
                {
                    var touch = touches[0];
    
                    if (!label.BoundingBoxTransformedToWorld.ContainsPoint(touch.Location))
                        return;
    
                    Activity gameActivity = this.Application.AndroidContentView.Context as Activity;
    
                    if (gameActivity != null)
                    {
                        // Perform native android commands
    
                        gameActivity.IsSoftKeyboardActive(out SoftKeyboardActive);
    
                        if (!SoftKeyboardActive)
                        {
                            gameActivity.ShowSoftKeyboard();
                            SoftKeyboardActive = true;
                            var view = gameActivity.CurrentFocus;
                            view.KeyPress += View_KeyPress;
                            label.Text = "[                        ]";
                            label.Color = CCColor3B.White;
                        }
                        else
                        {
                            gameActivity.HideSoftKeyboard();
                            SoftKeyboardActive = false;
                            var view = gameActivity.CurrentFocus;
                            view.KeyPress -= View_KeyPress;
                            label.Color = CCColor3B.Gray;
                        }
    
                    }
    
    
                }
            }
            void OnTouchesEnded(List<CCTouch> touches, CCEvent touchEvent)
            {
                if (touches.Count > 0)
                {
                    Activity gameActivity = this.Application.AndroidContentView.Context as Activity;
    
                    if (gameActivity != null)
                    {
                        gameActivity.HideSoftKeyboard();
                        SoftKeyboardActive = false;
                        var view = gameActivity.CurrentFocus;
                        view.KeyPress -= View_KeyPress;
                        label.Color = CCColor3B.Gray;
                    }
                }
            }
    
            private void View_KeyPress(object sender, View.KeyEventArgs e)
            {
                char c = (char)e.Event.UnicodeChar;
    
                if (e.Event.Action == KeyEventActions.Down)
                {
                    var currentText = label.Text;
                    var length = currentText.Length - 2;
                    var wrkText = "[" + currentText.Substring(1, length).Trim() + c;
                    wrkText = wrkText.PadRight(length);
                    wrkText += "]";
    
                    label.Text = wrkText;
    
                }
            }
        }
    
        public static class ActivityExtensions
        {
            public static void HideSoftKeyboard(this Activity activity)
            {
                new Handler().Post(delegate
                {
                    var view = activity.CurrentFocus;
                    if (view != null)
                    {
                        InputMethodManager manager = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
                        manager.HideSoftInputFromWindow(view.WindowToken, 0);
                    }
                });
            }
    
            public static void ToggleSoftKeyboard(this Activity activity, out bool isActive)
            {
                InputMethodManager manager = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
                manager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
                isActive = manager.IsActive;
            }
    
            public static void IsSoftKeyboardActive(this Activity activity, out bool isActive)
            {
                isActive = false;
                var view = activity.CurrentFocus;
                if (view != null)
                {
                    InputMethodManager manager = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
                    isActive = manager.HideSoftInputFromWindow(view.WindowToken, 0);
                }
            }
    
            public static void ShowSoftKeyboard(this Activity activity, View view = null, int delay = 200)
            {
                new Handler().PostDelayed(delegate
                {
                    view = view ?? activity.CurrentFocus;
                    if (view != null)
                    {
                        if (view.HasFocus)
                            view.ClearFocus(); //bug fix for older versions of android
    
                        view.RequestFocus();
                        InputMethodManager manager = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
                        manager.ShowSoftInput(view, ShowFlags.Forced );
                    }
                }, delay);
            }
    
            public static void ShowInputMethodPicker(this Activity activity, View view = null, int delay = 200)
            {
                new Handler().PostDelayed(delegate
                {
                    view = view ?? activity.CurrentFocus;
                    if (view != null)
                    {
                        if (view.HasFocus)
                            view.ClearFocus(); //bug fix for older versions of android
    
                        view.RequestFocus();
                        InputMethodManager manager = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
                        manager.ShowInputMethodPicker();
                    }
                }, delay);
            }
    
        }
    
    }
    
  • HeikofantHeikofant USUniversity ✭✭

    @kjpou1
    thank you for your replay.
    Your approach works on some devices but not on all.
    On my LG Nexus 4 with Android 5.1.1 the SoftKeyboard pops up but is not responsive at all. When I try to touch a key, the CCNode underneath receives its touch-input.

  • kjpou1kjpou1 LUMember, Xamarin Team Xamurai

    @Heikofant

    Like I said it was kind of thrown together. There may be other things that will need to be worked out on specific devices. Only tested on simulator to get a starting code base.

  • ReynaldoGalindoReynaldoGalindo USMember

    Kenneth, you pointed us to this code, is this possible in iOS as well? I noticed this was particularly for android.

  • kjpou1kjpou1 LUMember, Xamarin Team Xamurai

    Renaldo

    Yes this should be possible with iOS as well but will need to use iOS specific coding.

  • kjpou1kjpou1 LUMember, Xamarin Team Xamurai

    Here is the branch for CCTextField if anyone wants to follow it. Right now there is only an implementation for android and ios.

  • kjpou1kjpou1 LUMember, Xamarin Team Xamurai

    More tests and implementation in the textfield branch

  • kjpou1kjpou1 LUMember, Xamarin Team Xamurai

    CCTextField has made it into the master branch if anyone wants to test it.

Sign In or Register to comment.