Xamarin.Forms点击页面任意位置为何自动聚焦第一个Entry控件
问题现象
在Xamarin.Forms的ContentPage页面中放置多个Entry控件时,运行后出现异常交互:点击页面任意位置,焦点都会自动定位到第一个Entry控件。
问题效果演示:
可复现问题的页面代码如下:
<ContentPage.Content> <StackLayout> <Label Text="Welcome to Xamarin.Forms!" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" /> <Entry /> <Entry /> <Entry /> <Entry /> <Entry /> <Entry /> <Label Text="test" /> <Entry /> <Entry /> <Entry /> <Label Text="test2" /> </StackLayout> </ContentPage.Content>
问题原因
这个是Xamarin.Forms安卓端的已知行为:如果页面根布局没有设置背景,安卓系统会判定该布局无法消费触摸事件,未被控件拦截的点击事件会向上抛给系统输入管理模块,模块会自动遍历视图树找到第一个可输入的控件(也就是第一个Entry),强制给它分配焦点唤起软键盘。
解决方案
任选一种方案即可修复:
- 方案1(单页面最简修复):给根布局(本例中是
StackLayout)设置透明背景,让布局具备触摸事件消费能力:
<StackLayout BackgroundColor="Transparent"> <!-- 原有页面内容保持不变 --> </StackLayout>
- 方案2(全局修复):在安卓项目的
MainActivity.cs中重写触摸事件分发逻辑,拦截未被消费的触摸事件,阻止系统自动抢焦点:
public override bool DispatchTouchEvent(MotionEvent ev) { if (ev.Action == MotionEventActions.Down) { var currentFocus = CurrentFocus; if (currentFocus is EditText editText) { var outRect = new Rect(); editText.GetGlobalVisibleRect(outRect); if (!outRect.Contains((int)ev.RawX, (int)ev.RawY)) { editText.ClearFocus(); InputMethodManager imm = (InputMethodManager)GetSystemService(InputMethodService); imm.HideSoftInputFromWindow(editText.WindowToken, 0); } } } return base.DispatchTouchEvent(ev); }
- 方案3(单页面手势拦截):给页面根布局添加点击手势,点击空白区域时主动清空输入控件焦点:
// 在页面构造函数中添加以下代码 var tapRecognizer = new TapGestureRecognizer(); tapRecognizer.Tapped += (s, e) => { foreach (var entry in ((StackLayout)Content).Children.OfType<Entry>()) { entry.Unfocus(); } }; ((StackLayout)Content).GestureRecognizers.Add(tapRecognizer);
内容的提问来源于stack exchange,提问作者jary dst
相关产品推荐
相关产品推荐

