2015-01-16 1 views
4

Мы пытаемся создать приложение чата с использованием Xamarin Forms, но мы продолжаем получать эту неприятную ошибку с клавиатуры Android. Всякий раз, когда нажата кнопка «Отправить», фокус на записи (текстовое поле для общения) теряется, и клавиатура исчезает. Это не то, что мы хотели, чтобы мы добавили эту строку в TapGestureRecognizer:Клавиатура быстро скрывается и появляется на Android с помощью Xamarin Forms

messageEntry.Focus(); 

Но по какой-то причине этого не происходит достаточно быстро, и часто клавиатура идет вниз и сразу же снова. Это не позволяет пользователям быстро отправлять несколько сообщений последовательно. Кто-нибудь знает, как это можно исправить?

+0

Вы когда-нибудь понять это? У меня такая же проблема –

+0

Никогда, возможно, это невозможно, используя API-интерфейс платформы. – gerwin

ответ

1

Благодаря ответ @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; 
+0

Не могли бы вы предоставить полный код? – Polyariz

0

Было бы немного рубить, но вы могли бы закрутить задачу асинхронной, что ждет 50мс и затем вызывающую строку messageEntry.Focus() на главном потоке UI ...