Xamarin 形式的自定义键盘 [英] Custom Keyboard in Xamarin forms

查看:35
本文介绍了Xamarin 形式的自定义键盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了论坛、StackOverflow 和其他地方关于制作自定义键盘的许多帖子,但还没有找到适用于我的 Xamarin 表单跨平台项目的方法.它以编程方式生成.

例如,我构建了在几个地方推荐的这个键盘:

我尝试将其集成到我的 Xamarin 表单应用程序中,但无法做到这一点

我将不胜感激.

谢谢.

解决方案

Xamarin 表单中的自定义键盘

您可以创建一个 PageRenderer 并使用本机 .axml 布局文件来创建自定义 Keyboard.

例如,我的 KeyboardPageRenderer :

[程序集:ExportRenderer(typeof(MyKeyboardPage), typeof(KeyboardPageRenderer))]...公共类 KeyboardPageRenderer : PageRenderer{公共 CustomKeyboardView mKeyboardView;公共 EditText mTargetView;公共 Android.InputMethodServices.Keyboard mKeyboard;活动活动;global::Android.Views.View 视图;protected override void OnElementChanged(ElementChangedEventArgs e){base.OnElementChanged(e);if (e.OldElement != null || Element == null){返回;}尝试{设置用户界面();设置事件处理程序();this.AddView(view);}catch (System.Exception ex){System.Diagnostics.Debug.WriteLine(@"错误:", ex.Message);}}void SetupUserInterface(){活动 = this.Context 作为活动;view = activity.LayoutInflater.Inflate(Resource.Layout.activity_keyboard, this, false);mKeyboard = new Android.InputMethodServices.Keyboard(Context, Resource.Xml.keyboard);mTargetView = view.FindViewById(Resource.Id.target);mKeyboardView = view.FindViewById(Resource.Id.keyboard_view);mKeyboardView.Keyboard = mKeyboard;}void SetupEventHandlers(){mTargetView.Touch += (sender, e) =>{ShowKeyboardWithAnimation();e.handled = false;mTargetView.ShowSoftInputOnFocus = false;};mKeyboardView.Key += async (sender, e) =>{long eventTime = JavaSystem.CurrentTimeMillis();KeyEvent ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, e.PrimaryCode, 0, 0, 0, 0, KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);DispatchKeyEvent(ev);等待 Task.Delay(1);mTargetView.RequestFocus();};}公共无效 ShowKeyboardWithAnimation(){如果(mKeyboardView.Visibility == ViewStates.Gone){mKeyboardView.Visibility = ViewStates.Visible;Android.Views.Animations.Animation 动画 = AnimationUtils.LoadAnimation(语境,Resource.Animation.slide_in_bottom);mKeyboardView.ShowWithAnimation(动画);}}protected override void OnLayout(bool changed, int l, int t, int r, int b){base.OnLayout(改变,l,t,r,b);var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);view.Measure(msw, msh);view.Layout(0, 0, r - l, b - t);}}

效果:

.

我写了一个关于如何实现这个功能的简单演示,你可以在这个GitHub存储库中看到它.

我不会希伯来语,如果你要达到你发的图片的效果,你需要在keyboard.xml文件中自定义布局.

更新:

<块引用>

我使用 entry render 完成了 iOS 部分,所以只尝试为 android 部分做

我写了一个 EntryRenderer 来实现这个功能,效果就像 this,希望能帮到你.

