2013-08-12 3 views
3

Я пытаюсь заставить элемент управления EditText потерять фокус, когда пользователь нажимает кнопку «Назад», чтобы скрыть клавиатуру. Есть много вопросов, подобных этому уже, но через несколько часов я не смог заставить его работать.Force EditText потерять фокус при нажатии назад

Во-первых, просто немного контекста. У меня есть ListView с настраиваемыми элементами. Каждый элемент имеет несколько TextView и один EditText. У меня есть метод AfterTextChanged(), сохраняющий отредактированные значения. У меня есть стиль, созданный для выделения поля, если он имеет фокус. К сожалению, теперь гораздо более очевидно, что EditText фактически не теряет фокус, когда вы скрываете (мягкую) клавиатуру, и я думаю, что это запутывает. Я бы хотел, чтобы EditText не фокусировался, если нет клавиатуры.

Решение, которое представляется наиболее разумным, заключается в переопределении OnBackPressed() в операции, как описано here. К сожалению, похоже, что мой метод не вызван. То есть поле все еще сфокусировано, а точка останова в функции не срабатывает.

Аналогично, прослушиватель OnKeyUp() не запускается, а Xamarin не поддерживает обработчик OnKeyUp для элемента управления EditText.

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

Очевидно, что у многих людей есть эта проблема. Я уверен, что один из вас решил это! Можете ли вы поделиться своим решением?

Большое вам спасибо! -Karen

P.S. Мне не нужно знать, как скрыть клавиатуру. Мне нужно принять меры, когда пользователь скрывает клавиатуру с помощью кнопки «Назад». Спасибо :)

+0

Тот факт, что 'onBackPressed()' не называют звучит как отдельный выпуск. И было бы лучше сосредоточиться на этом. – keyser

ответ

7

В моем опыте onBackPressed() (по крайней мере, значение по умолчанию @Override в действии) обычно не срабатывает при нажатии кнопки «Назад», чтобы закрыть клавиатуру. Насколько я знаю, он будет срабатывать только тогда, когда нажимает Back (Назад) для начала финиша() для текущей активности.

Ниже приводится своего рода «хакерский» способ узнать, когда клавиатура отображается/скрыта, контролируя изменение размера изображения. Вы также должны установить значение Activity на android:windowSoftInputMode="adjustResize" в AndroidManifest.xml.

final View activityRootView = findViewById("Your main View"); 
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
     Rect r = new Rect(); 
     //r will be populated with the coordinates of your view that area still visible. 
     activityRootView.getWindowVisibleDisplayFrame(r); 

     int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top); 
     if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard... 
      //Keyboard is shown 


     } 
     if(heightDiff <= 100) { 
      //Keybaord not shown 
     } 
    } 
    }); 
+0

СПАСИБО ВАС !!!! С некоторыми подсказками для переводов Xamarin от https://github.com/xamarin/monodroid-samples/blob/master/GooglePlayServices/GooglePlayServicesTest/Source/MarkerDemoActivity.cs#L164 я смог заставить его работать. Я выложу последний код ниже, потому что он не хочет меня здесь. –

2

С искренним благодаря @Shadesblade (и примеры кода Xamarin в), мои EditTexts Теперь unfocus! Вот Xamarin-роскопия решения:

Для вашей деятельности, добавить этот класс:

class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener 
{ 
    Action on_global_layout; 
    public GlobalLayoutListener (Action onGlobalLayout) 
    { 
     on_global_layout = onGlobalLayout; 
    } 

    public void OnGlobalLayout() 
    { 
     on_global_layout(); 
    } 
} 

Добавить переменный класс для хранения View, так что делегат может получить доступ к нему:

View _rootview; 

В ваш OnCreate() add:

GlobalLayoutListener gll = new GlobalLayoutListener(
    delegate { 
     Android.Graphics.Rect r = new Android.Graphics.Rect(); 
     _rootView.GetWindowVisibleDisplayFrame(r); 
     int heightDiff = _rootView.RootView.Height - (r.Bottom - r.Top); 
     if (heightDiff < 100) 
     { 
      if (Window.CurrentFocus != null) 
       Window.CurrentFocus.ClearFocus(); 
     } 
    }); 

_rootView = FindViewById<View>(Resource.Id.relativeLayoutOrder); 
_rootView.ViewTreeObserver.AddOnGlobalLayoutListener(gll); 

Я ожидаю, что вам придется крутиться с высотой уровня шума и/или нужно добавить некоторую проверку вращения, но на данный момент я не выполнял никакой поддержки вращения, поэтому я могу использовать ее до конца.

Еще раз спасибо!* счастливый танец *

0

добавление к ответу Shadesblade, в если вы используете Scrollview, его ответ требует изменения в работу, потому что не все Scrollview показывает на экране. так вместо того, чтобы делать

int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top); 

вы должны сделать

int heightDiff = Utils.getScreenHeight(SearchActivity.this) - (r.bottom - r.top); 

где Utils.getScreenHeight это:

public static int getScreenHeight(Context c) { 
    if (screenHeight == 0) { 
     WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); 
     Display display = wm.getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 
     screenHeight = size.y; 
     screenWidth = size.x; 
    } 
    return screenHeight; 
} 
Смежные вопросы