【问题标题】:How to keep keyboard on Xamarin.Forms?如何在 Xamarin.Forms 上保留键盘?
【发布时间】:2017-07-11 06:07:14
【问题描述】:

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

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

【问题讨论】:

标签: c# xamarin.forms


【解决方案1】:

只是指出另一个适用于 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

希望这会有所帮助。

问候

【讨论】:

  • 这个解决方案很完美!
【解决方案2】:

如果您想从 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 方法中。

【讨论】:

  • 我这样做了,但它也隐藏了键盘。感谢您的帮助。
【解决方案3】:

最近我做了类似的事情。我想让键盘始终在页面中打开,而不是在单击按钮时隐藏。为此,我在 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,我创建了一个键盘助手界面并实现了它。

这是我的界面:

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

【讨论】:

    【解决方案4】:

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

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

    在您的 android 自定义条目渲染器上订阅此事件并在此处隐藏键盘。

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多