public class MyEntry2Renderer : ViewRenderer,文本观察者,TextView.IONEditorActionListener{私人布尔_hasFocus;公共 CustomKeyboardView mKeyboardView;公共 Android.InputMethodServices.Keyboard mKeyboard;ViewGroup 活动RootView;受保护的 EditText EditText =>Control.EditText;public bool OnEditorAction(TextView v, ImeAction actionId, KeyEvent e){if ((actionId == ImeAction.Done) || ((actionId == ImeAction.ImeNull) && (e.KeyCode == Keycode.Enter))){Control.ClearFocus();//隐藏键盘();((IEntryController)Element).SendCompleted();}返回真;}公共虚拟无效 AfterTextChanged(IEditable s){}public virtual void BeforeTextChanged(ICharSequence s, int start, int count, int after){}public virtual void OnTextChanged(ICharSequence s, int start, int before, int count){if (string.IsNullOrWhiteSpace(Element.Text) && (s.Length() == 0)) return;((IElementController)Element).SetValueFromRenderer(Entry.TextProperty, s.ToString());}受保护的覆盖 TextInputLayout CreateNativeControl(){var textInputLayout = new TextInputLayout(Context);var editText = new EditText(Context);#region 在页面中添加自定义键盘var activity = Forms.Context as Activity;var rootView = activity.Window.DecorView.FindViewById(Android.Resource.Id.Content);activity.Window.SetSoftInputMode(SoftInput.StateAlwaysHidden);activityRootView = ((ViewGroup)rootView).GetChildAt(0) as ViewGroup;mKeyboardView = new CustomKeyboardView(Forms.Context, null);Android.Widget.RelativeLayout.LayoutParams layoutParams =新的 Android.Widget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.WrapContent);//或 wrap_contentlayoutParams.AddRule(LayoutRules.AlignParentBottom);activityRootView.AddView(mKeyboardView, layoutParams);#endregion//先打开当前页面,隐藏键盘mKeyboardView.Visibility = ViewStates.Gone;//使用自定义键盘mKeyboard = new Android.InputMethodServices.Keyboard(Context, Resource.Xml.keyboard2);mKeyboardView.Keyboard = mKeyboard;mKeyboardView.Key += async (sender, e) =>{long eventTime = JavaSystem.CurrentTimeMillis();KeyEvent ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, e.PrimaryCode, 0, 0, 0, 0, KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);DispatchKeyEvent(ev);等待 Task.Delay(1);};textInputLayout.AddView(editText);返回文本输入布局;}protected override void OnElementChanged(ElementChangedEventArgs e){base.OnElementChanged(e);if (e.OldElement != null)如果(控制!= null)EditText.FocusChange -= ControlOnFocusChange;if (e.NewElement != null){var ctrl = CreateNativeControl();SetNativeControl(ctrl);EditText.ShowSoftInputOnFocus = false;EditText.FocusChange += ControlOnFocusChange;}}私有无效 ControlOnFocusChange(对象发送者,FocusChangeEventArgs args){_hasFocus = args.HasFocus;如果(_hasFocus){EditText.Post(() =>{EditText.RequestFocus();ShowKeyboardWithAnimation();});}别的{//隐藏键盘mKeyboardView.Visibility = ViewStates.Gone;}}公共无效 ShowKeyboardWithAnimation(){如果(mKeyboardView.Visibility == ViewStates.Gone){mKeyboardView.Visibility = ViewStates.Visible;Android.Views.Animations.Animation 动画 = AnimationUtils.LoadAnimation(语境,Resource.Animation.slide_in_bottom);mKeyboardView.ShowWithAnimation(动画);}}}

I've read the many posts on the forum and on StackOverflow and other places on making custom keyboards, but have not found an approach that will work for my Xamarin forms cross-platform project. It is programmatically generated.

For example, I built this keyboard that was recommended in several places:

I try to integrate this into my Xamarin forms app but not able to do this

https://github.com/Vaikesh/CustomKeyboard/blob/master/CustomKeyboard/Activity1.cs

It works fine as a standalone

I want Hebrew language keyboard in my application Like this

I would appreciate any help.

Thank you.

解决方案

Custom Keyboard in Xamarin forms

You could create a PageRenderer and use native .axml layout file to create the custom Keyboard.

For example, my KeyboardPageRenderer :

[assembly: ExportRenderer(typeof(MyKeyboardPage), typeof(KeyboardPageRenderer))]
...
public class KeyboardPageRenderer : PageRenderer
{

    public CustomKeyboardView mKeyboardView;
    public EditText mTargetView;
    public Android.InputMethodServices.Keyboard mKeyboard;
    Activity activity;
    global::Android.Views.View view;

    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null || Element == null)
        {
            return;
        }

        try
        {
            SetupUserInterface();
            SetupEventHandlers();
            this.AddView(view);
        }
        catch (System.Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(@"           ERROR: ", ex.Message);
        }
    }

    void SetupUserInterface()
    {
        activity = this.Context as Activity;
        view = activity.LayoutInflater.Inflate(Resource.Layout.activity_keyboard, this, false);

        mKeyboard = new Android.InputMethodServices.Keyboard(Context, Resource.Xml.keyboard);
        mTargetView = view.FindViewById<EditText>(Resource.Id.target);

        mKeyboardView = view.FindViewById<CustomKeyboardView>(Resource.Id.keyboard_view);
        mKeyboardView.Keyboard = mKeyboard;
    }

    void SetupEventHandlers()
    {
        mTargetView.Touch += (sender, e) =>
        {
            ShowKeyboardWithAnimation();
            e.Handled = false;
            mTargetView.ShowSoftInputOnFocus = false;
        };

        mKeyboardView.Key += async (sender, e) =>
        {
            long eventTime = JavaSystem.CurrentTimeMillis();
            KeyEvent ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, e.PrimaryCode, 0, 0, 0, 0, KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);

            DispatchKeyEvent(ev);

            await Task.Delay(1);

            mTargetView.RequestFocus();
        };
    }


    public void ShowKeyboardWithAnimation()
    {
        if (mKeyboardView.Visibility == ViewStates.Gone)
        {
            mKeyboardView.Visibility = ViewStates.Visible;
            Android.Views.Animations.Animation animation = AnimationUtils.LoadAnimation(
                Context,
                Resource.Animation.slide_in_bottom
            );
            mKeyboardView.ShowWithAnimation(animation);
        }
    }

    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        base.OnLayout(changed, l, t, r, b);

