C# 在Xamarin中隐藏软键盘

C# 在Xamarin中隐藏软键盘,c#,android,xamarin,xamarin.android,xamarin.forms,C#,Android,Xamarin,Xamarin.android,Xamarin.forms,在Xamarin.forms便携表单项目中,当聚焦条目时,如何隐藏显示的软键盘?我假设我们必须为此编写特定于平台的渲染器,但以下操作不起作用: 我创建自己的entry子类: public class MyExtendedEntry : Entry { } 然后在xamarin.android项目中,我的渲染器: public class MyExtendedEntryRenderer : EntryRenderer { protected override void OnElement

在Xamarin.forms便携表单项目中,当聚焦
条目时,如何隐藏显示的软键盘?我假设我们必须为此编写特定于平台的渲染器,但以下操作不起作用:

我创建自己的entry子类:

public class MyExtendedEntry : Entry
{
}
然后在xamarin.android项目中,我的渲染器:

public class MyExtendedEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            new Handler().Post(delegate
            {
                var imm = (InputMethodManager)Control.Context.GetSystemService(Context.InputMethodService);
                var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);
            });
        }
    }
}
公共类MyExtendedEntryRenderer:EntryRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(控件!=null)
{
新建处理程序().Post(委托
{
var imm=(InputMethodManager)Control.Context.GetSystemService(Context.InputMethodService);
var result=imm.HideSoftInputFromWindow(Control.WindowToken,0);
});
}
}
}

OnElementChanged
按预期调用,并且在使用
Handler.Post()时,我也会得到一个WindowToken,而不是null。遗憾的是,
HideSoftInputFromWindow
的返回值始终为false,并且在单击条目时软键盘仍会出现。

OnElementChanged
在初始化视图并将其附加到视图时被调用。您要做的是在单击条目时隐藏键盘,因此应将事件处理程序添加到
FocusChange
控件中

示例:

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            Control.Click += (sender, evt) => {
                new Handler().Post(delegate
                    {
                        var imm = (InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
                        var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);

                        Console.WriteLine(result);
                    });
            };

            Control.FocusChange += (sender, evt) => {
                new Handler().Post(delegate
                    {
                        var imm = (InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
                        var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);

                        Console.WriteLine(result);
                    });
            };
        }
    }
protected override void OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(控件!=null)
{
控件。单击+=(发送方,evt)=>{
新建处理程序().Post(委托
{
var imm=(InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
var result=imm.HideSoftInputFromWindow(Control.WindowToken,0);
控制台写入线(结果);
});
};
Control.FocusChange+=(发送方,evt)=>{
新建处理程序().Post(委托
{
var imm=(InputMethodManager)Control.Context.GetSystemService(Android.Content.Context.InputMethodService);
var result=imm.HideSoftInputFromWindow(Control.WindowToken,0);
控制台写入线(结果);
});
};
}
}
更新:来自@Vikram的综合答案


更新:添加了
单击事件处理程序
注意:我不精通Xamarin

根据我的经验,在控件接收焦点后立即使用
imm.HideSoftInputFromWindow(Control.WindowToken,0)
会产生不可靠的结果,即使使用
Post
。我成功地使用了
PostDelayed
。我使用的延迟是500毫秒

尝试一下:

public class MyExtendedEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            new Handler().PostDelayed(delegate
            {
                var imm = (InputMethodManager)Control.Context.GetSystemService(Context.InputMethodService);
                var result = imm.HideSoftInputFromWindow(Control.WindowToken, 0);
            }, 500L);
        }
    }
}
公共类MyExtendedEntryRenderer:EntryRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(控件!=null)
{
新处理程序().PostDelayed(委托
{
var imm=(InputMethodManager)Control.Context.GetSystemService(Context.InputMethodService);
var result=imm.HideSoftInputFromWindow(Control.WindowToken,0);
},500L);
}
}
}

防止虚拟键盘出现的关键是覆盖Focus()输入方法,而不是调用base方法。否则,无论你做什么,它总是偶尔出现。这还具有简化所需代码的额外好处,因为您可以自动控制虚拟键盘的外观和消失。到目前为止,我还没有发现这种方法的任何负面影响

我创建了一个示例控件,可以完全控制虚拟键盘和一个显示使用情况的小应用程序

由于这个问题是在几个论坛上提出的,我决定写一个详细的自述文件附在项目上,解释实现的所有关键点,而不是在几个不同的论坛上重复解释。我希望没问题。如果没有,请告诉我

整个项目可在以下位置获得:

遗憾的是,
result
仍然是false,并且显示了键盘。我发现如果用户第二次单击它,焦点没有改变,因此我还添加了
Click
事件处理程序。我试了试我的Note 3,它工作了,并且返回了
True
。显示然后隐藏键盘是不好的。有什么办法防止它在进入焦点时显示吗?光标没有显示(即使在聚焦时)。选择将其添加回
Control.SetSelection(0)
@Vikram这将在显示键盘后立即隐藏键盘,这并不好。有没有办法防止它完全显示在入门级焦点上?