Android 7 (Nougat): все мои виртуальные клавиатуры отсутствуют — не могу найти, как переустановить

Недавно все мои виртуальные клавиатуры исчезли. Всякий раз, когда я открываю какое-либо приложение, требующее ввода с клавиатуры, я получаю только голосовой ввод. Если я коснусь «X», чтобы закрыть голосовой ввод, ничего не произойдет. Если я выберу язык и клавиатуру, а затем виртуальную клавиатуру, все, что у нее есть, — это голосовой ввод Google.

Единственное, что «подозрительно» — это то, что я недавно прошел обновление системы. Я не знаю, вызвало ли это конкретно мою проблему, но до обновления казалось, что у меня была клавиатура. Я просто не уделил достаточно внимания обновлению, чтобы определить его как проблему.

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

Есть ли способ переустановить «виртуальную клавиатуру по умолчанию»?


Вы стерли кеш/сброс настроек после обновления? Возможно, проверьте язык и введите в настройках заводская виртуальная клавиатура устройства.

Ответ: Я не хочу выполнять сброс настроек до заводских. Я добавил много приложений и настроил «внешний вид» и не хочу делать это снова и снова. Клавиатура после всего этого заработала. Я надеюсь на другое решение.

3


Недавно у меня был та же проблема. Я решил это, удалив обновления GBoard и снова обновив GBoard.

1



Мягкая клавиатура открывает и закрывает слушателя в действии в Android

У меня есть Activity , где есть 5 EditText . Когда пользователь нажимает на первый EditText , открывается программная клавиатура для ввода в нее некоторого значения. Я хочу установить для некоторых других View видимость Gone , когда открывается программная клавиатура, а также когда пользователь нажимает на первый EditText , а также при закрытии программной клавиатуры из того же EditText при нажатии кнопки возврата. Затем я хочу установить видимость некоторого другого View на видимый.

Есть ли какой-либо прослушиватель, обратный вызов или какой-либо хак, когда программная клавиатура открывается по щелчку на первом EditText в Android?


Это работает, только когда android: windowSoftInputMode вашего действия установите в манифесте значение adjustResize . Вы можете использовать прослушиватель макета, чтобы увидеть, изменен ли размер корневого макета вашего действия с помощью клавиатуры.

