1

У меня есть приложение с двумя действиями, а иногда мне нужно переключать активность и в то же время открывать вход поиска на панели действий только что возобновленной деятельности. Все работает отлично, за исключением того, что я не могу заставить клавиатуру подняться. Соответствующие биты моего кода ниже (NB: булево startsearch устанавливается true в результате переключения деятельности, если требуется вход поиска):Android-клавиатура не появляется, даже если явно запрошено

public class MyActivity extends Activity { 

    private InputMethodManager imm; 
    public boolean startsearch; 
    private MenuItem DestinationTxt; 
    private SearchView mySearchView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // various initialisation, and then: 
     startsearch = false; 
     imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     super.onCreateOptionsMenu(menu); 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.action_menu, menu);  
     DestinationTxt = menu.findItem(R.id.actionbar_search); 
     mySearchView = (SearchView)DestinationTxt.getActionView(); 
     // more menu create stuff appears here  
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (startsearch) { 
      DestinationTxt.expandActionView(); 
      imm.showSoftInput(mySearchView, 0); 
     } 
    } 
} 

и соответствующий бит action_menu.xml является

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item android:id="@+id/actionbar_search" 
     android:orderInCategory="1" 
     android:showAsAction="always|withText|collapseActionView" 
     android:actionViewClass="android.widget.SearchView" 
     android:icon="@drawable/earth_2508858_search_en" 
     android:inputType="textPostalAddress" 
     android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"></item> 
</menu> 

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

ответ

3

Я теперь был в состоянии понять это. Изучив код для InputMethodManager.showSoftInput(View, int), я выяснил, что мой запрос на открытие клавиатуры игнорируется, потому что представление, которое я передавал, не было активным видом InputMethodManager.

Чтобы решить мою проблему, я добавил два новых поля для MyActivity класса, а именно:

private EditText search_edit_text; 
private boolean mySearchView_editflag; 

Переменная search_edit_text будет вид внутри SearchView mySearchView который является мнение, что на самом деле получает фокус и получает ввод с клавиатуры. mySearchView_editflag обычно будет ложным, но будет true, когда приложение ждет подходящее время для вызова клавиатуры.

Чтобы разжиться объекта search_edit_text EditText я использовал следующую функцию

public static EditText GetEditText(ViewGroup vg) { 
    for(int i=0; i< vg.getChildCount(); i++) { 
     View v = vg.getChildAt(i); 
     if (v instanceof EditText) { 
      return (EditText)v; 
     } else if (v instanceof ViewGroup) { 
      EditText et = GetEditText((ViewGroup)v); 
      if (et != null) return et; 
     } 
    }  
    return null; 
} 

и изменил мою onCreateOptionsMenu(Menu) функцию, чтобы включать в себя следующее

DestinationTxt = menu.findItem(R.id.actionbar_search); 
mySearchView = (SearchView)DestinationTxt.getActionView(); 
search_edit_text = GetEditText(mySearchView); 
mySearchView_editflag = false; 

Это инициализирует search_edit_text и mySearchView_editflag переменные.Мой метод onResume() был изменен на

@Override 
public void onResume() { 
    super.onResume(); 
    if (startsearch) { 
     DestinationTxt.expandActionView(); 
     mySearchView_editflag = true; 
    } 
} 

и я включил код, который вызывает следующий метод на высокой частоте:

public void CheckStatus() { 
    if (mySearchView_editflag && imm.isActive(search_edit_text)) { 
     imm.showSoftInput(search_edit_text, 0); 
     mySearchView_editflag=false; 
    } 
} 

Это приложение теперь работает, как я хочу, потому следующий переключатель активности, когда поиск вход в панель действий требуется, приложение теперь ожидает, пока imm.isActive(search_edit_text) не будет истинным (что означает, что объект EditText принимает вход) перед вызовом imm.showSoftInput(search_edit_text, 0), чтобы убедиться, что клавиатура видна.

Чтобы помочь мне работать все это, я использовал InputMethodManager.showSoftInput(View, int, ResultReceiver) вместо InputMethodManager.showSoftInput(View, int), поэтому вместо

imm.showSoftInput(search_edit_text, 0); 

Я имел

ImmResultsReceiver irr = new ImmResultsReceiver(); 
imm.showSoftInput(search_edit_text, 0, irr); 

где ImmResultsReceiver класс