        var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);
        var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);

        view.Measure(msw, msh);
        view.Layout(0, 0, r - l, b - t);
    }
}

Effect:

.

I wrote up a simple demo about how to implement this feature, you can see it in this GitHub Repository.

I don't know Hebrew, if you need to achieve the effect like the picture you have post, you need custom the layout in keyboard.xml file.

Update :

I am done iOS portion using entry render so only try to do for android portion

I write a EntryRenderer to implement this feature, effect like this, hope this can help you.

public class MyEntry2Renderer :  ViewRenderer<MyEntry, TextInputLayout>,
    ITextWatcher,
    TextView.IOnEditorActionListener
{
    private bool _hasFocus;

    public CustomKeyboardView mKeyboardView;
    public Android.InputMethodServices.Keyboard mKeyboard;

    ViewGroup activityRootView;

    protected EditText EditText => Control.EditText;

    public bool OnEditorAction(TextView v, ImeAction actionId, KeyEvent e)
    {
        if ((actionId == ImeAction.Done) || ((actionId == ImeAction.ImeNull) && (e.KeyCode == Keycode.Enter)))
        {
            Control.ClearFocus();
            //HideKeyboard();
            ((IEntryController)Element).SendCompleted();
        }
        return true;
    }

    public virtual void AfterTextChanged(IEditable s)
    {
    }

    public virtual void BeforeTextChanged(ICharSequence s, int start, int count, int after)
    {
    }

    public virtual void OnTextChanged(ICharSequence s, int start, int before, int count)
    {
        if (string.IsNullOrWhiteSpace(Element.Text) && (s.Length() == 0)) return;
        ((IElementController)Element).SetValueFromRenderer(Entry.TextProperty, s.ToString());
    }

    protected override TextInputLayout CreateNativeControl()
    {
        var textInputLayout = new TextInputLayout(Context);
        var editText = new EditText(Context);

        #region Add the custom Keyboard in your Page
        var activity = Forms.Context as Activity;
        var rootView = activity.Window.DecorView.FindViewById(Android.Resource.Id.Content);

        activity.Window.SetSoftInputMode(SoftInput.StateAlwaysHidden);

        activityRootView = ((ViewGroup)rootView).GetChildAt(0) as ViewGroup;
        mKeyboardView = new CustomKeyboardView(Forms.Context, null);

        Android.Widget.RelativeLayout.LayoutParams layoutParams =
            new Android.Widget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.WrapContent); // or wrap_content
        layoutParams.AddRule(LayoutRules.AlignParentBottom);
        activityRootView.AddView(mKeyboardView, layoutParams);
        #endregion

        //First open the current page, hide the Keyboard
        mKeyboardView.Visibility = ViewStates.Gone;

        //Use the custom Keyboard
        mKeyboard = new Android.InputMethodServices.Keyboard(Context, Resource.Xml.keyboard2);
        mKeyboardView.Keyboard = mKeyboard;

        mKeyboardView.Key += async (sender, e) =>
        {
            long eventTime = JavaSystem.CurrentTimeMillis();
            KeyEvent ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, e.PrimaryCode, 0, 0, 0, 0, KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);

            DispatchKeyEvent(ev);

            await Task.Delay(1);
        };

        textInputLayout.AddView(editText);
        return textInputLayout;
    }


    protected override void OnElementChanged(ElementChangedEventArgs<MyEntry> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
            if (Control != null)
                EditText.FocusChange -= ControlOnFocusChange;

        if (e.NewElement != null)
        {
            var ctrl = CreateNativeControl();
            SetNativeControl(ctrl);

            EditText.ShowSoftInputOnFocus = false;

            EditText.FocusChange += ControlOnFocusChange;
        }
    }

    private void ControlOnFocusChange(object sender, FocusChangeEventArgs args)
    {
        _hasFocus = args.HasFocus;
        if (_hasFocus)
        {
            EditText.Post(() =>
            {
                EditText.RequestFocus();
                ShowKeyboardWithAnimation();
            });
        }
        else
        {
            //Hide the Keyboard
            mKeyboardView.Visibility = ViewStates.Gone;
        }
    }

    public void ShowKeyboardWithAnimation()
    {
        if (mKeyboardView.Visibility == ViewStates.Gone)
        {
            mKeyboardView.Visibility = ViewStates.Visible;
            Android.Views.Animations.Animation animation = AnimationUtils.LoadAnimation(
                Context,
                Resource.Animation.slide_in_bottom
            );
            mKeyboardView.ShowWithAnimation(animation);
        }
    }
}

这篇关于Xamarin 形式的自定义键盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