Я использую что-то вроде следующего базового класса для своих действий:

  открытый класс BaseActivity расширяет Activity {частный ViewTreeObserver. OnGlobalLayoutListener keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {int heightDiff = rootLayout.getRootView (). GetHeight () - rootLayout.getHeight ();  int contentViewTop = getWindow (). findViewById (Window.ID_ANDROID_CONTENT) .getTop ();  LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance (BaseActivity.this);  если (heightDiff  

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

Макет xml:

   Xml version = "1.0" encoding = "utf-8"?>         

И действие:

  открытый класс TestActivity расширяет BaseActivity {@Override protected void onCreate (Bundle savedInstanceState) {super.  onCreate (savedInstanceState);  setContentView (R.layout.test_activity);  attachKeyboardListeners ();  } @Override protected void onShowKeyboard (int keyboardHeight) {//что-то делать, когда отображается клавиатура bottomContainer.setVisibility (View.GONE);  } @Override protected void onHideKeyboard () {//делаем что-то, когда клавиатура скрыта bottomContainer.setVisibility (View. ВИДИМЫЙ);  }}  

Кусок торта с библиотекой awesomeKeyboardVisibilityEvent

  KeyboardVisibilityEvent.setEventListener (getActivity (), new KeyboardVisibilityEventListener () {@Override public void onVisibilityChanged (boolean isOpen) {//Ах ... наконец-то. делай свое дело :)}});  

Кредиты для Ясухиро ШИМИЗУ

10


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

Может быть, этого достаточно, чтобы установить прослушиватель фокуса на текст редактирования :

  yourEditText.setOnFocusChangeListener (new OnFocusChangeListener () {@Overridepublic void onFocusChange (View v, boolean hasFocus  ) {if (hasFocus) {//получил фокус} else {//потерял фокус}}});  

8


Для действия:

  final View activityRootView = findViewById (R.id.activityRoot); activityRootView  .getViewTreeObserver (). addOnGlobalLayoutListener (новый ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {Rect r = new Rect ();  activityRootView.getWindowVisibleDisplayFrame (r);  int heightDiff = view.getRootView (). getHeight () - (r.bottom - r.top);  if (heightDiff> 100) {//введите здесь свой код} else {//введите код для hid}}});  

Для фрагмента:

  view = inflater.inflate (R.layout.live_chat_fragment, null); view.getViewTreeObserver (). addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayoutListener () {@Override public void onGlobalLayout = new  ();//r будет заполнено координатами вашего представления, которое все еще отображается view.getWindowVisibleDisplayFrame (r); int heightDiff = view.getRootView (). getHeight () - (r.bottom - r.top);  if (heightDiff> 500) {//если больше 100 пикселей, вероятно, это клавиатура ...}}});  

5


Ответ Jaap не будет работать для AppCompatActivity. Вместо этого получите высоту строки состояния, панели навигации и т. Д. И сравните с размером окна вашего приложения.

Вот так:

  private ViewTreeObserver.OnGlobalLayoutListener  keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {//высота панели навигации int navigationBarHeight = 0;  int resourceId = getResources (). getIdentifier ("navigation_bar_height", "dimen", "android");  если (resourceId> 0) {navigationBarHeight = getResources (). getDimensionPixelSize (resourceId);  }//высота строки состояния int statusBarHeight = 0;  resourceId = getResources (). getIdentifier ("status_bar_height", "dimen", "android");  если (resourceId> 0) {statusBarHeight = getResources (). getDimensionPixelSize (resourceId);  }//отображаем размер окна для макета приложения Rect rect = new Rect ();  getWindow (). getDecorView (). getWindowVisibleDisplayFrame (прямоугольник); //высота экрана - (высота пользовательского приложения + статус + навигация) ..... если отличное от нуля, то есть мягкая клавиатура int keyboardHeight = rootLayout.getRootView (). getHeight () - (statusBarHeight + navigationBarHeight + rect.  высота());  если (keyboardHeight  

1


Можете попробовать:

  private void initKeyBoardListener () {//Минимальное значение клавиатуры. //Порог минимальной высоты клавиатуры.  финальный int MIN_KEYBOARD_HEIGHT_PX = 150; //Окно верхнего уровня вид. //Вид оформления окна верхнего уровня.  окончательный вид decorView = getWindow (). getDecorView (); //Регистрируем глобальный слушатель.  Зарегистрируйте прослушиватель глобального макета.  decorView.getViewTreeObserver (). addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener () {//Видимый прямоугольник внутри окна.//Извлекает видимый прямоугольник внутри окна. private final Rect windowVisibleDisplayFrame = new Rect (); @ private int lastHlobalDevice;  ) {decorView.getWindowVisibleDisplayFrame (windowVisibleDisplayFrame); final int visibleDecorViewHeight = windowVisibleDisplayFrame.height (); if (lastVisibleDecorViewHeight! = 0) {if (lastVisibleDecorView_Height, "PasteVisibleDecorView_Height," Pastoreview_DecorView_Height> visibleDecorViewHeight + MINI  else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX  

1


Приведенный ниже код работает для меня,

mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {if (mainLayout height.  () .getHeight () - mainLayout.getHeight ();  if (heightDiff> dpToPx (getActivity (), 200)) {//клавиатура открыта} else {//клавиатура скрыта}}}});  

1


Вы можете использовать мою функцию расширения Rx (Kotlin).

 /** * @return [Observable], чтобы подписаться на изменения видимости клавиатуры.  */fun AppCompatActivity.keyboardVisibilityChanges (): Observable  {//флаг показывает, открыта ли клавиатура var isKeyboardOpen = false val notifier: BehaviorSubject  = BehaviorSubject.create ()//приблизительная высота клавиатуры val ApproximateKeyboardHeight = dip (100  )//высота экрана устройства val screenHeight: Int = getScreenHeight () val visibleDisplayFrame = Rect () val viewTreeObserver = window.decorView.viewTreeObserver val onDrawListener = ViewTreeObserver.OnDrawListener {window.decorView.getWindowVrameisibleDis visible  .bottom - visibleDisplayFrame.top) val keyboardOpen = keyboardHeight> = ApproximateKeyboardHeight val hasChanged = isKeyboardOpen xor keyboardOpen if (hasChanged) {isKeyboardOpen = keyboardOpen notifier.onNext (keyboardOpen)}} val lifeCycleOpensercycleStreamStation_Open = object: GenericLifeCycleOpenCycleClearver = объект:  , событие: Lifecycle.Event?) {if (source.life  cycle.currentState == Lifecycle.State.DESTROYED) {viewTreeObserver.removeOnDrawListener (onDrawListener) source.lifecycle.removeObserver (this) notifier.onComplete ()}}} viewTreeObserver.addOnDrawDrawListener (onDrawObserver.addOnDrawDrawListener (onDrawListener)  {viewTreeObserver.removeOnDrawListener (onDrawListener) lifecycle.removeObserver (lifeCycleObserver)} .onTerminateDetach () .hide ()}  

Пример:

  (контекст как AppCompatActivity) .keyboardVisibilityChanges () .subscribeBy {isKeyboardOpen ->//ваша логика}  

3


Если можете, попробуйте расширить EditText и переопределить метод onKeyPreIme.

  @Overridepublic void setOnEditorActionListener (последний прослушиватель OnEditorActionListener) {mEditorListener = listener; //сохраняем его для дальнейшего использования super.setOnEditorActionListener (listener);} @ Overridepublic логическое значение onKeyPreIme (final int keyCode, последнее событие KeyEvent) {if (event.getKeyCode () == KeyEvent.KEYCODE_BACK && event.getAction () == KeyEvent  .ACTION_UP) {if (mEditorListener! = Null) {//вы можете определить и использовать собственный прослушиватель,//ИЛИ определить собственный R.id. //ИЛИ проверить event.keyCode в прослушивателе impl//* Я использовал редактор  действие из-за ButterKnife @ mEditorListener.onEditorAction (this, android.R.id.closeButton, событие);  }} return super.onKeyPreIme (keyCode, event);}  

Как вы можете его расширить:

  1. Реализуйте прослушивание onFocus и объявить ‘onKeyboardShown’
  2. объявить ‘onKeyboardHidden’

Я думаю, что пересчет высоты экрана не на 100% успешен, как упоминалось ранее. Чтобы было ясно, переопределение onKeyPreIme не вызывается в методах «скрыть программную клавиатуру программно», НО, если вы делаете это где-нибудь, вы должны выполнять там логику «onKeyboardHidden» и не создавать комплексных решений.


Это будет работать без необходимости изменять вашей активности android: windowSoftInputMode

шаг 1: расширьте класс EditText и переопределите эти два:

  @Overridepublic void setOnEditorActionListener (последний слушатель OnEditorActionListener) {mEditorListener =  слушатель;  super.setOnEditorActionListener (listener);} @ Overridepublic логическое значение onKeyPreIme (final int keyCode, последнее событие KeyEvent) {if (event.getKeyCode () == KeyEvent.KEYCODE_BACK && event.getAction () == KeyEvent.ACTION_UP) {if (mistener  ! = ноль) {mEditorListener.onEditorAction (это, android.R.id.closeButton, событие);  }} return super.onKeyPreIme (keyCode, event);}  

шаг 2: создайте эти два в своей деятельности:

   private void initKeyboard () {окончательный AppEditText editText = findViewById (R.id.some_id);  editText.setOnFocusChangeListener (новый OnFocusChangeListener () {@Override public void onFocusChange (View v, boolean hasFocus) {setKeyboard (hasFocus);}});  editText.setOnEditorActionListener (new TextView.OnEditorActionListener () {@Override общедоступное логическое значение onEditorAction (TextView v, int actionId, событие KeyEvent) {if (event == null || event.getKeyCode () == KeyEvent.KEYCODE_BACK) {  ();} return false;}});} public void setKeyboard (boolean isShowing) {//что-то делаем}  

*** помните, чтобы clearFocus , вы должны сделать родительский или первый дочерний элемент в родительской иерархии доступным для фокусировки.

  setFocusableInTouchMode (true);  setFocusable (true);  

0


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

  implementation 'net.yslibrary  .keyboardvisibilityevent: keyboardvisibilityevent: 3.0.0-RC2 ' 

А затем вы просто используете этот сегмент кода для проверки видимости клавиатуры.

  KeyboardVisibilityEvent.setEventListener (this, new KeyboardVisibilityEventListener () {@Override public void onVisibilityChanged (логическое isOpen) {if (isOpen) Toast.makeText (MainActivity.this, «клавиатура открыта», Toast.LENGTH_SHORT) .show ()  Toast.makeText (MainActivity.this, «клавиатура скрыта», Toast.LENGTH_SHORT). show ();}});  

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

  UIUtil.showKeyboard (это, edittext_to_be_focused);  UIUtil.hideKeyboard (это);  


  открытый класс MainActivity расширяет BaseActivity {@Overrideprotected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState);  setContentView (R.layout.mainactivity);  attachKeyboardListeners ();  .... yourEditText1.setOnFocusChangeListener (новый OnFocusChangeListener () {@Override public void onFocusChange (View v, boolean hasFocus) {if (hasFocus) {yourEditText2.setVisibility (View.GONE); yourEditText4.setVisibility (View.GONE); yourEditText4.  .setVisibility (View.GONE); yourEditText5.setVisibility (View.GONE);} else {yourEditText2.setVisibility (View.VISIBLE); yourEditText3.setVisibility (View.VISIBLE); yourEditText4.setVisibility (View.VISIB)  (ВИДИМО);}}});  }}  

3


Используйте этот класс,

  import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import android.os.Handler; import android.os.Message  ; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; открытый класс SoftKeyboard реализует View.OnFocusChangeListener {private static final int CLEAR_FOCUS = 0; частный макет ViewGroup  ; частный int layoutBottom; частный InputMethodManager im; частный int [] coords; частный логический isKeyboardShow; частный SoftKeyboardChangesThread softKeyboardThread; частный список  editTextList; частный Просмотр tempView; //ссылка на выделенную EditTextpublic SoftKeyboard (макет ViewGroup, InputMethodManager im) {this.layout = layout;  keyboardHideByDefault ();  initEditTexts (макет);  this.im = im;  this.coords = новый int [2];  this.isKeyboardShow = false;  this.softKeyboardThread = новый SoftKeyboardChangesThread ();  this.softKeyboardThread.start ();} public void openSoftKeyboard () {если (! isKeyboardShow) {layoutBottom = getLayoutCoordinates ();  im.toggleSoftInput (0, InputMethodManager.SHOW_IMPLICIT);  softKeyboardThread.keyboardOpened ();  isKeyboardShow = true;  }} public void closeSoftKeyboard () {if (isKeyboardShow) {im.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0);  isKeyboardShow = false;  }} public void setSoftKeyboardCallback (SoftKeyboardChanged mCallback) {softKeyboardThread.setCallback (mCallback);} public void unRegisterSoftKeyboardCallback () {softKeyboardThread.stopThread ();} открытый интерфейс SoftKeyboardChanged {public void onSoft (public void onSoft);  публичная пустота onSoftKeyboardShow ();  } private int getLayoutCoordinates () {макет. getLocationOnScreen (координаты);  return coords [1] + layout.getHeight ();} приватная пустота keyboardHideByDefault () {layout.setFocusable (true);  layout.setFocusableInTouchMode (true);}/* * InitEditTexts теперь обрабатывает EditTexts во вложенных представлениях * Благодаря Francesco Verheye (verheye.francesco@gmail.com) */private void initEditTexts (ViewGroup viewgroup) {if (editTextList == null) editText  = новый список массивов  ();  int childCount = viewgroup.getChildCount ();  for (int i = 0; i  = layoutBottom && start.get ()) {currentBottomLocation = getLayoutCoordinates ();  }//Теперь отображается клавиатура. Продолжайте проверять размеры макета, пока клавиатура не исчезнет while (currentBottomLocation! = LayoutBottom && start.get ()) {synchronized (this) {try {wait (500);  } catch (InterruptedException e) {//TODO Автоматически сгенерированный блок catch e.printStackTrace ();  }} currentBottomLocation = getLayoutCoordinates ();  } если (start.get ()) mCallback.onSoftKeyboardHide (); //если открыта клавиатура, нажмите и EditText.  if (isKeyboardShow && началось. get ()) isKeyboardShow = false; //если EditText сфокусирован, удаляем его фокус (на потоке пользовательского интерфейса) if (start.get ()) mHandler.obtainMessage (CLEAR_FOCUS) .sendToTarget ();  }} public void keyboardOpened () {синхронизировано (это) {notify ();  }} public void stopThread () {синхронизировано (это) {start.set (false);  уведомлять();  }}}}  

В Android Manifest требуется android: windowSoftInputMode = "adjustResize" .

 /* Где-то еще в вашем коде */RelativeLayout mainLayout = findViewById (R.layout.main_layout); //Вы должны использовать макет rootInputMethodManager im = (InputMethodManager) getSystemService (Service.INPUT_METHOD_SERVICE);/* Создать и передать обратный вызов */SoftKeyboard softKeyboard; softKeyboard = new SoftKeyboard (mainLayout, im); softKeyboard (mainLayout, im); softKeyboard (mainLayout, im); softKeyboard (mainLayout, im); softKeyboard  () {@Overridepublic void onSoftKeyboardHide () {//Код здесь} @Overridepublic void onSoftKeyboardShow () {//Код здесь}});/* Легко открывать или закрывать программную клавиатуру */softKeyboard.openSoftKeyboard (); softKeyboard.closeSoftKeyboard  ();/* Предотвращаем утечку памяти: */@ Overridepublic void onDestroy () {super.onDestroy ();  softKeyboard.unRegisterSoftKeyboardCallback ();}  

PS — Полностью взято отсюда.


В случае adjustResize и FragmentActivity принятое решение от @Jaap у меня не работает.

Вот мое решение:

  частный ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener () {private int contentDiff;  частный int rootHeight;  @Override public void onGlobalLayout () {Просмотр contentView = getWindow (). FindViewById (Window.ID_ANDROID_CONTENT);  если (rootHeight! = mDrawerLayout.getRootView (). getHeight ()) {rootHeight = mDrawerLayout.getRootView (). getHeight ();  contentDiff = rootHeight - contentView.getHeight ();  возвращаться;  } int newContentDiff = rootHeight - contentView.getHeight ();  если (contentDiff! = newContentDiff) {если (contentDiff  


Другой подход был бы чтобы проверить, когда пользователь перестал печатать …

Когда TextEdit находится в фокусе (пользователь набирает/набирает), вы можете скрыть представления (прослушиватель фокуса)

и используйте Handler + Runnable и прослушиватель изменения текста, чтобы закрыть клавиатуру (независимо от ее видимости) и отобразить представления после некоторой задержки.

Главное, на что нужно обратить внимание, — это задержка, которую вы использование, которое будет зависеть от содержимого этих TextEdits.

  Обработчик timeoutHandler = new Handler (); Runnable typingRunnable = new Runnable () {public void run () {//текущий TextEdit View view = getCurrentFocus ();  InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); //сбрасываем фокус view.clearFocus (); //закрыть клавиатуру (независимо от того, открыта она или нет) imm.hideSoftInputFromWindow (view.getWindowToken (), InputMethodManager.RESULT_UNCHANGED_SHOWN); //УСТАНОВИТЬ ВИДИМЫЕ ВИДЫ}}; editText.setOnFocusChangeListener (new View.OnFocusChangeListener () {@Override public void onFocusChange (View v, boolean hasFocus) {if (hasFocus) {//SET VIEWS GONE//сбросить обработчик timeoutHandler.remove  typingRunnable); timeoutHandler.postDelayed (typingRunnable, TYPING_TIMEOUT);}}}); editText.addTextChangedListener (новый TextWatcher () {@Override public void beforeTextChanged (CharSequence s, int start, int start, int count, int after)  onTextChanged (CharSequence s, int start, int before, int count) {//Сброс обработчика ... timeoutHandler.removeCallbacks (typingRunnable);} @Override public void afterTextChanged (Editable s) {//Reset Handler Cont. if (editText.  getText (). toString (). trim (). length ()> 0) {timeoutHandler.postDelayed (typingRunnable, TYPING_TIMEOUT);}}});  


Этот код отлично работает красиво

используйте этот класс для корневого представления:

  открытый класс KeyboardConstraintLayout расширяет ConstraintLayout {private KeyboardListener keyboardListener; private EditText targetEditText; private  int minKeyboardHeight; частное логическое isShow; общедоступное KeyboardConstraintLayout (контекст контекста) {супер (контекст);  minKeyboardHeight = getResources (). getDimensionPixelSize (R.dimen.keyboard_min_height); //128dp} public KeyboardConstraintLayout (Контекст контекста, AttributeSet attrs) {super (context, attrs);  minKeyboardHeight = getResources (). getDimensionPixelSize (R.dimen.keyboard_min_height); //128dp} public KeyboardConstraintLayout (Контекст контекста, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr);  minKeyboardHeight = getResources (). getDimensionPixelSize (R.dimen.keyboard_min_height); //128dp} @Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {if (! IsInEditMode ()) {Activity activity = (Activity) getContext ();  @SuppressLint ("DrawAllocation") Rect rect = new Rect ();  getWindowVisibleDisplayFrame (прямоугольник);  int statusBarHeight = rect.top;  int keyboardHeight = activity.getWindowManager (). getDefaultDisplay (). getHeight () - (rect.bottom - rect.top) - statusBarHeight;  if (keyboardListener! = null && targetEditText! = null && targetEditText.isFocused ()) {if (keyboardHeight> minKeyboardHeight) {if (! isShow) {isShow = true;  keyboardListener.onKeyboardVisibility (истина);  }} еще {если (isShow) {isShow = false;  keyboardListener. onKeyboardVisibility (ложь);  }}}} super.onMeasure (widthMeasureSpec, heightMeasureSpec);} public boolean isShowKeyboard () {return isShow;} public void setKeyboardListener (EditText targetEditText, KeyboardListener keyboardListener) {this.targetEditText = targetEditText;  this.keyboardListener = keyboardListener;} общедоступный интерфейс KeyboardListener {void onKeyboardVisibility (boolean isVisible);}  

}

и установить прослушиватель клавиатуры в действии или фрагменте :

  rootLayout.setKeyboardListener (targetEditText, new KeyboardConstraintLayout.KeyboardListener () {@Override public void onKeyboardVisibility (boolean isVisible) {}});  


Вы можете управлять видимостью клавиатуры, переопределив два метода в вашем Activity: onKeyUp () и onKeyDown () дополнительная информация по этой ссылке: https://developer.android.com/training/keyboard-input/commands

1


Для использования в Kotlin внутри фрагмента, который распространенный вариант использования, с которым очень легко Библиотека KeyboardVisibilityEvent .

В build.gradle:

  реализация  'net.yslibrary.keyboardvisibilityevent: keyboardvisibilityevent: 3.0.0-RC2'  

Во фрагменте:

  activity? .let {KeyboardVisibilityEvent.setEventListener (it, object: KeyboardVisibilityEventListener {переопределить удовольствие onVisibilityChanged (isOpen: Boolean) {if (isOpen) Toast.makeText (context, "Keyboard is open", Toast.LENGTH_SHORT) .show  () else Toast.makeText (context, "Keyboard is closed", Toast.LENGTH_SHORT) .show ()}})}  

Источник и кредиты


К сожалению, у меня недостаточно высокой репутации, чтобы комментировать ответ Яапа ван Хенгстума. Но я прочитал несколько комментариев людей, у которых проблема с тем, что contentViewTop всегда 0 и что onShowKeyboard (...) всегда вызывается.

У меня была такая же проблема, и я понял, в чем проблема. Я использовал AppCompatActivity вместо «обычного» Activity . В этом случае Window.ID_ANDROID_CONTENT относится к ContentFrameLayout , а не к FrameLayout с правым верхним значением. В моем случае было нормально использовать «нормальную» Activity , если вам нужно использовать другой тип активности (я только что протестировал AppCompatActivity , возможно, это также проблема с другими типами активности, такими как FragmentActivity ), вам необходимо получить доступ к FrameLayout , который является предком ContentFrameLayout .


при отображении клавиатуры

  rootLayout.getHeight ()  

верно, иначе скрыть


  private boolean isKeyboardShown = false; private int prevContentHeight = 0; private ViewGroup contentLayout; private ViewTreeObserver.OnGlobalLayoutListener keyboar  dLayoutListener = новый ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {int contentHeight = contentLayout.getHeight ();  int rootViewHeight = contentLayout.getRootView (). getHeight ();  if (contentHeight> 0) {if (! isKeyboardShown) {if (contentHeight  prevContentHeight) {isKeyboardShown = false;  onHideKeyboard ();  }} prevContentHeight = contentHeight;  }}};  

Я немного изменил принятый ответ Jaap. Но в моем случае есть несколько предположений, таких как android: windowSoftInputMode = adjustResize , и клавиатура не отображается в начале при запуске приложения. Кроме того, я предполагаю, что экран соответствует высоте родительского элемента.

contentHeight> 0 эта проверка позволяет мне узнать, скрыт или показан соответствующий экран чтобы применить прослушивание событий клавиатуры для этого конкретного экрана. Также я передаю представление макета соответствующего экрана в attachKeyboardListeners () в методе onCreate () моего основного действия. Каждый раз, когда высота соответствующего экрана изменяется, я сохраняю его в переменной prevContentHeight , чтобы позже проверить, отображается ли клавиатура или скрыта.

Для меня так пока что это проработано довольно хорошо. Я надеюсь, что это сработает и для других.


«Яап ван Хенгстум «ответ работает для меня, но нет необходимости устанавливать» android: windowSoftInputMode «, как он только что сказал!

Я уменьшил его (теперь он просто определяет то, что я хочу, фактически событие при отображении и скрытии клавиатуры):

  private ViewTreeObserver. OnGlobalLayoutListener keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {int heightDiff = rootLayout.getRootView (). GetHeight () - rootLayout.getHeight ();  int contentViewTop = getWindow (). findViewById (Window.ID_ANDROID_CONTENT) .getTop ();  если (heightDiff  

и просто не забудьте добавить это

  protected void onCreate (Bundle savedInstanceState) {super.onCreate (  saveInstanceState);  setContentView (R.layout.activity_comments);  attachKeyboardListeners ();}  


Это не работает по желанию …

… видел много вычислений размера для проверки …

Я хотел определить, открыт он или нет, и обнаружил isAcceptingText()

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

в действии

  if (((InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE)). isAcceptingText  ()) {Log.d (ТЕГ, «Показана программная клавиатура»);  } else {Log.d (ТЕГ, «Программная клавиатура не была показана»);  }  

во фрагменте

  if (((InputMethodManager) getActivity (). getSystemService (Context.INPUT_METHOD_SERVICE)). isAcceptingText  ()) {Log.d (ТЕГ, «Показана программная клавиатура»);  } else {Log.d (ТЕГ, «Программная клавиатура не была показана»);  }  


проверьте с помощью приведенного ниже кода:

КОД XML:

   ................. ConstraintLayout>  

КОД JAVA:

 //Глобальная переменнаяandroid.support.constraint.  ConstraintLayout activityRootView; логическое isKeyboardShowing = false; частный ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener; android.support.constraint.ConstraintLayout.LayoutParams layoutParams; //onCreate или onViewAttached activityRootView = view.findViewById (R.id.coordinatorParent);  onGlobalLayoutListener = onGlobalLayoutListener ();  activityRootView.getViewTreeObserver (). addOnGlobalLayoutListener (onGlobalLayoutListener); //вне oncreate ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener () {вернуть новый ViewTreeObserver.OnGlobalLayoutListener () {@Override public void onGlobalLayout () {Rect r = new Rect ();  activityRootView.getWindowVisibleDisplayFrame (r);  int screenHeight = activityRootView.getRootView (). getHeight ();  int keypadHeight = screenHeight - r.bottom;  if (keypadHeight> screenHeight * 0.15) {//0,15, возможно, достаточно для определения высоты клавиатуры.  if (! isKeyboardShowing) {//клавиатура открыта isKeyboardShowing = true;  onKeyboardVisibilityChanged (истина);  }} else {if (isKeyboardShowing) {//клавиатура закрыта isKeyboardShowing = false;  onKeyboardVisibilityChanged (ложь);  }}}//здесь заканчивается};  } void onKeyboardVisibilityChanged (логическое значение) {layoutParams = (android.support.constraint.ConstraintLayout.LayoutParams) topImg.getLayoutParams ();  если (значение) {int length = (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, 90, getResources (). getDisplayMetrics ());  layoutParams.height = длина;  layoutParams.width = длина;  topImg.setLayoutParams (layoutParams);  Log.i ("клавиатура", "" + значение);  } else {int length1 = (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, 175, getResources (). getDisplayMetrics ());  layoutParams.height = length1;  layoutParams.width = length1;  topImg.setLayoutParams (layoutParams);  Log.i ("клавиатура", "" + значение);  }} @Override public void onDetach () {super.onDetach ();  если (onGlobalLayoutListener! = null) {activityRootView.getViewTreeObserver (). removeOnGlobalLayoutListener (onGlobalLayoutListener);  }}  


Есть слушатель, закрытый с клавиатуры.
Класс SearchEditText является производным от класса android.widget.EditText . В этом классе есть интерфейс SearchEditText.OnKeyboardDismissListener . Вы можете посмотреть документацию:
https://developer.android.com/reference/androidx/leanback/widget/SearchEditText

Примечание. Перед использованием SearchEditText необходимо настроить зависимости Gradle в build.gradle (: app):

  implementation 'androidx.leanback:  Leanback: 1.1.0-alpha05 ' 

Может кому пригодится.

Подробный ответ:

  импортировать androidx. appcompat.app.AppCompatActivity; import androidx.leanback.widget.SearchEditText; import android.os.Bundle; import android.widget.Toast; открытый класс MainActivity расширяет AppCompatActivity реализует SearchEditText.OnKeyboardDismissListener {SearchEditText searchEditText;  @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (saveInstanceState);  setContentView (R.layout.activity_main);  searchEditText = findViewById (R.id.search_edit_text);  searchEditText.setOnKeyboardDismissListener (это);  }/** * Метод, вызываемый при закрытии клавиатуры.  */@Override public void onKeyboardDismiss () {Toast.makeText (this, «Слушатель работал», Toast.LENGTH_LONG) .show ();  }}  

activity_main.xml

   xml version = "1.0" encoding = "utf-8"?>     

Примечание: слушатель работает с:

   android: windowSoftInputMode = "adjustPan" android: windowSoftInputMode = "adjustResize"  

2


Обнаружен точный способ узнать, есть ли клавиатура при использовании ‘AdjustResize’ Мягкий режим ввода (код Kotlin)

Определение пары переменных области действия

  private var activityHeight = 0private var keyboardOpen = false  

Напишите следующий код в onCreate

  переопределить удовольствие onCreate (savedInstanceState: Bundle?) {super.onCreate (savedInstanceState) setContentView (  R.layout.activity_main) .../* Получение начального значения экрана */this@ActivityMain.window.decorView.doOnNextLayout {val displayFrame: Rect = Rect () this@ActivityMain.window.decorView.getWindowVisibleDisplayFrame (displayFrame) activityHeight = displayFrame  .height ()}/* Проверка открытия/закрытия клавиатуры */this@ActivityMain.window.decorView.addOnLayoutChangeListener {v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> val drawFrame: Rect = Rect  () this@ActivityMain.window.decorView.getWindowVisibleDispla  yFrame (drawFrame) val currentSize = drawFrame.height () keyboardOpen = currentSize  

Теперь у вас есть логическое значение, которое точно отслеживает, открыта клавиатура или нет, делайте то, что вы будет


сначала создайте файл kotlin и добавьте эти методы:

  fun Activity.getRootView (): View {return findViewById  (android.R.id.content)} fun Context.convertDpToPx (dp: Float): Float {  return TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, dp, this.resources.displayMetrics)} fun Activity.isKeyboardOpen (): Boolean {val visibleBounds = Rect () this.getRootView (). getWindowVisibleDisplayFrame (visibleBounds).  height - visibleBounds.height () val marginOfError = Math.round (this.convertDpToPx (50F)) return heightDiff> marginOfError} fun Activity.isKeyboardClosed (): Boolean {return! this.isKeyboardOpen ()}  

n создать класс слушателя для проверки того, открыта клавиатура или нет:

  class KeyboardEventListener (частное действие val: AppCompatActivity, частный обратный вызов val: (isOpen: Boolean) -> Unit)  : LifecycleObserver {private val listener = object: ViewTreeObserver.OnGlobalLayoutListener {private var lastState: Boolean = activity.isKeyboardOpen () переопределить веселье onGlobalLayout () {val isOpen = activity.isKeyboardOpen () if (isOpen == last else {return}) {return  dispatchKeyboardEvent (isOpen) lastState = isOpen}}} init {//Отправка текущего состояния клавиатуры dispatchKeyboardEvent (activity.isKeyboardOpen ())//Обеспечение активности компонента с учетом жизненного цикла. lifecycle.addObserver (this) registerKeyboardListener ()} private fun  registerKeyboardListener () {activity.getRootView (). viewTreeObserver.addOnGlobalLayoutListener (слушатель)} private fun dispatchKeyboardEvent (isOpen: Boolean) {когда {isOpen -> callback (true)! isOpen -> callback (false)}} @ventOnLife  Лиф  ecycle.Event.ON_PAUSE) @CallSuper fun onLifecyclePause () {unregisterKeyboardListener ()} частное развлечение unregisterKeyboardListener () {activity.getRootView (). viewTreeObserver.removeOnGlobalLayoutListener (listenerpre)}}      и используйте его так:  
  переопределить удовольствие onResume () {super.onResume () KeyboardEventListener (this) {isOpen ->//обработать событие}}  

Надеюсь, вам это пригодится.


Решение с дополнительным свойством в Activity Fragment, но без каких-либо гипотетических жестко заданных значений высоты (например, 100 и т. д.). Просто добавьте OnGlobalLayoutListener в корневое представление и сохраните его начальную высоту до отображения клавиатуры:

   var firstLoad = truevar contentFullWeight = 0заменить веселье onViewCreated (layoutView: View, savedInstanceState: Bundle?) {super. onViewCreated (layoutView, savedInstanceState) view? .viewTreeObserver? .addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener {if (firstLoad) {contentFullWeight = view? .height !! firstLoad = false} if (view? ..dullheight) if (view? ..dullheight)  ("TEZT_KEYBOARD", ">> KBD OPENED")} else {Log.d ("TEZT_KEYBOARD", ">> KBD closed")}})}  


    

final LinearLayout activityRootView = view.findViewById (R.id.addresses_c onfirm_root_view); activityRootView.getViewTreeObserver (). addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener () {@Overridepublic void onGlobalLayout () {Rect r = new Rect ();//координаты r будут по-прежнему заполнены. activityRootView.getWindowVisibleDisplayFrame (r);

  int heightDiff = activityRootView.getRootView (). getHeight () - r.height ();  if (heightDiff> 0,25 * activityRootView.getRootView (). getHeight ()) {//если больше 25% экрана, вероятно, это клавиатура ... onkeyboard ();  } else {//Клавиатура не видна вне клавиатуры ();  }}});  

Оцените статью
clickpad.ru
Добавить комментарий