2013-06-01 80 views
1

我有兩個活動的應用程序,有時我需要切換活動並同時打開剛剛恢復的活動的操作欄中的搜索輸入。一切正常,除了我不能讓鍵盤出現。我的代碼的相關位低於(NB:布爾開始搜索被設置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_textmySearchView_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.showSoftInput(search_edit_text, 0)以確保鍵盤可見之前,應用程序現在一直等到imm.isActive(search_edit_text)爲真(表示EditText對象正在接收輸入)。

爲了幫助我的工作出這一切,我用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的活動視圖,因此忽略對InputMethodManager.showSoftInput(...)的調用。

+1

..... Google所做的ROFL讓簡單的事情變得如此複雜,比如去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

編輯帖子,檢查 – CRUSADER

+0

感謝您的建議,但似乎也沒有工作。我認爲問題可能是你的建議和我最初的嘗試(發佈在問題中)在'onResume(...)'期間被調用。因此,活動可能並非完全「公開」,因此對InputMethodManager的調用會丟失/被忽略。 – Stochastically

0

我最後一次輸入的附言。在我postDelayed開關之前,我檢查InputMethodManager.isActive()爲false。一切順利,除了在350毫秒後它不再適用。因此,在您的postDelayed中,當您的延遲代碼運行時,請再次檢查InputMethodManager.isActive(),如果爲true,則不要僅切換showSoftInput,否則新顯示的鍵盤將消失,這根本不是人們想要的。

+0

很難理解你的答案,請舉一些例子。 – GANI

0

糟糕,我想我把postscript發佈到一個相關的線程,而不是原來的,但是我所談論的是當一個人的應用程序被一個電話強迫進入後臺,並且它返回EVEN時你明確地找到了有重點的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); 
    } 
相關問題