隐藏

c#开发Xamarin.Android时如何快速隐藏和重新出现键盘

发布:2022/12/22 10:43:34作者:管理员 来源:本站 浏览次数:687

我们正在尝试使用 Xamarin Forms 构建一个聊天应用程序,但我们一直在使用 Android 键盘遇到这个恼人的错误。每当点击“发送”按钮时,条目(用于聊天的文本框)上的焦点就会丢失,键盘也会消失。这不是我们想要的,所以我们将这一行添加到 TapGestureRecognizer:


messageEntry.Focus();


但由于某种原因,这种情况发生的速度不够快,而且键盘经常按下并立即再次弹起。这可以防止用户按顺序快速发布多条消息。有人知道如何解决这个问题吗?


最佳答案


感谢@AdamKemp 在此 post 中的回答,这是我的解决方案。如果触摸在我的 EntryStackLayout 内(不要忘记创建空的自定义渲染器),那么我不会关闭键盘(这就是 DispatchTouchEvent 将执行的操作,如果CurrentFocus 是 EditText)。


public class EditorAndButtonReproPage : ContentPage

   {

       public EditorAndButtonReproPage()

       {

           BackgroundColor = Color.Gray;

           Padding = 50;

           var editor = new Editor {HorizontalOptions = LayoutOptions.FillAndExpand};

           var editorButton = new Button {Text = "OK", HorizontalOptions = LayoutOptions.End};

           var editorLayout = new EntryStackLayout { Orientation = StackOrientation.Horizontal, Children = { editor, editorButton}, VerticalOptions = LayoutOptions.Start};

           var entry = new ExtendedEntry { Placeholder = "Entry", HorizontalOptions = LayoutOptions.FillAndExpand };

           var entryButton = new Button { Text = "OK", HorizontalOptions = LayoutOptions.End };

           var entryLayout = new EntryStackLayout { Orientation = StackOrientation.Horizontal, Children = { entry, entryButton }, VerticalOptions = LayoutOptions.Start };

           Content = new StackLayout {Children = {editorLayout, entryLayout}};

       }

   }


在 MainActivity 中:


private bool _ignoreNewFocus;

       public override bool DispatchTouchEvent(MotionEvent e)

       {

           var currentView = CurrentFocus;

           var parent = currentView?.Parent?.Parent;

           var entryStackLayout = parent as EntryStackLayout;

           if (entryStackLayout != null)

           {

               var entryLayoutLocation = new int[2];

               entryStackLayout.GetLocationOnScreen(entryLayoutLocation);

               var x = e.RawX + entryStackLayout.Left - entryLayoutLocation[0];

               var y = e.RawY + entryStackLayout.Top - entryLayoutLocation[1];

               var entryStackLayoutRect = new Rectangle(entryStackLayout.Left, entryStackLayout.Top, entryStackLayout.Width, entryStackLayout.Height);

               _ignoreNewFocus = entryStackLayoutRect.Contains(x, y);

           }

           var result = base.DispatchTouchEvent(e);

           _ignoreNewFocus = false;

           return result;

       }


       public override Android.Views.View CurrentFocus => _ignoreNewFocus ? null : base.CurrentFocus;