public class ImmResultsReceiver extends ResultReceiver {   
    public ImmResultsReceiver() { super(null); }   
    @Override 
    protected void onReceiveResult (int resultCode, Bundle resultData) { 
     String descrip; 
     switch(resultCode) { 
      case InputMethodManager.RESULT_UNCHANGED_SHOWN: descrip = "RESULT_UNCHANGED_SHOWN"; break; 
      case InputMethodManager.RESULT_UNCHANGED_HIDDEN: descrip = "RESULT_UNCHANGED_HIDDEN"; break; 
      case InputMethodManager.RESULT_SHOWN: descrip = "RESULT_SHOWN"; break; 
      case InputMethodManager.RESULT_HIDDEN: descrip = "RESULT_HIDDEN"; break; 
      default:descrip="InputMethodManager("+resultCode+")"; break; 
     } 
     Log.d("MyLog", "ImmResultsReceiver,"+descrip+","+(resultData == null?"":"resultData.size()="+resultData.size())); 
    }    
} 

Если метод ImmResultsReceiver.onReceiveResult(...) никогда не вызывается, это означает, что t Если вызов InputMethodManager.showSoftInput(...) был проигнорирован, поскольку представление, которое передано в InputMethodManager.showSoftInput(...), не является активным представлением InputMethodManager.

+1

..... Что делает ROFL от Google, делает простую вещь настолько сложной, как переход на Area51 – nyconing

1

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

android:windowSoftInputMode="stateVisible" 

Это должно привести к клавиатуре, чтобы стать видимым, когда начинается активность.

редактировать

затем попробовать это в onCreateOptionsMenu ..

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.action_menu, menu); 
    MenuItem menu_search = menu.findItem(actionbar_search); 


    menu_search.setOnActionExpandListener(new OnActionExpandListener() { 
     @Override 
     public boolean onMenuItemActionCollapse(MenuItem item) { 
      // Do something when collapsed 
      return true; // Return true to collapse action view 
     } 

     @Override 
     public boolean onMenuItemActionExpand(MenuItem item) { 
      //get focus 
      item.getActionView().requestFocus(); 
      //get input method 
      InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
      imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); 
      return true; // Return true to expand action view 
     } 
    }); 
    return true; 
} 
+0

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

+0

отредактировал сообщение, plz check – CRUSADER

+0

Спасибо за предложение, но это, похоже, не работает. Я думаю, проблема может заключаться в том, что и ваше предложение, и моя первоначальная попытка (размещенная в вопросе) вызываются во время 'onResume (...)'. В результате может быть, что активность не полностью «открыта для бизнеса», так что вызовы InputMethodManager теряются/игнорируются. – Stochastically

0

Приписка к моему последнему вводу. До того, как я отправилОстальный переключатель, я проверил InputMethodManager.isActive() для false. Все хорошо и хорошо, за исключением того, что после 350 мс он больше не применяется. Поэтому в вашем postDelayed, когда ваш отложенный код запускается, снова проверьте для InputMethodManager.isActive(), и если true не переключается только showSoftInput, иначе новая видимая клавиатура исчезнет, ​​что совсем не то, что вам нужно.

+0

Сложно понять ваш ответ, пожалуйста, напишите на каком-то примере. – GANI

0

К сожалению, я разместил свой постскриптум в связанной теме, но не в оригинале, однако то, о чем я говорю, приходит, когда ваше приложение было принудительно переведено на задний план с помощью телефонного звонка, например, когда он возвращается. ДАЖЕ, если вы явно находите EditText, который был в фокусе, и попытайтесь поднять мягкую клавиатуру, он просто не появится. Итак, вот фрагмент кода, который я использовал после прочтения о публикации Toggle ...

Обратите внимание, что здесь «O» - это просто класс статических объектов, которые я использую в своем приложении, а imeListener - это обратный вызов Я использую, чтобы рассказать Фрагментам о том, что происходит ...

if (O.mInputMethodManager.isActive()) { 
     if (imeListener != null) { 
      O.mInputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT, 
        new ResultReceiver(handler) { 
         protected void onReceiveResult(int resultCode, Bundle resultData) { 
          if (resultCode == InputMethodManager.RESULT_SHOWN || resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN) { 
           imeListener.onSoftKeyboardShown(filenameEditText); 
          } 
         } 
        } 
      ); 
     } 
     else { 
      O.mInputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT); 
     } 
    } 
    else { // there will be a slight delay... 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       if (!O.mInputMethodManager.isActive()) { // come right? 
        O.mInputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); 
       } 
       if (imeListener != null) { 
        O.mInputMethodManager.showSoftInput(filenameEditText, InputMethodManager.SHOW_IMPLICIT, 
          new ResultReceiver(handler) { 
           protected void onReceiveResult(int resultCode, Bundle resultData) { 
            if (resultCode == InputMethodManager.RESULT_SHOWN || resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN) { 
             imeListener.onSoftKeyboardShown(filenameEditText); 
            } 
           } 
          } 
        ); 
       } else { 
        O.mInputMethodManager.showSoftInput(filenameEditText, InputMethodManager.SHOW_IMPLICIT); 
       } 
      } 
     }, 350); 
    } 
Смежные вопросы