【发布时间】:2015-08-06 21:02:34
【问题描述】:
经过大量搜索,我找到了一种在 Xamarin Forms 中按下按钮时隐藏键盘的方法,适用于 iOS 案例。所以在下面分享。
如果有人可以改进它,或者为 Android 端分享一个解决方案,那就太好了。
【问题讨论】:
经过大量搜索,我找到了一种在 Xamarin Forms 中按下按钮时隐藏键盘的方法,适用于 iOS 案例。所以在下面分享。
如果有人可以改进它,或者为 Android 端分享一个解决方案,那就太好了。
【问题讨论】:
在shared/PCL项目中,添加:
using System;
using Xamarin.Forms;
namespace MyApp.Views
{
public class ButtonKeyboardHiding : Button {}
}
在表单中使用此类代替 Button。
在iOS项目中,添加:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using Foundation;
using UIKit;
using MyApp.Views;
using MyApp.iOS;
[assembly: ExportRenderer ( typeof (ButtonKeyboardHiding), typeof (ButtonKeyboardHidingRenderer ) ) ]
namespace MyApp.iOS
{
public class ButtonKeyboardHidingRenderer : ButtonRenderer
{
protected override void OnElementChanged ( ElementChangedEventArgs<Button> e )
{
base.OnElementChanged (e );
if ( Control != null )
{
Control.TouchUpInside += ( sender, el ) =>
{
UIView ctl = Control;
while ( true )
{
ctl = ctl.Superview;
if ( ctl.Description.Contains ( "UIView" ) )
break;
}
ctl.EndEditing ( true );
};
}
}
}
}
【讨论】:
这是我为 Android 端隐藏虚拟键盘的解决方案。
我编写了一个具有 HideKeyboard() 方法的 IKeyboardInteractions 接口。然后我在 MyProject.Droid 中声明一个实现 IKeyboardInteractions 的 KeyboardInteractions 类:
通用代码:
public interface IKeyboardInteractions {
void HideKeyboard();
}
MyProject.Droid 代码:
[assembly: Dependency (typeof (KeyboardInteractions))] namespace MyProject.Droid
{
public class KeyboardInteractions : IKeyboardInteractions
{
public void HideKeyboard()
{
var inputMethodManager = Xamarin.Forms.Forms.Context.GetSystemService(Context.InputMethodService) as InputMethodManager;
if (inputMethodManager != null && Xamarin.Forms.Forms.Context is Activity)
{
var activity = Xamarin.Forms.Forms.Context as Activity;
var token = activity.CurrentFocus == null ? null : activity.CurrentFocus.WindowToken;
inputMethodManager.HideSoftInputFromWindow(token, 0);
}
}
}
}
消费方式:
IKeyboardInteractions keyboardInteractions = DependencyService.Get<IKeyboardInteractions>();
keyboardInteractions.HideKeyboard ();
【讨论】:
Xamarin.Forms.Forms.Context 自 XF 2.5 起已弃用。 Android.App.Application.Context 似乎是错误的上下文。你现在用哪一个?
我发现这很有用:
https://forums.xamarin.com/discussion/comment/172077#Comment_172077
界面:
public interface IKeyboardHelper
{
void HideKeyboard();
}
iOS:
public class iOSKeyboardHelper : IKeyboardHelper
{
public void HideKeyboard()
{
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
}
}
机器人:
public class DroidKeyboardHelper : IKeyboardHelper
{
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();
}
}
}
在 Xamarin 表单中的用法:
DependencyService.Get<IKeyboardHelper>().HideKeyboard();
【讨论】:
这里是 F. Badili 解决方案的更新版本,它基于 Xamarin Forms 2.5 中的弃用更改。唯一的区别是如何在 Android 类中访问 Context。
在 Xamarin Forms 项目中:
public interface IKeyboardHelper
{
void HideKeyboard();
}
在 iOS 项目中:
using System;
using Xamarin.Forms;
using ProjectName;
using ProjectName.iOS;
using UIKit;
[assembly: Dependency(typeof(iOSKeyboardHelper))]
namespace ProjectName.iOS
{
public class iOSKeyboardHelper : IKeyboardHelper
{
public void HideKeyboard()
{
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
}
}
}
在 Droid 项目中:
using System;
using Xamarin.Forms;
using ProjectName;
using ProjectName.Droid;
using Xamarin.Forms.Platform.Android;
using Android.Views.InputMethods;
using Android.App;
using Android.Content;
[assembly: Xamarin.Forms.Dependency(typeof(DroidKeyboardHelper))]
namespace ProjectName.Droid
{
public class DroidKeyboardHelper : IKeyboardHelper
{
public void HideKeyboard()
{
var context = Android.App.Application.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();
}
}
}
}
在 Xamarin 表单 页面中:
DependencyService.Get<IKeyboardHelper>().HideKeyboard();
【讨论】:
即使使用 Kenan Casey 的更新,我也无法让 F. Badili 的 Android 解决方案正常工作。进一步谷歌搜索将我带到Dave's Tech Blog 关于Xamarin.Forms.Forms.Context 的弃用。它说Android.App.Application.Context 不是也不能转换为Activty(至少在我的情况下,请参阅博客文章的 cmets 以获得解释)。
在 Droid 项目中:
[assembly: Xamarin.Forms.Dependency(typeof(DroidKeyboardHelper))]
namespace ProjectName.Droid{
public class DroidKeyboardHelper : IKeyboardHelper {
static Context _context;
public static void Init(Context context) => _context = context;
public void HideKeyboard(){
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();
}
}
}
}
在Droid MainActivity.cs中:
protected override void OnCreate(Bundle savedInstanceState){
base.OnCreate(savedInstanceState);
...
KeyboardHelper.Init(this);
...
LoadApplication(new App());
}
注意:
这仅在您的应用仅在单个 Activity 上运行时才有效。如果在任何情况下您的应用程序有多个活动,请参阅Dave's Tech Blog 以获取适合您情况的正确实施。
【讨论】:
view.Unfocus();
就是这样。
有些人报告说这不起作用,但对我来说它就像大炮一样。
【讨论】:
如果在经过大量搜索后移除焦点方法对您不起作用(并且对我不起作用),我意识到一种强制关闭键盘的简单方法。
FindViewById<EditText>(Resource.Id.edittextname).Enabled = false;
FindViewById<EditText>(Resource.Id.edittextname).Enabled = true;
就是这样。只需禁用并启用它,它就会关闭键盘。
【讨论】:
MyEntry.IsEnabled=false 比MyEntry.UnFocus() 效果更好。
UIApplication.SharedApplication.KeyWindow.EndEditing(true); 和 View.UnFocus 效果更好
Forms9Patch 具有良好的工作实现。
所以只需使用整个库 (https://github.com/baskren/Forms9Patch) 或使用来自 Github 存储库 (KeyboardService.cs) 的代码。
那么使用它就很容易了:
Forms9Patch.KeyboardService.Hide();
适用于 Android、iOS 和 UWP。
【讨论】:
Xamarin Forms 4.8 背后的代码中的简单解决方案。订阅TextChanged事件,即Editor或Entry,然后查看后面代码中的key。 Le Mot Juiced 回答时,UnFocused() 将关闭键盘。我的示例在按下回车键后关闭键盘,但您可以将另一个键应用于条件。
XAML
<Editor TextChanged="Input_TextChanged"></Editor>
背后的代码
private void Input_TextChanged(object sender, TextChangedEventArgs e)
{
char key = string.IsNullOrEmpty(e.NewTextValue) ? ' ' : e.NewTextValue.Last();
if (key == '\n')
{
var s = (Editor)sender;
s.Text = e.OldTextValue ?? string.Empty;
s.Unfocus();
}
}
【讨论】:
我遇到了一个问题,即适用于 Android 的 TapGestureRecognizer 的键盘没有关闭。为了解决这个问题,我不得不用一个按钮替换 Span。下面注释掉的代码在关闭键盘方面对我不起作用。在 Android 中单击按钮时键盘会自动关闭。
<Button VerticalOptions="Center" Text="Login" Command="{Binding LoginCommand}"/>
<!--
<StackLayout Grid.Row="2" Padding="20">
<Label HorizontalOptions="Center">
<Label.FormattedText>
<FormattedString>
<Span Text="Login" TextColor="Blue">
<Span.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginCommand}"/>
</Span.GestureRecognizers>
</Span>
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
-->
【讨论】:
UnFocus() 对我有用,但有一些注意事项。
我有两个页面:EditPage 有一个 Entry 控件,当获得焦点时,它会显示键盘。 ListPage 没有 Entry 字段。 当 EditPage 被显示并且 Entry 聚焦时,键盘被显示。如果我现在导航到 ListPage,键盘仍然显示。
为了解决,我尝试了这些:
1.) 在 ListPage.OnAppearing() 中,我添加了对 Unfocus() 的调用。
愚蠢,因为此时没有任何重点,但如果这是隐藏键盘的方式,值得一试。此外,无论我们来自何处,此页面都应负责显示或隐藏键盘。
没用。
2.) 在 EditPage.OnDisappearing() 中,我像这样添加了 Unfocus():
protected override void OnDisappearing()
{
Unfocus();
base.OnDisappearing();
}
这行得通。
【讨论】:
您可以为输入字段命名。例如Entryfield1 和EntryField2 是显示键盘的条目。然后用OnDisappearing 覆盖页面事件,如下所示:
protected override void OnDisappearing()
{
Entryfield1.Unfocus();
EntryField2.Unfocus();
base.OnDisappearing();
}
【讨论】: