Intereting Posts

Сохранять открытое / закрытое состояние клавиатуры для EditText, когда приложение выходит на передний план

У меня есть Activity который воссоздается при изменении конфигурации (желательно). У меня есть DialogFragment который вызывает setRetainInstance(true) с одним EditText в своем макете.

В диалоговом окне DialogFragment onActivityCreated я вызываю:

 getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 

A) Если я открываю клавиатуру, то, когда я помещаю приложение в фоновый режим и затем переношу его в исходное, тогда я хочу, чтобы клавиатура все еще отображалась .

B) Если я закрываю клавиатуру (EditText все еще имеет фокус и показывает курсор, который является желательным поведением), я хочу, чтобы клавиатура все еще была закрыта, если я помещаю приложение в фоновый режим, а затем вывожу его на передний план.

Кажется, я не могу достичь как A), так и B). Клавиатура всегда закрыта, когда я приношу приложение на передний план. Я пробовал .SOFT_INPUT_STATE_ALWAYS_VISIBLE, но тогда клавиатура всегда открыта.

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

Редактировать Пожалуйста, обратите внимание, что я не хочу, чтобы активность не воссоздавалась при изменении конфигурации.

Я также экспериментировал с WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED который поддерживал состояние открытия / закрытия клавиатуры во время вращения на телефоне (макет одиночной панели), но a) не работал с макетом двойной панели. B) не поддерживал состояние клавиатуры при приеме Приложение на передний план.

Solutions Collecting From Web of "Сохранять открытое / закрытое состояние клавиатуры для EditText, когда приложение выходит на передний план"

Привет, прежде всего, спасибо за интересный вопрос. Это заставило меня поэкспериментировать с кодом. Здесь я описываю свое решение.

Чтобы найти решение, мне нужно было знать две вещи

1. Как определить, видна ли клавиатура или нет

2. Как установить программную клавиатуру видимой или скрытой.

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

И для установки softkeyboardstate я просто использовал метод Window.setSoftInputMode .

И знать взаимодействие с пользователем, я переопределяю метод onUserInteraction

Удержал два флага. Один флаг состоит в том, чтобы сохранить состояние keyboardstate другое – знать, попало ли приложение в фоновый режим или нет

КОД:

1. переменная, объявленная

 int lastDiff = 0; volatile boolean flag = false; volatile int flag2 = 0; 

2. ViewTreeObserver

 activityRootView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect r = new Rect(); activityRootView.getWindowVisibleDisplayFrame(r); int heightDiff = activityRootView.getRootView() .getHeight() - (r.bottom - r.top); if (lastDiff == heightDiff) return; lastDiff = heightDiff; Log.i("aerfin","arefin "+lastDiff); if (heightDiff > 100) { // if more than 100 pixels, its // probably a keyboard... flag2 = 0; } else { if (flag == false) flag2 = 1; } } }); 

3. Обработка взаимодействия с пользователем

  @Override public void onUserInteraction() { super.onUserInteraction(); flag = true; } 

4. Наконец onPause и onResume

 @Override protected void onPause() { super.onPause(); flag = true; } @Override protected void onResume() { flag = false; switch (flag2) { case 0: getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); break; case 1: getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); break; default: break; } super.onResume(); } 

Объяснение:

Здесь я использовал два флага ( flag2 и flag ). flag2 сохраняет состояние keyboardstate и flag сохраняет, переходит ли приложение в фоновый режим или есть ли какое-либо взаимодействие с пользователем. flag используется, потому что, когда приложение переходит в фоновый режим, сначала сначала скрывает клавиатуру. Другие вещи можно легко понять из приведенного выше кода.

Контрольная работа:

В s2 (ics), желание s (ics), галактика y (2.3.6)

Заключительный комментарий:

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

Вы должны использовать флаг (boolean kbShowing) чтобы сохранить текущий статус клавиатуры, например set kbShowing = true когда отображается клавиатура, иначе установите kbShowing = false .

onCreate

  showKB(); // if keyboard is not showed automatically. 

onRestart

  if(kbShowing) showKb(); // if keyboard is not showed automatically. else hideKb(); // if keyboard is showed automatically. 

Если вы не знаете, как обнаружить, когда клавиатура отображается или скрывается, ответьте Stefan на этот вопрос. Как захватить событие «виртуальная клавиатура show / hide» в Android?

Объявите свой EditText на уровне класса

EditText editText;

Теперь переопределите onResume () и onPause () метод активности …

  @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); editText.requestFocus(); editText.postDelayed(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED); } }, 100); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); editText.postDelayed(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager)getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); } }, 200); } 

Этот код работает для меня отлично.

Наслаждайтесь -: D

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

 final View activityRootView = findViewById(R.id.activityRoot); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight(); if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard... ... do something here } } }); 

В соответствии с ответом здесь: Как проверить видимость программной клавиатуры в Android?

Затем установите одну из следующих настроек в onResume:

  getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 

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

  android:windowSoftInputMode="stateAlwaysVisible|adjustPan"> 

Это позаботится о части вращения вашей проблемы и должно работать и onResume. StateAlwaysVisible запустит клавиатуру на onCrate, и adjustPan будет обрабатывать вращение.

Вот пример из одного из моих действий из моего файла манифеста:

 <activity android:name=".GMax3Main" android:label="@string/app_name" android:windowSoftInputMode="stateAlwaysVisible|adjustPan"> <intent-filter> <action android:name="com.medeasy.GMax3.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> 

Надеюсь это поможет.

В моем классе активности я открываю свою программную клавиатуру в методе onCreate своего класса:

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new UserSync().execute(); setContentView(R.layout.main); InputMethodManager imm = (InputMethodManager) GMax3Main.this.getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null){ imm.toggleSoftInput(InputMethodManager.RESULT_SHOWN, 0); } 

Затем я вызываю свой android:windowSoftInputMode="stateAlwaysVisible|adjustPan"> как показано выше в моем файле манифеста.

Я бы расширил подход Wayne, переписав и создав собственный виджет EditText который вы должны использовать во всем своем приложении.

 public class PJLsEditText extends EditText { public PJLsEditText(Context context) { super(context); saveKbState(); } public PJLsEditText(Context context, AttributeSet attrs) { super(context, attrs); saveKbState(); } private void saveKbState() { //get keyboard state and set a flag either in a static class or as SharedPreference } // I'm not sure if EditText objects get destroyed on configuration change. // If so, you might need to overwrite the onConfigurationChanged method here, // as well... } 

Я предполагаю, что это должно помочь вам всегда знать последнее состояние клавиатуры, даже если оно изменено через Dialogs. Вы можете скрыть или показать клавиатуру, а затем в соответствии с этим флагом в onResume и onPause .