如何在Xamarin Forms中按下按钮上的键盘

时间:2015-05-25 11:30:18

标签: keyboard xamarin.forms

经过多次狩猎后,我找到了一种方法,可以在Xamarin Forms的按钮上隐藏键盘,适用于iOS机箱。所以它在下面分享。

如果有人可以改进它,或者为Android方共享解决方案,那就太棒了。

10 个答案:

答案 0 :(得分:15)

我觉得这很有用:

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();

答案 1 :(得分:7)

 view.Unfocus();

就是这样。

有人报告这行不通,但对我来说却像大爆炸一样。

答案 2 :(得分:5)

这是我隐藏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 ();

答案 3 :(得分:2)

在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 );
                };
            }
        }
    }
}

答案 4 :(得分:2)

这是基于Xamarin Forms 2.5中弃用变更的F. Badili解决方案的更新版本。唯一的区别是如何在Android类中访问Context。

Xamarin表单项目中:

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();

答案 5 :(得分:2)

如果经过大量搜索后,removeing focus方法对您不起作用(并且对我不起作用),我便意识到可以强制关闭键盘的简便方法。

FindViewById<EditText>(Resource.Id.edittextname).Enabled = false;
FindViewById<EditText>(Resource.Id.edittextname).Enabled = true;

就是这样。只需禁用并启用它,它将关闭键盘。

答案 6 :(得分:0)

即使使用Kenan Casey的更新,我也无法获得F. Badili的Android解决方案。进一步的谷歌搜索使我着眼于Xamarin.Forms.Forms.Context的弃用。它说Android.App.Application.Context不是,也不能转换为Activty(至少就我而言,请参阅博客文章的注释以获取解释)。

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());
}
  

注意

     
    

这仅在您的应用仅在单个活动上运行时才有效。无论如何,如果您的应用有多个活动,请参考Dave's Tech Blog,以获取适合您情况的正确实施方式。

  

答案 7 :(得分:0)

Forms9Patch具有良好的工作实现。

因此,只需使用整个库(https://github.com/baskren/Forms9Patch)或使用Github存储库(KeyboardService.cs)中的代码即可。

使用它非常容易:

Forms9Patch.KeyboardService.Hide();

适用于Android,iOS和UWP。

答案 8 :(得分:0)

Xamarin Forms 4.8背后的代码中的简单解决方案。订阅TextChanged事件,即“编辑器”或“条目”,然后检查后面代码中的键。正如 Le Mot Juiced 的回答,UnFocused()将关闭键盘。我的示例在按下Enter键后关闭了键盘,但是您可以将另一个键应用于条件。

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();
        }
    }

答案 9 :(得分:0)

我遇到了一个问题,即针对 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>
            -->