Xamarin 表单中的自定义键盘 [英] Custom Keyboard in Xamarin forms

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

问题描述

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

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

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

我将不胜感激.

谢谢.

解决方案

Xamarin 表单中的自定义键盘

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

比如我的KeyboardPageRenderer:

[程序集:ExportRenderer(typeof(MyKeyboardPage), typeof(KeyboardPageRenderer))]...公共类 KeyboardPageRenderer : PageRenderer{公共自定义键盘视图 mKeyboardView;公共EditText mTargetView;公共 Android.InputMethodServices.Keyboard mKeyboard;活动活动;global::Android.Views.View 视图;受保护的覆盖无效 OnElementChanged(ElementChangedEventArgs<Page>e){base.OnElementChanged(e);if (e.OldElement != null || 元素 == null){返回;}尝试{设置用户界面();设置事件处理程序();this.AddView(view);}捕捉(System.Exception ex){System.Diagnostics.Debug.WriteLine(@" ERROR: ", ex.Message);}}无效设置用户界面(){活动 = this.Context 作为活动;视图 = 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;}无效的设置事件处理程序(){mTargetView.Touch += (sender, e) =>{ShowKeyboardWithAnimation();e.Handled = false;mTargetView.ShowSoftInputOnFocus = false;};mKeyboardView.Key += async (sender, e) =>{长事件时间 = 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文件中自定义布局.

更新:

<块引用>

我使用入口渲染完成了 iOS 部分,所以只尝试为 android 部分做

我写了一个EntryRenderer来实现这个功能,效果类似于this,希望对你有帮助.

public class MyEntry2Renderer : ViewRenderer,ITextWatcher,TextView.IONEditorActionListener{私人布尔_hasFocus;公共自定义键盘视图 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();}返回真;}公共虚拟 void AfterTextChanged(IEditable s){}公共虚拟 void BeforeTextChanged(ICharSequence s, int start, int count, int after){}公共虚拟 void OnTextChanged(ICharSequence s, int start, int before, int count){if (string.IsNullOrWhiteSpace(Element.Text) && (s.Length() == 0)) 返回;((IElementController)Element).SetValueFromRenderer(Entry.TextProperty, s.ToString());}受保护的覆盖 TextInputLayout CreateNativeControl(){var textInputLayout = new TextInputLayout(Context);var editText = new EditText(Context);#region 在您的页面中添加自定义键盘var 活动 = Forms.Context 作为活动;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) =>{长事件时间 = 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);返回文本输入布局;}受保护的覆盖无效 OnElementChanged(ElementChangedEventArgs<MyEntry>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天全站免登陆