如何在Xamarin.Forms上保留键盘?

时间:2017-02-21 14:40:30

标签: c# xamarin.forms

Entry.unfocus / Entry.completed隐藏键盘,如何取消?

我有一个带有一些条目的页面,当我按下键盘输入键时,我希望键盘不能隐藏。如何使用PCL项目(​​Android e iOS)?

4 个答案:

答案 0 :(得分:0)

最近我做了类似的事情。我希望键盘始终在页面中打开,而不是在单击按钮时隐藏。为实现这一目标,我在iOS和Android上采用了不同的方式。

的iOS

在iOS中,我创建了一个自定义编辑器渲染器

public class CustomEditorRenderer : EditorRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
    {
        base.OnElementChanged(e);

        var element = this.Element as CustomEditor;

        Control.InputAccessoryView = null;
        Control.ShouldEndEditing += DisableHidingKeyboard;

        MessagingCenter.Subscribe<ReportEventDetailPage>(this, "FocusKeyboardStatus", (sender) =>
        {

            if (Control != null)
            {
                Control.ShouldEndEditing += EnableHidingKeyboard;
            }

            MessagingCenter.Unsubscribe<ReportEventDetailPage>(this, "FocusKeyboardStatus");
        });
    }

    private bool DisableHidingKeyboard(UITextView textView)
    {
        return false;
    }

    private bool EnableHidingKeyboard(UITextView textView)
    {
        return true;
    }
}

在这段代码中:

Control.ShouldEndEditing += DisableHidingKeyboard;在关注自定义编辑器后使键盘始终打开。但是,将当前页面更改为其他页面时,键盘不会隐藏。为了解决这个问题,我使用了MessagingCenter,当当前页面耗尽时,我发送一条消息来隐藏键盘。

的Android

对于Android,我创建了一个键盘辅助界面并实现了它。

这是我的界面:

public interface IKeyboardHelper
{
    void ShowKeyboard();

    void HideKeyboard();
}

Android的键盘助手类:

public class KeyboardHelper : IKeyboardHelper
{
    public void ShowKeyboard()
    {
        var context = Forms.Context;
        var inputMethodManager = context.GetSystemService(Context.InputMethodService) as InputMethodManager;

        if (inputMethodManager != null && context is Activity)
        {
            var activity = context as Activity;
            var token = activity.CurrentFocus?.WindowToken;
            inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
        }
    }

    public void HideKeyboard()
    {
        var context = Forms.Context;
        var inputMethodManager = context.GetSystemService(Context.InputMethodService) as InputMethodManager;

        if (inputMethodManager != null && context is Activity)
        {
            var activity = context as Activity;
            var token = activity.CurrentFocus?.WindowToken;
            inputMethodManager.HideSoftInputFromWindow(token, HideSoftInputFlags.None);

            activity.Window.DecorView.ClearFocus();
        }
    }

在当前页面的构造函数中:

else if (Device.OS == TargetPlatform.Android)
{
     MessagingCenter.Send(this, "AndroidFocusEditor");
}

和当前页面的OnAppearing方法:

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (Device.OS == TargetPlatform.Android)
        {
            DependencyService.Get<IKeyboardHelper>().ShowKeyboard();
            //EventEditor.Focus();

            MessagingCenter.Subscribe<ReportEventDetailPage>(this, "AndroidFocusEditor", (sender) => {
                Device.BeginInvokeOnMainThread(async () => {
                    await Task.Run(() => Task.Delay(1));
                    EventEditor.Focus();

                    MessagingCenter.Unsubscribe<ReportEventDetailPage>(this, "AndroidFocusEditor");
                });
            });
        }

        else if (Device.OS == TargetPlatform.iOS)
        {
            EventEditor.Focus();
        }
    }

最后一件事:如果用户点击页面上的另一个按钮,键盘就会隐藏。为了防止这种情况,我遵循了这个链接,这对我帮助很大

Keep Keyboard Open For Android

答案 1 :(得分:0)

如果您想从PCL那里做到这一点,那么可以通过简单方便的方式浏览您的参赛作品并让他们一个接一个地关注(如果这是您正在寻找的,而不仅仅是保持键盘打开)
我们假设您的页面中有大约5个条目,并且您希望在用户按下doneenter键时循环显示这些条目。

CurrentPage.FindByName<Entry>("FirstEntry").Completed += (o, args) =>
{
    CurrentPage.FindByName<Entry>("SecondEntry").Focus();
};
CurrentPage.FindByName<Entry>("SecondEntry").Completed += (o, args) =>
{
    CurrentPage.FindByName<Entry>("ThirdEntry").Focus();
};
CurrentPage.FindByName<Entry>("ThirdEntry").Completed += (o, args) =>
{
    CurrentPage.FindByName<Entry>("ForthEntry").Focus();
};
CurrentPage.FindByName<Entry>("ForthEntry").Completed += (o, args) =>
{
    CurrentPage.FindByName<Entry>("FifthEntry").Focus();
};
CurrentPage.FindByName<Entry>("FifthEntry").Completed += (o, args) =>
{
    //Keep going or execute your command, you got the drill..
};  

您可以将其添加到ViewIsAppearingInit方法。

答案 2 :(得分:0)

仅需指出另一种Android解决方案。如果要始终保持特定编辑器渲染器的键盘可见,则需要在MainActivity类中重写以下方法:

private bool _lieAboutCurrentFocus;
    public override bool DispatchTouchEvent(MotionEvent ev)
    {
        var focused = CurrentFocus;
        bool customEntryRendererFocused = focused != null && focused.Parent is YourCustomEditorRenderer;

        _lieAboutCurrentFocus = customEntryRendererFocused;
        var result = base.DispatchTouchEvent(ev);
        _lieAboutCurrentFocus = false;

        return result;
    }

    public override Android.Views.View CurrentFocus
    {
        get
        {
            if (_lieAboutCurrentFocus)
            {
                return null;
            }

            return base.CurrentFocus;
        }
    }

您可以找到更详细的说明here

希望这会有所帮助。

致谢

答案 3 :(得分:0)

如果您有自定义键盘,则可以在android渲染器上实现“显示”和“隐藏”方法。 然后在页面上,在您的自定义控件上显示键盘而不隐藏它。您可以在更改页面时通过覆盖OnBackButtonPressed来隐藏它。

在OnBackButtonPressed中,使用MessagingCenter发送消息。然后在您的自定义控件构造函数上订阅它。 声明您在回调方法中调用的EventHandler。

在您的android自定义条目渲染器上订阅此事件,然后将键盘隐藏在那里。