Xamarin.Forms如何不触发软键盘给Entry重设焦点并将光标置零
Xamarin.Forms扫码后Entry无键盘回焦解决方案
核心实现逻辑
通过自定义Entry控件标记焦点触发来源,配合平台渲染器区分用户手动点击和代码自动触发的焦点,仅在手动点击时允许软键盘弹出。
步骤1:创建自定义Entry控件
共享项目中新增自定义Entry类,新增属性标记焦点触发类型:
public class NoAutoKeyboardEntry : Entry { // 标记当前焦点是否由用户手动点击触发 public bool IsManuallyFocused { get; set; } }
步骤2:页面中注册回车事件
页面XAML中使用自定义Entry,绑定回车完成事件:
<local:NoAutoKeyboardEntry x:Name="ScanEntry" Completed="ScanEntry_Completed" Placeholder="扫码输入区"/>
页面后台实现Completed事件逻辑:
private void ScanEntry_Completed(object sender, EventArgs e) { // 标记本次为代码自动触发焦点,禁止弹出软键盘 ScanEntry.IsManuallyFocused = false; // 刷新焦点状态 ScanEntry.Unfocus(); ScanEntry.Focus(); // 设置光标到输入框最左端 ScanEntry.CursorPosition = 0; }
步骤3:Android平台自定义渲染器
Android项目中新增渲染器实现键盘控制逻辑:
[assembly: ExportRenderer(typeof(NoAutoKeyboardEntry), typeof(NoAutoKeyboardEntryRenderer))] namespace 你的项目命名空间.Droid.Renderers { public class NoAutoKeyboardEntryRenderer : EntryRenderer { public NoAutoKeyboardEntryRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) { base.OnElementChanged(e); if (Control == null || e.NewElement == null) return; var customEntry = (NoAutoKeyboardEntry)e.NewElement; // 监听手动点击事件,标记为用户触发焦点 Control.Touch += (s, args) => { if (args.Event.Action == MotionEventActions.Down) { customEntry.IsManuallyFocused = true; } }; // 焦点变化时控制软键盘状态 Control.FocusChange += (s, args) => { if (!args.HasFocus) return; if (!customEntry.IsManuallyFocused) { // 代码触发焦点时隐藏软键盘 var imm = (InputMethodManager)Context.GetSystemService(Context.InputMethodService); imm.HideSoftInputFromWindow(Control.WindowToken, 0); } }; } } }
步骤4:iOS平台自定义渲染器
iOS项目中新增渲染器实现键盘控制逻辑:
[assembly: ExportRenderer(typeof(NoAutoKeyboardEntry), typeof(NoAutoKeyboardEntryRenderer))] namespace 你的项目命名空间.iOS.Renderers { public class NoAutoKeyboardEntryRenderer : EntryRenderer { public override bool BecomeFirstResponder() { var customEntry = (NoAutoKeyboardEntry)Element; // 代码触发焦点时不弹出键盘 if (!customEntry.IsManuallyFocused) { return false; } return base.BecomeFirstResponder(); } protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) { base.OnElementChanged(e); if (Control == null || e.NewElement == null) return; var customEntry = (NoAutoKeyboardEntry)e.NewElement; // 监听手动编辑事件,标记为用户触发焦点 Control.ShouldBeginEditing += (textField) => { customEntry.IsManuallyFocused = true; return true; }; // 代码触发焦点时强制设置光标到开头 Control.EditingDidBegin += (s, args) => { if (!customEntry.IsManuallyFocused) { Control.SelectedTextRange = Control.GetTextRange(Control.BeginningOfDocument, Control.BeginningOfDocument); } }; } } }
注意事项
- 替换代码中
你的项目命名空间为实际项目的对应命名空间即可正常使用 - 硬件扫码枪默认模拟外接键盘输入,无需额外适配即可兼容该方案
- 如需支持UWP平台,可按照相同逻辑实现对应平台渲染器,核心规则都是区分焦点触发来源控制键盘弹出逻辑
内容的提问来源于stack exchange,提问作者Shibit
相关产品推荐
相关产品推荐

